shell suport multiple commands in single statement

This commit is contained in:
Bomin Zhang 2020-05-26 16:51:26 +08:00
parent 7c31b143b2
commit c1bc7ef982
4 changed files with 116 additions and 111 deletions

View File

@ -335,17 +335,14 @@ void *shellLoopQuery(void *arg) {
tscError("failed to malloc command"); tscError("failed to malloc command");
return NULL; return NULL;
} }
while (1) {
// Read command from shell.
do {
// Read command from shell.
memset(command, 0, MAX_COMMAND_SIZE); memset(command, 0, MAX_COMMAND_SIZE);
set_terminal_mode(); set_terminal_mode();
shellReadCommand(con, command); shellReadCommand(con, command);
reset_terminal_mode(); reset_terminal_mode();
} while (shellRunCommand(con, command) == 0);
// Run the command
shellRunCommand(con, command);
}
pthread_cleanup_pop(1); pthread_cleanup_pop(1);

View File

@ -82,20 +82,15 @@ TAOS *shellInit(SShellArguments *args) {
// Check if it is temperory run // Check if it is temperory run
if (args->commands != NULL || args->file[0] != 0) { if (args->commands != NULL || args->file[0] != 0) {
if (args->commands != NULL) { if (args->commands != NULL) {
char *token; printf("%s%s\n", PROMPT_HEADER, args->commands);
token = strtok(args->commands, ";"); shellRunCommand(con, args->commands);
while (token != NULL) {
printf("%s%s\n", PROMPT_HEADER, token);
shellRunCommand(con, token);
token = strtok(NULL, ";");
}
} }
if (args->file[0] != 0) { if (args->file[0] != 0) {
source_file(con, args->file); source_file(con, args->file);
} }
taos_close(con);
taos_close(con);
write_history(); write_history();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@ -111,67 +106,66 @@ TAOS *shellInit(SShellArguments *args) {
return con; return con;
} }
void shellReplaceCtrlChar(char *str) {
_Bool ctrlOn = false;
char *pstr = NULL;
char quote = 0;
for (pstr = str; *str != '\0'; ++str) { static bool isEmptyCommand(const char* cmd) {
if (ctrlOn) { for (char c = *cmd++; c != 0; c = *cmd++) {
switch (*str) { if (c != ' ' && c != '\t' && c != ';') {
case 'n': return false;
*pstr = '\n';
pstr++;
break;
case 'r':
*pstr = '\r';
pstr++;
break;
case 't':
*pstr = '\t';
pstr++;
break;
case 'G':
*pstr++ = '\\';
*pstr++ = *str;
break;
case '\\':
*pstr = '\\';
pstr++;
break;
case '\'':
case '"':
if (quote) {
*pstr++ = '\\';
*pstr++ = *str;
}
break;
default:
*pstr = *str;
pstr++;
break;
}
ctrlOn = false;
} else {
if (*str == '\\') {
ctrlOn = true;
} else {
if (quote == *str) {
quote = 0;
} else if (*str == '\'' || *str == '"') {
quote = *str;
}
*pstr = *str;
pstr++;
}
} }
} }
*pstr = '\0'; return true;
} }
int32_t shellRunCommand(TAOS *con, char *command) {
static int32_t shellRunSingleCommand(TAOS *con, char *command) {
/* If command is empty just return */ /* If command is empty just return */
if (regex_match(command, "^[ \t;]*$", REG_EXTENDED)) { if (isEmptyCommand(command)) {
return 0;
}
// Analyse the command.
if (regex_match(command, "^[ \t]*(quit|q|exit)[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
taos_close(con);
write_history();
return -1;
}
if (regex_match(command, "^[\t ]*clear[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
// If clear the screen.
system("clear");
return 0;
}
if (regex_match(command, "^[\t ]*set[ \t]+max_binary_display_width[ \t]+(default|[1-9][0-9]*)[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
strtok(command, " \t");
strtok(NULL, " \t");
char* p = strtok(NULL, " \t");
if (strcasecmp(p, "default") == 0) {
tsMaxBinaryDisplayWidth = DEFAULT_MAX_BINARY_DISPLAY_WIDTH;
} else {
tsMaxBinaryDisplayWidth = atoi(p);
}
return 0;
}
if (regex_match(command, "^[ \t]*source[\t ]+[^ ]+[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
/* If source file. */
char *c_ptr = strtok(command, " ;");
assert(c_ptr != NULL);
c_ptr = strtok(NULL, " ;");
assert(c_ptr != NULL);
source_file(con, c_ptr);
return 0;
}
shellRunCommandOnServer(con, command);
return 0;
}
int32_t shellRunCommand(TAOS* con, char* command) {
/* If command is empty just return */
if (isEmptyCommand(command)) {
return 0; return 0;
} }
@ -190,40 +184,63 @@ int32_t shellRunCommand(TAOS *con, char *command) {
} }
} }
shellReplaceCtrlChar(command); bool esc = false;
char quote = 0, *cmd = command, *p = command;
// Analyse the command. for (char c = *command++; c != 0; c = *command++) {
if (regex_match(command, "^[ \t]*(quit|q|exit)[ \t;]*$", REG_EXTENDED | REG_ICASE)) { if (esc) {
taos_close(con); switch (c) {
write_history(); case 'n':
return -1; c = '\n';
} else if (regex_match(command, "^[\t ]*clear[ \t;]*$", REG_EXTENDED | REG_ICASE)) { break;
// If clear the screen. case 'r':
system("clear"); c = '\r';
} else if (regex_match(command, "^[\t ]*set[ \t]+max_binary_display_width[ \t]+(default|[1-9][0-9]*)[ \t;]*$", REG_EXTENDED | REG_ICASE)) { break;
strtok(command, " \t"); case 't':
strtok(NULL, " \t"); c = '\t';
char* p = strtok(NULL, " \t"); break;
if (strcasecmp(p, "default") == 0) { case 'G':
tsMaxBinaryDisplayWidth = DEFAULT_MAX_BINARY_DISPLAY_WIDTH; *p++ = '\\';
} else { break;
tsMaxBinaryDisplayWidth = atoi(p); case '\'':
case '"':
if (quote) {
*p++ = '\\';
}
break;
}
*p++ = c;
esc = false;
continue;
}
if (c == '\\') {
esc = true;
continue;
} }
} else if (regex_match(command, "^[ \t]*source[\t ]+[^ ]+[ \t;]*$", REG_EXTENDED | REG_ICASE)) {
/* If source file. */
char *c_ptr = strtok(command, " ;");
assert(c_ptr != NULL);
c_ptr = strtok(NULL, " ;");
assert(c_ptr != NULL);
source_file(con, c_ptr); if (quote == c) {
} else { quote = 0;
shellRunCommandOnServer(con, command); } else if (c == '\'' || c == '"') {
quote = c;
}
*p++ = c;
if (c == ';') {
c = *p;
*p = 0;
if (shellRunSingleCommand(con, cmd) < 0) {
return -1;
}
*p = c;
p = cmd;
}
} }
return 0; *p = 0;
return shellRunSingleCommand(con, cmd);
} }
void shellRunCommandOnServer(TAOS *con, char command[]) { void shellRunCommandOnServer(TAOS *con, char command[]) {
int64_t st, et; int64_t st, et;
wordexp_t full_path; wordexp_t full_path;

View File

@ -307,19 +307,13 @@ void *shellLoopQuery(void *arg) {
return NULL; return NULL;
} }
while (1) { do {
// Read command from shell. // Read command from shell.
memset(command, 0, MAX_COMMAND_SIZE); memset(command, 0, MAX_COMMAND_SIZE);
set_terminal_mode(); set_terminal_mode();
shellReadCommand(con, command); shellReadCommand(con, command);
reset_terminal_mode(); reset_terminal_mode();
} while (shellRunCommand(con, command) == 0);
// Run the command
if (shellRunCommand(con, command) != 0) {
break;
}
}
tfree(command); tfree(command);
exitShell(); exitShell();

View File

@ -203,16 +203,13 @@ void *shellLoopQuery(void *arg) {
char *command = malloc(MAX_COMMAND_SIZE); char *command = malloc(MAX_COMMAND_SIZE);
if (command == NULL) return NULL; if (command == NULL) return NULL;
while (1) { do {
memset(command, 0, MAX_COMMAND_SIZE); memset(command, 0, MAX_COMMAND_SIZE);
shellPrintPrompt(); shellPrintPrompt();
// Read command from shell. // Read command from shell.
shellReadCommand(con, command); shellReadCommand(con, command);
} while (shellRunCommand(con, command) == 0);
// Run the command
shellRunCommand(con, command);
}
return NULL; return NULL;
} }