From e6c8e335dff7a51b1192e04f3174362e6bd6eb1c Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 1 Nov 2023 20:46:26 +0900 Subject: [PATCH] examples/runwasi: separate cli argument processing for easier reuse --- examples/runwasi/CMakeLists.txt | 1 + examples/runwasi/main.c | 83 +++++---------------------- examples/runwasi/runwasi_cli_args.c | 88 +++++++++++++++++++++++++++++ examples/runwasi/runwasi_cli_args.h | 12 ++++ 4 files changed, 115 insertions(+), 69 deletions(-) create mode 100644 examples/runwasi/runwasi_cli_args.c create mode 100644 examples/runwasi/runwasi_cli_args.h diff --git a/examples/runwasi/CMakeLists.txt b/examples/runwasi/CMakeLists.txt index bf4f1f00..3ffdfb48 100644 --- a/examples/runwasi/CMakeLists.txt +++ b/examples/runwasi/CMakeLists.txt @@ -9,6 +9,7 @@ find_package(toywasm-lib-wasi REQUIRED) set(sources "runwasi.c" + "runwasi_cli_args.c" "main.c" ) diff --git a/examples/runwasi/main.c b/examples/runwasi/main.c index 780f9baa..844250f8 100644 --- a/examples/runwasi/main.c +++ b/examples/runwasi/main.c @@ -5,7 +5,6 @@ * % runwasi --dir=. --env=a=b -- foo.wasm -x -y */ -#include #include #include #include @@ -14,85 +13,31 @@ #include #include "runwasi.h" - -enum longopt { - opt_wasi_dir, - opt_wasi_env, -}; - -static const struct option longopts[] = { - { - "dir", - required_argument, - NULL, - opt_wasi_dir, - }, - { - "env", - required_argument, - NULL, - opt_wasi_env, - }, - { - NULL, - 0, - NULL, - 0, - }, -}; +#include "runwasi_cli_args.h" int main(int argc, char **argv) { - unsigned int nenvs = 0; - char **envs = NULL; - unsigned int ndirs = 0; - char **dirs = NULL; - - int ret; - int longidx; - while ((ret = getopt_long(argc, argv, "", longopts, &longidx)) != -1) { - switch (ret) { - case opt_wasi_dir: - ndirs++; - dirs = realloc(dirs, ndirs * sizeof(*dirs)); - if (dirs == NULL) { - xlog_error("realloc failed"); - exit(1); - } - dirs[ndirs - 1] = optarg; - break; - case opt_wasi_env: - nenvs++; - envs = realloc(envs, nenvs * sizeof(*envs)); - if (envs == NULL) { - xlog_error("realloc failed"); - exit(1); - } - envs[nenvs - 1] = optarg; - break; - default: - exit(1); - } - } - argc -= optind; - argv += optind; - if (argc < 1) { - xlog_error("unexpected number of args"); - exit(2); - } - const char *filename = argv[0]; + struct runwasi_cli_args a0; + struct runwasi_cli_args *a = &a0; uint32_t wasi_exit_code; + int ret; const int stdio_fds[3] = { STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, }; - ret = runwasi(filename, ndirs, dirs, nenvs, (const char *const *)envs, - argc, (const char *const *)argv, stdio_fds, NULL, + ret = runwasi_cli_args_parse(argc, argv, a); + if (ret != 0) { + xlog_error("failed to process cli arguments"); + exit(1); + } + ret = runwasi(a->filename, a->ndirs, a->dirs, a->nenvs, + (const char *const *)a->envs, a->argc, + (const char *const *)a->argv, stdio_fds, NULL, &wasi_exit_code); - free(dirs); - free(envs); + free(a->dirs); + free(a->envs); if (ret != 0) { exit(1); } diff --git a/examples/runwasi/runwasi_cli_args.c b/examples/runwasi/runwasi_cli_args.c new file mode 100644 index 00000000..175a37b5 --- /dev/null +++ b/examples/runwasi/runwasi_cli_args.c @@ -0,0 +1,88 @@ + +#include +#include +#include + +#include "runwasi_cli_args.h" + +enum longopt { + opt_wasi_dir, + opt_wasi_env, +}; + +static const struct option longopts[] = { + { + "dir", + required_argument, + NULL, + opt_wasi_dir, + }, + { + "env", + required_argument, + NULL, + opt_wasi_env, + }, + { + NULL, + 0, + NULL, + 0, + }, +}; + +int +runwasi_cli_args_parse(int argc, char **argv, struct runwasi_cli_args *a) +{ + unsigned int nenvs = 0; + char **envs = NULL; + unsigned int ndirs = 0; + char **dirs = NULL; + void *p; + + int ret; + int longidx; + while ((ret = getopt_long(argc, argv, "", longopts, &longidx)) != -1) { + switch (ret) { + case opt_wasi_dir: + ndirs++; + p = realloc(dirs, ndirs * sizeof(*dirs)); + if (p == NULL) { + goto fail; + } + dirs = p; + dirs[ndirs - 1] = optarg; + break; + case opt_wasi_env: + nenvs++; + p = realloc(envs, nenvs * sizeof(*envs)); + if (p == NULL) { + goto fail; + } + envs = p; + envs[nenvs - 1] = optarg; + break; + default: + goto fail; + } + } + argc -= optind; + argv += optind; + if (argc < 1) { + goto fail; + } + const char *filename = argv[0]; + + a->filename = filename; + a->ndirs = ndirs; + a->dirs = dirs; + a->nenvs = nenvs; + a->envs = envs; + a->argc = argc; + a->argv = argv; + return 0; +fail: + free(envs); + free(dirs); + return 1; +} diff --git a/examples/runwasi/runwasi_cli_args.h b/examples/runwasi/runwasi_cli_args.h new file mode 100644 index 00000000..302a1db0 --- /dev/null +++ b/examples/runwasi/runwasi_cli_args.h @@ -0,0 +1,12 @@ + +struct runwasi_cli_args { + const char *filename; + unsigned int ndirs; + char **dirs; + unsigned int nenvs; + char **envs; + int argc; + char **argv; +}; + +int runwasi_cli_args_parse(int argc, char **argv, struct runwasi_cli_args *a);