aboutsummaryrefslogtreecommitdiff
path: root/smash/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'smash/main.c')
-rw-r--r--smash/main.c72
1 files changed, 55 insertions, 17 deletions
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)