summaryrefslogtreecommitdiff
path: root/src/user/app/shell/parser.c
diff options
context:
space:
mode:
authordzwdz2022-07-27 20:02:50 +0200
committerdzwdz2022-07-27 20:02:50 +0200
commit67718cbcda566127b8c5b38ecda83cbd469dbc3f (patch)
treed87c171a92646048f7c65fe0f9070e9ff4e4211f /src/user/app/shell/parser.c
parentc77b0fa7916f79c099ee4a6a80a093334e9090ac (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.c64
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;
+}