summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2022-03-14 08:45:34 -0700
committerVito Caputo <vcaputo@pengaru.com>2022-03-14 18:45:12 -0700
commit4960649f21582a74e949a62b8fde8067852ffab7 (patch)
treea4aa094238979250fc17d6cef640d8c737f38a2e
parent7ff8ef94c05ae6386463b63f3ba25add52340d8b (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.c45
-rw-r--r--src/til_args.h1
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
© All Rights Reserved