poafloc

poafloc - Parser Of Arguments For Lines Of Commands
git clone git://git.dimitrijedobrota.com/poafloc.git
Log | Files | Refs | README | LICENSE

commit 394aa9e76ad447d967bf40ddef9eecd1fef06735
parent a23c8139cf1ef9d4141701edc0385ab26b07cebd
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Thu,  6 Jun 2024 14:25:22 +0200

Options with optional arguments

* Long options with optional argument require '='
* Short options with optional argument cannot be ganged together

Diffstat:
Margs.hpp | 25++++++++++++++++---------
Mdemo.cpp | 14++++++++------
2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/args.hpp b/args.hpp @@ -13,6 +13,13 @@ class Parser { const char *name; const char key; const char *arg; + const uint8_t options; + }; + + enum Option { + ARG_OPTIONAL = 0x1, + HIDDEN = 0x2, + ALIAS = 0x3, }; struct argp_t { @@ -58,11 +65,10 @@ class Parser { const char *arg = nullptr; if (option->arg) { - if (opt[j + 1] == 0) { + if (opt[j + 1] != 0) arg = opt + j + 1; + else if ((option->options & ARG_OPTIONAL) == 0) { if (i == argc) goto missing; arg = argv[++i]; - } else { - arg = opt + j + 1; } } @@ -82,12 +88,13 @@ class Parser { const auto *option = options[key - 'a']; const char *arg = nullptr; - if (eq) { - if (!option->arg) goto excess; - arg = eq + 1; - } else if (option->arg) { - if (i == argc) goto missing; - arg = argv[++i]; + if (!option->arg && eq) goto excess; + if (option->arg) { + if (eq) arg = eq + 1; + else if ((option->options & ARG_OPTIONAL) == 0) { + if (i == argc) goto missing; + arg = argv[++i]; + } } argp->parser(key, arg, input); diff --git a/demo.cpp b/demo.cpp @@ -29,7 +29,7 @@ int parse_opt(int key, const char *arg, void *input) { if (arguments->hex) error("cannot mix -hex and -relocatable"); arguments->relocatable = true; break; - case 'o': arguments->output_file = arg; break; + case 'o': arguments->output_file = arg ? arg : "stdout"; break; case 'i': arguments->input_file = arg; break; default: arguments->args.push_back(arg); } @@ -37,13 +37,15 @@ int parse_opt(int key, const char *arg, void *input) { return 0; } +using enum Parser::Option; + // clang-format off static const Parser::option_t options[] = { - { 0, 'o', "file"}, - { "input", 'i', "file"}, - { "debug", 'd', 0}, - { "hex", 'h', 0}, - {"relocatable", 'r', 0}, + { "output", 'o', "file", ARG_OPTIONAL}, + { 0, 'i', "file", 0}, + { "debug", 'd', 0, 0}, + { "hex", 'h', 0, 0}, + {"relocatable", 'r', 0, 0}, {0}, }; // clang-format on