aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--smash/Makefile2
-rw-r--r--smash/env.c85
-rw-r--r--smash/env.h9
-rw-r--r--smash/main.c16
4 files changed, 107 insertions, 5 deletions
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)