diff options
| author | 2024-09-17 20:44:04 -0400 | |
|---|---|---|
| committer | 2024-09-17 20:44:04 -0400 | |
| commit | b8501210aefeff45b2eb75429c6e3ca2c1ecc983 (patch) | |
| tree | 7a4d581862da2ac3b33286284b8dea94a0c113b7 | |
| parent | Update README.md (diff) | |
changed tokenizer to handle all the chaining operators
Diffstat (limited to '')
| -rw-r--r-- | src/lua_api.c | 2 | ||||
| -rw-r--r-- | src/lush.c | 94 | ||||
| -rw-r--r-- | src/lush.h | 2 |
3 files changed, 78 insertions, 20 deletions
diff --git a/src/lua_api.c b/src/lua_api.c index 99892c7..d40489c 100644 --- a/src/lua_api.c +++ b/src/lua_api.c @@ -99,7 +99,7 @@ static int execute_command(lua_State *L, const char *line) { int status = 0; lush_push_history(line); char *expanded_line = lush_resolve_aliases((char *)line); - char **commands = lush_split_pipes(expanded_line); + char **commands = lush_split_commands(expanded_line); char ***args = lush_split_args(commands, &status); if (status == -1) { @@ -25,6 +25,7 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. #include "lualib.h" #include <asm-generic/ioctls.h> #include <bits/time.h> +#include <ctype.h> #include <dirent.h> #include <linux/limits.h> #include <locale.h> @@ -935,34 +936,87 @@ char *lush_resolve_aliases(char *line) { return result; } -char **lush_split_pipes(char *line) { +static int is_operator(const char *str) { + const char *operators[] = {"||", "&&", "&", ";", ">>", ">", "<", + "\\", "(", ")", "{", "}", "!", "|"}; + int num_operators = sizeof(operators) / sizeof(operators[0]); + + for (int i = 0; i < num_operators; i++) { + int len = strlen(operators[i]); + if (strncmp(str, operators[i], len) == 0) { + return len; + } + } + return 0; +} + +static char *trim_whitespace(char *str) { + char *end; + + // Trim leading space + while (isspace((unsigned char)*str)) + str++; + + if (*str == 0) + return str; // If all spaces, return empty string + + // Trim trailing space + end = str + strlen(str) - 1; + while (end > str && isspace((unsigned char)*end)) + end--; + + *(end + 1) = '\0'; + + return str; +} + +// Split the command based on various chaining operations +char **lush_split_commands(char *line) { char **commands = calloc(16, sizeof(char *)); if (!commands) { perror("calloc failed"); exit(1); } - char *command; int pos = 0; + char *start = line; + while (*start) { + // Skip leading spaces + while (isspace((unsigned char)*start)) + start++; + + // Check for operators + int op_len = is_operator(start); + if (op_len > 0) { + // Allocate memory for operator command + char *operator_cmd = calloc(op_len + 1, sizeof(char)); + strncpy(operator_cmd, start, op_len); + commands[pos++] = operator_cmd; + start += op_len; + } else { + // Collect regular commands until the next operator or end of string + char *next = start; + while (*next && !is_operator(next)) { + next++; + } - command = strtok(line, "|"); - while (command) { - commands[pos++] = command; - command = strtok(NULL, "|"); - } - - // trim off whitespace - for (int i = 0; i < pos; i++) { - while (*commands[i] == ' ' || *commands[i] == '\n') { - commands[i]++; + // Copy the command between start and next + char *command = strndup(start, next - start); + commands[pos++] = trim_whitespace(command); + start = next; } - char *end_of_str = strrchr(commands[i], '\0'); - --end_of_str; - while (*end_of_str == ' ' || *end_of_str == '\n') { - *end_of_str = '\0'; - --end_of_str; + + if (pos >= 16) { + // Resize if necessary + commands = realloc(commands, (pos + 16) * sizeof(char *)); + if (!commands) { + perror("realloc failed"); + exit(1); + } } } + + commands[pos] = NULL; return commands; } @@ -1221,7 +1275,7 @@ int main(int argc, char *argv[]) { continue; } char *expanded_line = lush_resolve_aliases(line); - char **commands = lush_split_pipes(expanded_line); + char **commands = lush_split_commands(expanded_line); char ***args = lush_split_args(commands, &status); if (status == -1) { fprintf(stderr, "lush: Expected end of quoted string\n"); @@ -1229,6 +1283,10 @@ int main(int argc, char *argv[]) { exit(1); } + for (int i = 0; commands[i] != NULL; i++) { + printf("Command %d: '%s'\n", i, commands[i]); + } + for (int i = 0; args[i]; i++) { free(args[i]); } @@ -35,7 +35,7 @@ int lush_num_builtins(); int lush_run(lua_State *L, char ***commands, int num_commands); char *lush_read_line(); -char **lush_split_pipes(char *line); +char **lush_split_commands(char *line); char ***lush_split_args(char **commands, int *status); void lush_execute_command(char **args, int input_fd, int output_fd); |
