diff options
Diffstat (limited to 'smash/main.c')
| -rw-r--r-- | smash/main.c | 72 |
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) |