From 642b5fb0007b64c77d186fcb018d571152ee1d47 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Mon, 14 Aug 2023 18:51:07 +0200 Subject: reorganization: first steps --- src/cmd/shell/parser.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/cmd/shell/parser.c (limited to 'src/cmd/shell/parser.c') diff --git a/src/cmd/shell/parser.c b/src/cmd/shell/parser.c new file mode 100644 index 0000000..ad09348 --- /dev/null +++ b/src/cmd/shell/parser.c @@ -0,0 +1,76 @@ +#include "shell.h" +#include +#include +#include + +static char skipspace(char **sp) { + char *s = *sp; + while (*s && isspace(*s)) s++; + *sp = s; + return *s; +} + +static bool isspecial(char c) { + return c == '>' || c == '#'; +} + +static char *parg(char **sp) { + char *s = *sp; + char *res = NULL; + + if (skipspace(&s)) { + // TODO incorrectly handles strings like a"b" + switch (*s) { + case '"': + s++; + res = s; + while (*s && *s != '"') + s++; + break; + default: + res = s; + while (*s && !isspace(*s) && !isspecial(*s)) + s++; + if (*s == '#') { + *s = '\0'; /* end parsing early */ + if (res == s) /* don't output an empty arg */ + res = NULL; + } + break; + } + if (*s) *s++ = '\0'; + } + + *sp = s; + return res; +} + +int parse(char *s, char **argv, size_t argvlen, struct redir *redir) { + if (argvlen == 0) return -1; + size_t argc = 0; + char *arg; + + *argv = NULL; + redir->stdout = NULL; + redir->append = false; + + while (skipspace(&s)) { + switch (*s) { + case '>': + s++; + if (*s == '>') { + s++; + redir->append = true; + } + redir->stdout = parg(&s); + break; + default: + arg = parg(&s); + argv[argc++] = arg; + if (argc >= argvlen) + return -1; + } + } + argv[argc] = NULL; + return argc; +} -- cgit v1.2.3