diff options
Diffstat (limited to 'alias.c')
-rw-r--r-- | alias.c | 123 |
1 files changed, 108 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; } |