summaryrefslogtreecommitdiff
path: root/alias.c
diff options
context:
space:
mode:
Diffstat (limited to 'alias.c')
-rw-r--r--alias.c123
1 files changed, 108 insertions, 15 deletions
diff --git a/alias.c b/alias.c
index 23c557a..bc3e604 100644
--- a/alias.c
+++ b/alias.c
@@ -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;
}