Skip to content

Commit

Permalink
examples/runwasi: separate cli argument processing for easier reuse
Browse files Browse the repository at this point in the history
  • Loading branch information
yamt committed Nov 1, 2023
1 parent 51504f9 commit e6c8e33
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 69 deletions.
1 change: 1 addition & 0 deletions examples/runwasi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ find_package(toywasm-lib-wasi REQUIRED)

set(sources
"runwasi.c"
"runwasi_cli_args.c"
"main.c"
)

Expand Down
83 changes: 14 additions & 69 deletions examples/runwasi/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* % runwasi --dir=. --env=a=b -- foo.wasm -x -y
*/

#include <getopt.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
Expand All @@ -14,85 +13,31 @@
#include <toywasm/xlog.h>

#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);
}
Expand Down
88 changes: 88 additions & 0 deletions examples/runwasi/runwasi_cli_args.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@

#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>

#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;
}
12 changes: 12 additions & 0 deletions examples/runwasi/runwasi_cli_args.h
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit e6c8e33

Please sign in to comment.