poafloc

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

commit 31ec9d8f40fb2be1730ea600e5e73e2cebb8630a
parent 166d7e74f5d7a5c3adc525595375c5fe34ab36b6
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Thu,  6 Jun 2024 04:12:15 +0200

Parse ganged up short options, with trailing arg

Diffstat:
Margs.hpp | 35+++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/args.hpp b/args.hpp @@ -37,8 +37,6 @@ class Parser { } int parse(int argc, char *argv[], void *input) { - const char *arg = nullptr; - char key; int i; for (i = 1; i < argc; i++) { @@ -49,24 +47,37 @@ class Parser { if (argv[i][1] != '-') { const char *opt = argv[i] + 1; - key = opt[0]; + for (int j = 0; opt[j]; j++) { + const char key = opt[j]; - const auto *option = options[key - 'a']; - if (!option) goto unknown; + const auto *option = options[key - 'a']; + if (!option) goto unknown; - if (option->arg) { - if (i == argc) goto missing; - arg = argv[++i]; + const char *arg = nullptr; + if (option->arg) { + if (opt[j + 1] == 0) { + if (i == argc) goto missing; + arg = argv[++i]; + } else { + arg = opt + j + 1; + } + } + + argp->parser(key, arg, input); + + if (arg) break; } } else { const char *opt = argv[i] + 2; const auto eq = std::strchr(opt, '='); - key = trie.get(!eq ? opt : std::string(opt, eq - opt)); + const char key = + trie.get(!eq ? opt : std::string(opt, eq - opt)); if (!key) goto unknown; const auto *option = options[key - 'a']; + const char *arg = nullptr; if (eq) { if (!option->arg) goto excess; @@ -75,9 +86,9 @@ class Parser { if (i == argc) goto missing; arg = argv[++i]; } - } - argp->parser(key, arg, input); + argp->parser(key, arg, input); + } } return 0; @@ -108,8 +119,8 @@ class Parser { trie_t *crnt = this; for (const char c : option) { - crnt->count++; if (!crnt->terminal) crnt->key = key; + crnt->count++; const uint8_t idx = c - 'a'; if (!crnt->children[idx]) crnt->children[idx] = new trie_t();