From 799d930c2540933c23a1b6ba28e8e5e4f3bccb64 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Thu, 9 Feb 2023 18:05:28 +0100 Subject: add variable system via env --- smash/Makefile | 2 +- smash/env.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ smash/env.h | 9 +++++++ smash/main.c | 16 ++++++++--- 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 smash/env.c create mode 100644 smash/env.h diff --git a/smash/Makefile b/smash/Makefile index 1d8e228..b8fb606 100644 --- a/smash/Makefile +++ b/smash/Makefile @@ -17,4 +17,4 @@ unit_test_exec: ./test all: - gcc main.c comment.c exec.c parser.c builtin.c ../lib/slib.a -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -fno-builtin -o smash -DVARIABLES_UNIT_TEST -g + gcc main.c env.c comment.c exec.c parser.c builtin.c ../lib/slib.a -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -fno-builtin -o smash -DVARIABLES_UNIT_TEST -g diff --git a/smash/env.c b/smash/env.c new file mode 100644 index 0000000..1bf7e21 --- /dev/null +++ b/smash/env.c @@ -0,0 +1,85 @@ +#include "../lib/env/env.h" +#include "../lib/cstr/cstr.h" +#include "../lib/malloc/malloc.h" + +#include "../lib/io/io.h" + +#include "env.h" + +void clear_buf(char *buf, u64 size) +{ + for (int i = 0; i < size; ++i) buf[i] = 0; +} + +void init_arg_env(int argc, const char **argv) +{ + char buf[32]; + u64_to_cstr(argc - 1, buf, 32); + setenv("@", buf); + for (int i = 1; i < argc; ++i) { + clear_buf(buf, 32); + u64_to_cstr(i - 1, buf, 32); + setenv(buf, argv[i]); + } +} + + +char* new_line_and_replace_vars(const char *line, u64 n) +{ + char var[64]; + int size; + char *replaced; + + for (int i = 0; i < n && line[i]; ++i) { + if (line[i] == '$') { + clear_buf(var, 64); + ++i; + for (int j = 0; line[i] && line[i] != ' ';) { + var[j] = line[i]; + ++j; + ++i; + } + + if (cstr_length(var) == 0) { + size++; + } else { + const char *e = getenv(var); + if (e) size += cstr_length(e); + } + } else { + size++; + } + } + + replaced = malloc(size + 1); + int line_pos = 0; + + for (int i = 0; i < size && line[line_pos]; ++i) { + + if (line[line_pos] == '$') { + clear_buf(var, 64); + ++line_pos; + + for (int j = 0; line[line_pos] && line[line_pos] != ' ';) { + var[j] = line[line_pos]; + ++j; + ++line_pos; + } + + if (cstr_length(var)) { + const char *e = getenv(var); + while (*e) { + replaced[i++] = *(e++); + } + } + + } else { + replaced[i] = line[line_pos++]; + } + } + + + replaced[size] = 0; + + return replaced; +} diff --git a/smash/env.h b/smash/env.h new file mode 100644 index 0000000..0c233e9 --- /dev/null +++ b/smash/env.h @@ -0,0 +1,9 @@ +#ifndef SMASH_ENV_H +#define SMASH_ENV_H + +#include "../lib/sys/sizes.h" + +void init_arg_env(int argc, const char **argv); +char *new_line_and_replace_vars(const char *line, u64 n); + +#endif diff --git a/smash/main.c b/smash/main.c index 48aaed6..645f4eb 100644 --- a/smash/main.c +++ b/smash/main.c @@ -1,10 +1,12 @@ #include "exec.h" #include "comment.h" +#include "env.h" #include "../lib/sys/io.h" #include "../lib/cstr/cstr.h" #include "../lib/sys/dup2.h" #include "../lib/sys/exit.h" +#include "../lib/malloc/malloc.h" #include "../lib/io/io.h" #include "../lib/sys/errno.h" @@ -53,14 +55,17 @@ int io_getline(int fd, char *linebuf) return size; } -int main(int argc, char *argv[], char *envp[]) +int main(int argc, char *argv[]) { char prompt[] = "$ "; i64 line_length; int fd = STDIN_FD; char linebuf[BUFSIZ]; + char *line; - if (argc == 2) { + init_arg_env(argc, (const char**)argv); + + if (argc > 1) { fd = open(argv[1], OPEN_READ_ONLY, 0); if (fd < 0) { @@ -80,11 +85,14 @@ int main(int argc, char *argv[], char *envp[]) } remove_comment(linebuf); - line_length = cstr_length(linebuf); + line = new_line_and_replace_vars(linebuf, BUFSIZ); + line_length = cstr_length(line); if (line_length > 0) { - exec(linebuf); + exec(line); } + + free(line); } if (fd != STDOUT_FD) -- cgit v1.2.3-70-g09d2