diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-10-18 15:38:02 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-10-18 15:38:02 -0400 |
| commit | 7e5a1fa68dbdc2aa034d9e22648837ef63e57d5e (patch) | |
| tree | 2b0a210de66f181d395b0330c30fbaa20bfc7e65 /src | |
| parent | f879157284ab9a13fb37cfdc18e7919248fb37fe (diff) | |
Fix '--' arg parsing
Diffstat (limited to 'src')
| -rw-r--r-- | src/stdlib/cli.c | 51 | ||||
| -rw-r--r-- | src/stdlib/cli.h | 2 | ||||
| -rw-r--r-- | src/tomo.c | 2 |
3 files changed, 34 insertions, 21 deletions
diff --git a/src/stdlib/cli.c b/src/stdlib/cli.c index d545cbc3..6e0a4b81 100644 --- a/src/stdlib/cli.c +++ b/src/stdlib/cli.c @@ -205,35 +205,48 @@ void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, const c for (int i = 0; i < spec_len; i++) { parsed[i] = pop_cli_flag(&args, spec[i].short_flag, spec[i].name, spec[i].dest, spec[i].type); } - for (int64_t i = 0; i < (int64_t)args.length; i++) { + + bool show_help = false; + if (pop_boolean_cli_flag(&args, 'h', "help", &show_help) && show_help) { + print(help); + exit(0); + } + bool show_version = false; + if (pop_boolean_cli_flag(&args, 'v', "version", &show_version) && show_version) { + print(version); + exit(0); + } + + List_t before_double_dash = args, after_double_dash = EMPTY_LIST; + for (int i = 0; i < (int64_t)args.length; i++) { const char *arg = *(const char **)(args.data + i * args.stride); if (streq(arg, "--")) { - List$remove_at(&args, I(i + 1), I(1), sizeof(const char *)); + before_double_dash = List$slice(args, I(1), I(i)); + after_double_dash = List$slice(args, I(i + 2), I(-1)); break; } else if (arg[0] == '-') { print_err("Unrecognized argument: ", arg); } } - for (int i = 0; i < spec_len && args.length > 0; i++) { - if (!parsed[i] && spec[i].required) { - parsed[i] = pop_cli_positional(&args, spec[i].name, spec[i].dest, spec[i].type); + + for (int i = 0; i < spec_len && before_double_dash.length > 0; i++) { + if (!parsed[i]) { + parsed[i] = pop_cli_positional(&before_double_dash, spec[i].name, spec[i].dest, spec[i].type, false); } } + for (int i = 0; i < spec_len && after_double_dash.length > 0; i++) { + if (!parsed[i]) { + parsed[i] = pop_cli_positional(&after_double_dash, spec[i].name, spec[i].dest, spec[i].type, true); + } + } + for (int i = 0; i < spec_len; i++) { if (!parsed[i] && spec[i].required) print_err("Missing required flag: --", spec[i].name, "\n", usage); } - bool show_help = false; - if (pop_boolean_cli_flag(&args, 'h', "help", &show_help) && show_help) { - print(help); - exit(0); - } - bool show_version = false; - if (pop_boolean_cli_flag(&args, 'v', "version", &show_version) && show_version) { - print(version); - exit(0); - } - if (args.length > 0) { - print_err("Unknown flag values: ", generic_as_text(&args, true, List$info(&CString$info))); + + List_t remaining_args = List$concat(before_double_dash, after_double_dash, sizeof(const char *)); + if (remaining_args.length > 0) { + print_err("Unknown flag values: ", generic_as_text(&remaining_args, true, List$info(&CString$info))); } } @@ -397,12 +410,12 @@ bool pop_cli_flag(List_t *args, char short_flag, const char *flag, void *dest, c return false; } -bool pop_cli_positional(List_t *args, const char *flag, void *dest, const TypeInfo_t *type) { +bool pop_cli_positional(List_t *args, const char *flag, void *dest, const TypeInfo_t *type, bool allow_dashes) { if (args->length == 0) { print_err("No value provided for flag: --", flag); return false; } - int64_t n = parse_arg_list(*args, flag, dest, type, true); + int64_t n = parse_arg_list(*args, flag, dest, type, allow_dashes); if (n == 0) print_err("No value provided for flag: --", flag); List$remove_at(args, I(1), I(n), sizeof(const char *)); return true; diff --git a/src/stdlib/cli.h b/src/stdlib/cli.h index 8f9e2a9c..596409c1 100644 --- a/src/stdlib/cli.h +++ b/src/stdlib/cli.h @@ -22,4 +22,4 @@ void _tomo_parse_args(int argc, char *argv[], Text_t usage, Text_t help, const c (cli_arg_t[]){__VA_ARGS__}) bool pop_cli_flag(List_t *args, char short_flag, const char *flag, void *dest, const TypeInfo_t *type); -bool pop_cli_positional(List_t *args, const char *flag, void *dest, const TypeInfo_t *type); +bool pop_cli_positional(List_t *args, const char *flag, void *dest, const TypeInfo_t *type, bool allow_dashes); @@ -220,6 +220,7 @@ int main(int argc, char *argv[]) { Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage); tomo_parse_args(argc, argv, usage, help, TOMO_VERSION, // {"run", 'r', false, List$info(&Path$info), &run_files}, // + {"args", '\0', false, List$info(&Text$info), &args}, // {"format", 'F', false, List$info(&Path$info), &format_files}, // {"format-inplace", '\0', false, List$info(&Path$info), &format_files_inplace}, // {"transpile", 't', false, List$info(&Path$info), &transpile_files}, // @@ -237,7 +238,6 @@ int main(int argc, char *argv[]) { {"force-rebuild", 'f', false, &Bool$info, &clean_build}, // {"source-mapping", 'm', false, &Bool$info, &source_mapping}, {"changelog", '\0', false, &Bool$info, &show_changelog}, // - {"args", '\0', false, List$info(&Text$info), &args}, // ); if (show_prefix) { |
