diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2022-03-14 08:45:34 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2022-03-14 18:45:12 -0700 |
commit | 4960649f21582a74e949a62b8fde8067852ffab7 (patch) | |
tree | a4aa094238979250fc17d6cef640d8c737f38a2e | |
parent | 7ff8ef94c05ae6386463b63f3ba25add52340d8b (diff) |
til_args: introduce til_args_pruned_parse() variant
When integrating libtil into higher order application/gui
toolkits, it's desirable to passthru any unhandled arguments to
the toolkit's initializer.
The specific impetus for adding this is glimmer, which uses
gtk/glib where g_application_run() wants an argv but won't know
what to do with the libtil-recognized args.
-rw-r--r-- | src/til_args.c | 45 | ||||
-rw-r--r-- | src/til_args.h | 1 |
2 files changed, 43 insertions, 3 deletions
diff --git a/src/til_args.c b/src/til_args.c index ae1346c..b010b04 100644 --- a/src/til_args.c +++ b/src/til_args.c @@ -1,5 +1,6 @@ #include <assert.h> #include <errno.h> +#include <stdlib.h> #include <string.h> #include "til_args.h" @@ -9,12 +10,32 @@ * ./rototiller --video=sdl,size=640x480 * ./rototiller --module=roto,foo=bar,module=settings * ./rototiller --defaults + * + * unrecognized arguments trigger an -EINVAL error, unless res_{argc,argv} are non-NULL + * where a new argv will be allocated and populated with the otherwise invalid arguments + * in the same order they were encountered in the input argv. This is to support integration + * with argv-handling application libraries like glib(g_application_run()). */ -int til_args_parse(int argc, const char *argv[], til_args_t *res_args) +static int args_parse(int argc, const char *argv[], til_args_t *res_args, int *res_argc, const char **res_argv[]) { - assert(argc > 0); assert(argv); assert(res_args); + assert(!res_argc || res_argv); + + if (res_argv) { + *res_argv = calloc(argc + 1, sizeof(*res_argv)); + + if (!*res_argv) + return -ENOMEM; + + *res_argc = 0; + } + + if (!argc) + return 0; + + if (res_argv) + (*res_argv)[(*res_argc)++] = argv[0]; /* this is intentionally being kept very simple, no new dependencies like getopt. */ @@ -28,7 +49,10 @@ int til_args_parse(int argc, const char *argv[], til_args_t *res_args) } else if (!strcmp("--help", argv[i])) { res_args->help = 1; } else { - return -EINVAL; + if (!res_argv) + return -EINVAL; + + (*res_argv)[(*res_argc)++] = argv[i]; } } @@ -36,6 +60,21 @@ int til_args_parse(int argc, const char *argv[], til_args_t *res_args) } +int til_args_pruned_parse(int argc, const char *argv[], til_args_t *res_args, int *res_argc, const char **res_argv[]) +{ + assert(res_argc && res_argv); + + return args_parse(argc, argv, res_args, res_argc, res_argv); +} + + +int til_args_parse(int argc, const char *argv[], til_args_t *res_args) +{ + return args_parse(argc, argv, res_args, NULL, NULL); + +} + + int til_args_help(FILE *out) { return fprintf(out, diff --git a/src/til_args.h b/src/til_args.h index 018ae80..a94b7a1 100644 --- a/src/til_args.h +++ b/src/til_args.h @@ -12,6 +12,7 @@ typedef struct til_args_t { } til_args_t; int til_args_parse(int argc, const char *argv[], til_args_t *res_args); +int til_args_pruned_parse(int argc, const char *argv[], til_args_t *res_args, int *res_argc, const char **res_argv[]); int til_args_help(FILE *out); #endif |