aboutsummaryrefslogtreecommitdiff
path: root/smash
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2023-02-08 13:19:56 +0100
committerNathan Reiner <nathan@nathanreiner.xyz>2023-02-08 13:19:56 +0100
commitd7229970f8910aa756d299f8bdceee7f4d1fbfbc (patch)
treea95ff2e6bd50578d34d6449c9fde173acc0ef59c /smash
parente947b1459f93f11ad91f3e920676fe1b828281e7 (diff)
add env and make smash be able to parse files with comments
Diffstat (limited to 'smash')
-rw-r--r--smash/Makefile2
-rw-r--r--smash/comment.c6
-rw-r--r--smash/comment.h6
-rw-r--r--smash/main.c72
4 files changed, 68 insertions, 18 deletions
diff --git a/smash/Makefile b/smash/Makefile
index 8bae278..1d8e228 100644
--- a/smash/Makefile
+++ b/smash/Makefile
@@ -17,4 +17,4 @@ unit_test_exec:
./test
all:
- gcc main.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 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/comment.c b/smash/comment.c
new file mode 100644
index 0000000..8171cf1
--- /dev/null
+++ b/smash/comment.c
@@ -0,0 +1,6 @@
+#include "comment.h"
+
+void remove_comment(char *line) {
+ while (*line && *line != '#') ++line;
+ *line = 0;
+}
diff --git a/smash/comment.h b/smash/comment.h
new file mode 100644
index 0000000..f20877f
--- /dev/null
+++ b/smash/comment.h
@@ -0,0 +1,6 @@
+#ifndef COMMENT_H
+#define COMMENT_H
+
+void remove_comment(char *line);
+
+#endif
diff --git a/smash/main.c b/smash/main.c
index ed41b70..4d81f18 100644
--- a/smash/main.c
+++ b/smash/main.c
@@ -1,52 +1,90 @@
#include "exec.h"
+#include "comment.h"
#include "../lib/sys/io.h"
#include "../lib/cstr/cstr.h"
#include "../lib/sys/dup2.h"
+#include "../lib/sys/exit.h"
#include "../lib/io/io.h"
#include "../lib/sys/errno.h"
-#define BUFSIZ 1024
+#define BUFSIZ 16384
-void clear_buf(char *buf)
+char buf[BUFSIZ] = {0};
+int getline(int fd, char *linebuf)
{
- for (int i = 0; i < BUFSIZ; ++i)
- buf[i] = 0;
+ u64 size = 0;
+ char *line = buf;
+
+ while (*line && *line != '\n') line++;
+
+ if (!*line) {
+ u64 s = cstr_length(buf);
+ s = read(fd, buf + s, BUFSIZ - s - 1);
+
+ if (s == 0) {
+ return -1;
+ }
+
+ buf[s] = 0;
+ while (*line && *line != '\n') line++;
+
+ if (!*line) {
+ wf(STDERR_FD, "line too long to handle, exiting.\n");
+ exit(-1);
+ }
+ }
+
+ *line = 0;
+ ++line;
+
+ size = cstr_length(buf);
+ for (int i = 0; buf[i]; ++i) linebuf[i] = buf[i];
+ linebuf[size] = 0;
+
+ buf[0] = 0;
+ for (int i = 0; *line; ++i) {
+ buf[i] = *line;
+ buf[i + 1] = 0;
+ ++line;
+ }
+
+ return size;
}
int main(int argc, char *argv[], char *envp[])
{
- char buf[BUFSIZ] = {0};
char prompt[] = "$ ";
- u64 line_length;
+ i64 line_length;
int fd = STDIN_FD;
+ char linebuf[BUFSIZ];
if (argc == 2) {
fd = open(argv[1], OPEN_READ_ONLY, 0);
- if (fd < 0)
- wstdf("%s\n", errstr[-fd]);
+ if (fd < 0) {
+ wff(STDERR_FD, "smash: %s\n", errstr[-fd]);
+ return -1;
+ }
}
while (1) {
if (fd == STDIN_FD)
- write(STDOUT_FD, prompt, cstr_length(prompt));
- int p = read(fd, buf, BUFSIZ);
- line_length = cstr_length(buf);
+ wstd(prompt);
+ line_length = getline(fd, linebuf);
- if (line_length == 0)
+ if (line_length == -1) {
break;
+ }
- if (buf[line_length - 1] == '\n')
- buf[--line_length] = 0;
+ remove_comment(linebuf);
+ line_length = cstr_length(linebuf);
if (line_length > 0) {
- exec(buf);
+ exec(linebuf);
}
-
- clear_buf(buf);
}
if (fd != STDOUT_FD)