summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exec.c42
-rw-r--r--src/utils.c25
-rw-r--r--src/utils.h4
3 files changed, 64 insertions, 7 deletions
diff --git a/src/exec.c b/src/exec.c
index 2bcffb9..0c53971 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -1,4 +1,6 @@
+#include <assert.h>
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
@@ -10,12 +12,38 @@
void execute_command_pipeline(Pipeline pipeline, int stdin_fd, int stdout_fd, bool wait_here, int* pgid, ShellState* shstate);
+DECLARE_MAYBE(StrPair, MaybeStrPair)
+
+MaybeStrPair parse_assignment(char* token) {
+ printf("%s\n", token);
+ // TODO: ideally shouldn't mutate maybe
+ if (token == NULL) return (MaybeStrPair){.some = false};
+ char* eq = strchr(token, '=');
+ if (eq == NULL || eq == token) return (MaybeStrPair){.some = false};
+ *eq = '\0';
+ if (!is_identifier(token)) exit(42);
+ return (MaybeStrPair){.some = true, .value = (StrPair){.key = token, .val = eq+1}};
+}
+
+
bool handle_builtin(ExecutableCommand cmd, ShellState* shstate) {
+ assert(cmd.args[0] != NULL);
// TODO: handle id=value assignments
if (strcmp(cmd.args[0], "exit") == 0) {
exit(0);
+ } else if (strcmp(cmd.args[0], "cd") == 0) {
+ assert(cmd.args[1] != NULL);
+ chdir(cmd.args[1]);
+ return true;
+ } else if (strcmp(cmd.args[0], "alias") == 0) {
+ // TODO: if no arg1 -> print alias list
+ MaybeStrPair m_assignment = parse_assignment(cmd.args[1]);
+ assert(m_assignment.some);
+ printf("%s:%s\n", m_assignment.value.key, m_assignment.value.val);
+ set_map_pair(&shstate->aliases, m_assignment.value);
+ return true;
}
return false;
}
@@ -137,7 +165,19 @@ ExecutableCommand process_pl_command(PlCommand pl_cmd, int* pgid, ShellState* sh
char** args = malloc(sizeof(char*) * (arg_vec.count + 1));
for (int i = 0; i < arg_vec.count; i++) {
- args[i] = *get_from_StrVec(&arg_vec, i);
+ if (i == 0) {
+ char* arg = *get_from_StrVec(&arg_vec, 0);
+ MaybeStr m_dealias = get_map_value(&shstate->aliases, arg);
+ if (m_dealias.some) {
+ args[0] = m_dealias.value;
+ printf("%s\n", args[0]);
+ } else {
+ printf("Nah\n");
+ args[0] = arg;
+ }
+ } else {
+ args[i] = *get_from_StrVec(&arg_vec, i);
+ }
}
args[arg_vec.count] = NULL;
diff --git a/src/utils.c b/src/utils.c
index 1f08445..1110194 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -23,22 +23,24 @@ char* inner(String* str) {
}
-void set_map_pair(KeyValMap* map, char* key, char* val) {
-for (int i = 0; i < map->count; i++) {
+void set_map_pair(KeyValMap* map, StrPair pair) {
+ for (int i = 0; i < map->count; i++) {
char* key_i = get_from_KeyValMap(map, i)->key;
if (key_i == NULL) continue;
- if (strcmp(key_i, key) == 0) {
+ if (strcmp(key_i, pair.key) == 0) {
// TODO: maybe copy instead
strcpy(
map->blocks[i / map->block_size][i % map->block_size].val,
- val
+ pair.val
);
- break;
+ return;
}
}
+ push_to_KeyValMap(map, pair);
}
MaybeStr get_map_value(KeyValMap* map, char* key) {
+ printf("%d\n", map->count);
for (int i = 0; i < map->count; i++) {
char* key_i = get_from_KeyValMap(map, i)->key;
if (key_i == NULL) continue;
@@ -69,3 +71,16 @@ char* get_var(char* varname, ShellState* shstate) {
if (maybe_varval.some == true) return maybe_varval.value;
return getenv(varname);
}
+
+
+bool is_identifier(char* str) {
+ if (str == NULL) return false;
+ if (!isalpha(str[0]) && str[0] != '_') return false;
+for (int i = 1; str[i] != '\0'; i++) {
+ if (!isalnum(str[i]) && str[i] != '_') return false;
+ }
+ return true;
+}
+
+
+
diff --git a/src/utils.h b/src/utils.h
index cbfaadd..571a217 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -96,7 +96,7 @@ typedef struct {
} StrPair;
DECLARE_VEC(StrPair, KeyValMap)
-void set_map_pair(KeyValMap* map, char* key, char* val);
+void set_map_pair(KeyValMap* map, StrPair);
MaybeStr get_map_value(KeyValMap* map, char* key);
void unset_map_key(KeyValMap* map, char* key);
@@ -107,3 +107,5 @@ typedef struct {
} ShellState;
char* get_var(char* varname, ShellState* shstate);
+
+bool is_identifier(char* str);