From 2046dc0fbdbd77bb05542d7bc7d43edb0f057422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 17 Jul 2019 09:46:45 +0200 Subject: [PATCH] slave: break out command line tokenizer --- meson.build | 1 + slave.c | 80 +----------------------------------------------- tokenize.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tokenize.h | 5 +++ 4 files changed, 94 insertions(+), 79 deletions(-) create mode 100644 tokenize.c create mode 100644 tokenize.h diff --git a/meson.build b/meson.build index 37a3ed26..934e2681 100644 --- a/meson.build +++ b/meson.build @@ -73,6 +73,7 @@ executable( 'shm.c', 'shm.h', 'slave.c', 'slave.h', 'terminal.c', 'terminal.h', + 'tokenize.c', 'tokenize.h', 'tllist.h', 'vt.c', 'vt.h', wl_proto_src + wl_proto_headers, diff --git a/slave.c b/slave.c index 2910a554..86d5b94f 100644 --- a/slave.c +++ b/slave.c @@ -11,85 +11,7 @@ #define LOG_MODULE "slave" #define LOG_ENABLE_DBG 0 #include "log.h" - -static bool -push_argv(char ***argv, size_t *size, char *arg, size_t *argc) -{ - if (arg != NULL && arg[0] == '%') - return true; - - if (*argc >= *size) { - size_t new_size = *size > 0 ? 2 * *size : 10; - char **new_argv = realloc(*argv, new_size * sizeof(new_argv[0])); - - if (new_argv == NULL) - return false; - - *argv = new_argv; - *size = new_size; - } - - (*argv)[(*argc)++] = arg; - return true; -} - -static bool -tokenize_cmdline(char *cmdline, char ***argv) -{ - *argv = NULL; - size_t argv_size = 0; - - bool first_token_is_quoted = cmdline[0] == '"' || cmdline[0] == '\''; - char delim = first_token_is_quoted ? cmdline[0] : ' '; - - char *p = first_token_is_quoted ? &cmdline[1] : &cmdline[0]; - - size_t idx = 0; - while (*p != '\0') { - char *end = strchr(p, delim); - if (end == NULL) { - if (delim != ' ') { - LOG_ERR("unterminated %s quote\n", delim == '"' ? "double" : "single"); - free(*argv); - return false; - } - - if (!push_argv(argv, &argv_size, p, &idx) || - !push_argv(argv, &argv_size, NULL, &idx)) - { - goto err; - } else - return true; - } - - *end = '\0'; - - if (!push_argv(argv, &argv_size, p, &idx)) - goto err; - - p = end + 1; - while (*p == delim) - p++; - - while (*p == ' ') - p++; - - if (*p == '"' || *p == '\'') { - delim = *p; - p++; - } else - delim = ' '; - } - - if (!push_argv(argv, &argv_size, NULL, &idx)) - goto err; - - return true; - -err: - free(*argv); - return false; -} +#include "tokenize.h" void slave_spawn(int ptmx, char *cmd, int err_fd) diff --git a/tokenize.c b/tokenize.c new file mode 100644 index 00000000..b4aab6b5 --- /dev/null +++ b/tokenize.c @@ -0,0 +1,87 @@ +#include "tokenize.h" + +#include +#include + +#define LOG_MODULE "tokenize" +#define LOG_ENABLE_DBG 0 +#include "log.h" + +static bool +push_argv(char ***argv, size_t *size, char *arg, size_t *argc) +{ + if (arg != NULL && arg[0] == '%') + return true; + + if (*argc >= *size) { + size_t new_size = *size > 0 ? 2 * *size : 10; + char **new_argv = realloc(*argv, new_size * sizeof(new_argv[0])); + + if (new_argv == NULL) + return false; + + *argv = new_argv; + *size = new_size; + } + + (*argv)[(*argc)++] = arg; + return true; +} + +bool +tokenize_cmdline(char *cmdline, char ***argv) +{ + *argv = NULL; + size_t argv_size = 0; + + bool first_token_is_quoted = cmdline[0] == '"' || cmdline[0] == '\''; + char delim = first_token_is_quoted ? cmdline[0] : ' '; + + char *p = first_token_is_quoted ? &cmdline[1] : &cmdline[0]; + + size_t idx = 0; + while (*p != '\0') { + char *end = strchr(p, delim); + if (end == NULL) { + if (delim != ' ') { + LOG_ERR("unterminated %s quote\n", delim == '"' ? "double" : "single"); + free(*argv); + return false; + } + + if (!push_argv(argv, &argv_size, p, &idx) || + !push_argv(argv, &argv_size, NULL, &idx)) + { + goto err; + } else + return true; + } + + *end = '\0'; + + if (!push_argv(argv, &argv_size, p, &idx)) + goto err; + + p = end + 1; + while (*p == delim) + p++; + + while (*p == ' ') + p++; + + if (*p == '"' || *p == '\'') { + delim = *p; + p++; + } else + delim = ' '; + } + + if (!push_argv(argv, &argv_size, NULL, &idx)) + goto err; + + return true; + +err: + free(*argv); + return false; +} diff --git a/tokenize.h b/tokenize.h new file mode 100644 index 00000000..f9579255 --- /dev/null +++ b/tokenize.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +bool tokenize_cmdline(char *cmdline, char ***argv);