diff options
author | WormHeamer | 2025-03-08 17:48:05 -0500 |
---|---|---|
committer | WormHeamer | 2025-03-08 17:48:05 -0500 |
commit | 2b156fe0ca12386a7e61c02067bc16f6028d62d6 (patch) | |
tree | c5c1cf01e763371d47592ca7b1d2e090e480ce9e | |
parent | fe358325bd443a076732259bd2a50c97f12d7602 (diff) |
allow -- argument to stop parsing options
-rw-r--r-- | args.h | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/args.h b/args.h index 35c5283..b8e2d94 100644 --- a/args.h +++ b/args.h @@ -6,6 +6,7 @@ typedef struct { const char **arg; const char *opt_end; + int no_opts; } ArgsState; typedef enum { @@ -24,7 +25,7 @@ ArgResult arg_getv(ArgsState *a, const char *fmt, Str *arg, ...); #include <stdarg.h> ArgsState args_begin(const char **argv) { - return (ArgsState) { argv + 1, NULL }; + return (ArgsState) { argv + 1, NULL, 0 }; } static int arg_opt_find(const char **opts, Str key) { @@ -89,21 +90,33 @@ static ArgResult arg_got_short(ArgsState *a, const char *fmt, Str *arg) { } static ArgResult arg_get_long(ArgsState *a, const char *fmt, const char **opts, int *optv, Str *arg) { - if (*a->arg && !**a->arg) a->arg++; +recurse: if (!*a->arg) return ARG_END; + if (a->no_opts) { +pop: *arg = str_from_cstr(*a->arg++); + return ARG_OK; + } const char *arg_end = *a->arg + strlen(*a->arg); - if (a->opt_end != arg_end) { - if (a->arg[0][0] != '-' || a->arg[0][1] == '\0') { - *arg = str_from_cstr(*a->arg++); - return ARG_OK; + if (a->opt_end == arg_end) { + if (!**a->arg) { + a->arg++; + goto recurse; } - if (a->arg[0][1] == '-') { + return arg_got_short(a, fmt, arg); + } + if (**a->arg != '-' || a->arg[0][1] == '\0') goto pop; + if (a->arg[0][1] == '-') { + if (a->arg[0][2] == '\0') { + a->no_opts = 1; + a->arg++; + goto recurse; + } else { return arg_got_long(a, opts, optv, arg); } - (*a->arg)++; - a->opt_end = arg_end; } - return arg_got_short(a, fmt, arg); + (*a->arg)++; + a->opt_end = arg_end; + goto recurse; } ArgResult arg_getv(ArgsState *a, const char *fmt, Str *arg, ...) { |