diff options
author | Jakob Kaivo <jkk@x1-nano.kaivo.local> | 2023-04-01 21:39:06 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@x1-nano.kaivo.local> | 2023-04-01 21:39:06 -0400 |
commit | b732995c5217d0619fd8d67653b930665ca09d12 (patch) | |
tree | 5270548dd778dc0d571d6f4f9ff3551a5028ec12 | |
parent | d8fcf51d92039f8edfffafada18f78b047afae8f (diff) |
begin to handle aliases
-rw-r--r-- | alias.c | 123 | ||||
-rw-r--r-- | parse.c | 23 | ||||
-rw-r--r-- | sh.h | 1 |
3 files changed, 132 insertions, 15 deletions
@@ -24,26 +24,52 @@ #include <unistd.h> struct alias { + struct alias *next; + struct alias *prev; char *alias; char *command; }; static struct alias *aliases = NULL; -static void set_alias(const char *alias, const char *command) +static int set_alias(const char *alias, const char *command) { - (void)alias; (void)command; -} + struct alias *p = aliases; + for (; p != NULL; p = p->next) { + if (strcmp(p->alias, alias) == 0) { + free(p->command); + p->command = strdup(command); + return 0; + } + } + + struct alias *a = calloc(1, sizeof(*a)); + if (a == NULL) { + return 1; + } + + a->alias = strdup(alias); + a->command = strdup(command); -char * sh_get_alias(const char *alias) -{ if (aliases == NULL) { - return NULL; + aliases = a; + return 0; + } + + for (p = aliases; p->next != NULL; p = p->next) { + /* find tail */ } + p->next = a; + a->prev = p; + + return 0; +} - for (int i = 0; aliases[i].alias; i++) { - if (!strcmp(aliases[i].alias, alias)) { - return aliases[i].command; +char * sh_get_alias(const char *alias) +{ + for (struct alias *p = aliases; p != NULL; p = p->next) { + if (!strcmp(p->alias, alias)) { + return p->command; } } @@ -67,28 +93,95 @@ int alias_main(int argc, char *argv[]) } if (argv[optind] == NULL) { - for (int i = 0; aliases && aliases[i].alias; i++) { - printf("%s=%s\n", aliases[i].alias, aliases[i].command); + for (struct alias *p = aliases; p != NULL; p = p->next) { + printf("%s=%s\n", p->alias, p->command); } return 0; } + int ret = 0; do { char *a = argv[optind++]; char *eq = strchr(a, '='); if (eq) { *eq = '\0'; - set_alias(a, eq + 1); + ret |= set_alias(a, eq + 1); } else { show_alias(a); } } while (optind < argc); - return 0; + return ret; +} + +static struct alias *free_alias(struct alias *alias) +{ + struct alias *next = alias->next; + if (alias == aliases) { + aliases = next; + } + + if (alias->next) { + alias->next->prev = alias->prev; + } + + if (alias->prev) { + alias->prev->next = alias->next; + } + + free(alias->alias); + free(alias->command); + free(alias); + return next; } int unalias_main(int argc, char **argv) { - printf("Sorry, %s isn't implemented yet.\n", argv[0]); - return argc; + int all = 0; + + int c = 0; + while (getopt(argc, argv, "a") != -1) { + switch (c) { + case 'a': + all = 1; + break; + + default: + return 1; + } + } + + if (all) { + if (optind < argc) { + fprintf(stderr, "unalias: -a takes no arguments\n"); + return 1; + } + for (struct alias *p = aliases; p != NULL; p = free_alias(p)) { + /* handled by update step */ + } + return 0; + } + + if (optind >= argc) { + fprintf(stderr, "unalias: missing operands\n"); + return 1; + } + + int ret = 0; + for (int i = optind; i < argc; i++) { + int removed = 0; + for (struct alias *p = aliases; p != NULL; p = p->next) { + if (strcmp(p->alias, argv[i]) == 0) { + removed = 1; + free_alias(p); + break; + } + } + if (!removed) { + fprintf(stderr, "unalias: %s not defined\n", argv[i]); + ret = 1; + } + } + + return ret; } @@ -86,6 +86,22 @@ struct command *sh_parse(const char *cmdline) cmd->cmd.simple.argv = calloc(100, sizeof(char *)); char *next = strtok(start, " "); + + char *alias = sh_get_alias(next); + if (alias) { + char *params = strtok(NULL, " "); + if (params == NULL) { + free(l); + return sh_parse(alias); + } + size_t len = strlen(alias) + strlen(params) + 2; + char *expanded = calloc(1, len); + snprintf(expanded, len, "%s %s", alias, params); + free(l); + l = expanded; + next = strtok(l, " "); + } + do { cmd->cmd.simple.argv[cmd->cmd.simple.argc++] = strdup(next); } while ((next = strtok(NULL, " ")) != NULL); @@ -137,6 +153,13 @@ int sh_simple_command(struct simple_command *c) } /* + if (sh_is_unspecified_utility(path)) { + fprintf(stderr, "sh: %s has unspecified behavior, doing nothing\n", path); + return 1; + } + */ + + /* if (sh_is_function(path)) { return sh_function(c->argc, c->argv); } @@ -42,6 +42,7 @@ struct command; struct command *sh_parse(const char *cmdline); void sh_freecmd(struct command *cmd); int sh_execute(struct command *cmd); +char *sh_get_alias(const char *cmd); void sh_set(char option, int value); void sh_seto(char *option, int value); |