From 5b97afd1bce6b4114792f97a417dd7af02cd570b Mon Sep 17 00:00:00 2001 From: "S.J.R. van Schaik" Date: Thu, 20 Jul 2017 16:16:53 +0200 Subject: [PATCH] shell: implement functions to parse command lines into an (argc, argv) tuple --- Makefile | 1 + include/shell.h | 3 +++ source/shell/args.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 source/shell/args.c diff --git a/Makefile b/Makefile index 8c689ec..b2eb853 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,7 @@ obj-y += source/ftl/ftl.o obj-y += source/ftl/gc.o obj-y += source/ftl/map.o +obj-y += source/shell/args.o obj-y += source/shell/cmd.o obj-y += source/shell/flash.o obj-y += source/shell/ftl.o diff --git a/include/shell.h b/include/shell.h index ba12b24..54ff439 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,5 +1,8 @@ #pragma once +size_t count_args(char *line); +char **parse_args(char *line, size_t *argc); + struct cmd { const char *key; void (* exec)(const char *line); diff --git a/source/shell/args.c b/source/shell/args.c new file mode 100644 index 0000000..6fc08bb --- /dev/null +++ b/source/shell/args.c @@ -0,0 +1,75 @@ +#include +#include +#include + +#include + +size_t count_args(char *line) +{ + char *p = line; + size_t n = 0; + + while (*p != '\0') { + p += strspn(p, " \n\r"); + + while (*p != '\0' && *p != ' ') { + if (*p++ != '\"') + continue; + + while (*p != '\0' && *p != '\"') + ++p; + + if (*p == '\"') + ++p; + } + + ++n; + } + + return n; +} + +char **parse_args(char *line, size_t *argc) +{ + char **argv; + char **arg; + char *p = line; + char *s; + size_t n; + + if (!argc) + argc = &n; + + *argc = count_args(line); + + if (!(argv = malloc(*argc * sizeof(char *) + strlen(line) + 1))) + return NULL; + + arg = argv; + s = (char *)argv + *argc * sizeof(char *); + + while (*p != '\0') { + p += strspn(p, " \n\r"); + *arg++ = s; + + while (*p != '\0' && *p != ' ') { + if (*p != '\"') { + *s++ = *p++; + continue; + } + + ++p; + + while (*p != '\0' && *p != '\"') + *s++ = *p++; + + if (*p == '\"') + ++p; + } + + *s++ = '\0'; + } + + return argv; +} +