summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@x1-nano.kaivo.local>2023-04-01 21:39:06 -0400
committerJakob Kaivo <jkk@x1-nano.kaivo.local>2023-04-01 21:39:06 -0400
commitb732995c5217d0619fd8d67653b930665ca09d12 (patch)
tree5270548dd778dc0d571d6f4f9ff3551a5028ec12
parentd8fcf51d92039f8edfffafada18f78b047afae8f (diff)
begin to handle aliases
-rw-r--r--alias.c123
-rw-r--r--parse.c23
-rw-r--r--sh.h1
3 files changed, 132 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;
}
diff --git a/parse.c b/parse.c
index 61e41ee..3c955e5 100644
--- a/parse.c
+++ b/parse.c
@@ -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);
}
diff --git a/sh.h b/sh.h
index 3479baa..d6a7f68 100644
--- a/sh.h
+++ b/sh.h
@@ -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);