diff options
author | dzwdz | 2022-07-27 20:02:50 +0200 |
---|---|---|
committer | dzwdz | 2022-07-27 20:02:50 +0200 |
commit | 67718cbcda566127b8c5b38ecda83cbd469dbc3f (patch) | |
tree | d87c171a92646048f7c65fe0f9070e9ff4e4211f /src/user/app/shell/parser.c | |
parent | c77b0fa7916f79c099ee4a6a80a093334e9090ac (diff) |
user/shell: actual parsing, multiple argument support
Diffstat (limited to 'src/user/app/shell/parser.c')
-rw-r--r-- | src/user/app/shell/parser.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/user/app/shell/parser.c b/src/user/app/shell/parser.c new file mode 100644 index 0000000..bd70350 --- /dev/null +++ b/src/user/app/shell/parser.c @@ -0,0 +1,64 @@ +#include "shell.h" +#include <stdbool.h> +#include <string.h> + +static bool isspace(char c) { + return c == ' ' || c == '\t' || c == '\n'; +} + +static char skipspace(char **sp) { + char *s = *sp; + while (*s && isspace(*s)) s++; + *sp = s; + return *s; +} + +static char *parg(char **sp) { + char *s = *sp; + char *res = NULL; + + if (skipspace(&s)) { + switch (*s) { + case '"': + s++; + res = s; + while (*s && *s != '"') + s++; + break; + default: + res = s; + while (*s && !isspace(*s) && *s != '>') + s++; + break; + } + if (*s) *s++ = '\0'; + } + + *sp = s; + return res; +} + +int parse(char *s, char **argv, size_t argvlen, char **redir) { + if (argvlen == 0) return -1; + size_t argc = 0; + char *arg; + + *argv = NULL; + *redir = NULL; + + while (skipspace(&s)) { + switch (*s) { + case '>': + s++; + *redir = parg(&s); + break; + default: + arg = parg(&s); + argv[argc++] = arg; + if (argc >= argvlen) + return -1; + } + } + argv[argc] = NULL; + return argc; +} |