poafloc

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

commit 2a2b4adf380a3a90c6a04413958986b622219bcf
parent 4cda95db89f7f2106d3f7a9c0374c0d1490402db
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Sat,  8 Jun 2024 23:35:46 +0200

Change interface to use 1 static function

* Use static function as an entry point
* Proveded callback accepts Parser* for interfacing with the parser

Diffstat:
Margs.hpp | 35+++++++++++++++++++++--------------
Mdemo.cpp | 22+++++++++-------------
2 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/args.hpp b/args.hpp @@ -38,7 +38,7 @@ class Parser { }; struct argp_t { - using parse_f = int (*)(int key, const char *arg, void *input); + using parse_f = int (*)(int key, const char *arg, Parser *parser); const option_t *options; const parse_f parser; @@ -46,7 +46,15 @@ class Parser { const char *message; }; - Parser(argp_t *argp) : argp(argp) { + static int parse(argp_t *argp, int argc, char *argv[], void *input) { + Parser parser(input, argp); + return parser.parse(argc, argv, &parser); + } + + void *input; + + private: + Parser(void *input, argp_t *argp) : input(input), argp(argp) { bool hidden = false; int group = 0, key_last = 0; @@ -128,11 +136,11 @@ class Parser { int parse(int argc, char *argv[], void *input) { int args = 0, i; - argp->parser(Key::INIT, 0, input); + argp->parser(Key::INIT, 0, this); for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { - argp->parser(Key::ARG, argv[i], input); + argp->parser(Key::ARG, argv[i], this); args++; continue; } @@ -164,7 +172,7 @@ class Parser { } } - argp->parser(key, arg, input); + argp->parser(key, arg, this); // if last option required argument we are done if (arg) break; @@ -204,40 +212,39 @@ class Parser { } } - argp->parser(key, arg, input); + argp->parser(key, arg, this); } } // parse rest argv as normal arguments for (i = i + 1; i < argc; i++) { - argp->parser(Key::ARG, argv[i], input); + argp->parser(Key::ARG, argv[i], this); args++; } - if (!args) argp->parser(Key::NO_ARGS, 0, input); + if (!args) argp->parser(Key::NO_ARGS, 0, this); - argp->parser(Key::END, 0, input); - argp->parser(Key::SUCCESS, 0, input); + argp->parser(Key::END, 0, this); + argp->parser(Key::SUCCESS, 0, this); return 0; unknown: std::cerr << std::format("unknown option {}\n", argv[i]); - argp->parser(Key::ERROR, 0, input); + argp->parser(Key::ERROR, 0, this); return 1; missing: std::cerr << std::format("option {} missing a value\n", argv[i]); - argp->parser(Key::ERROR, 0, input); + argp->parser(Key::ERROR, 0, this); return 2; excess: std::cerr << std::format("option {} don't require a value\n", argv[i]); - argp->parser(Key::ERROR, 0, input); + argp->parser(Key::ERROR, 0, this); return 3; } - private: class trie_t { public: ~trie_t() noexcept { diff --git a/demo.cpp b/demo.cpp @@ -15,8 +15,8 @@ struct arguments_t { std::vector<const char *> args; }; -int parse_opt(int key, const char *arg, void *input) { - auto arguments = (arguments_t *)input; +int parse_opt(int key, const char *arg, Parser *parser) { + auto arguments = (arguments_t *)parser->input; switch (key) { case 777: arguments->debug = true; break; @@ -45,7 +45,7 @@ static const Parser::option_t options[] = { { 0, 0, 0, 0, "Program mode", 1}, {"relocatable", 'r', 0, 0, "Output in relocatable format"}, { "hex", 'h', 0, 0, "Output in hex format"}, - {"hexadecimal", 0, 0, ALIAS | HIDDEN}, + {"hexadecimal", 0, 0, ALIAS | HIDDEN}, { 0, 0, 0, 0, "For developers", 4}, { "debug", 777, 0, 0, "Enable debugging mode"}, { 0, 0, 0, 0, "Input/output", 3}, @@ -57,17 +57,12 @@ static const Parser::option_t options[] = { // clang-format on int main(int argc, char *argv[]) { - Parser::argp_t argp = { - options, - parse_opt, - "doc string\nother usage", - "First half of the message\vsecond half of the message" - }; - Parser parser(&argp); - arguments_t arguments; + Parser::argp_t argp = { + options, parse_opt, "doc string\nother usage", + "First half of the message\vsecond half of the message"}; - if (parser.parse(argc, argv, &arguments)) { + if (Parser::parse(&argp, argc, argv, &arguments)) { error("There was an error while parsing arguments"); return 1; } @@ -81,7 +76,8 @@ int main(int argc, char *argv[]) { std::cout << "\t relocatable: " << arguments.relocatable << std::endl; std::cout << "\t args: "; - for (const auto &arg : arguments.args) std::cout << arg << " "; + for (const auto &arg : arguments.args) + std::cout << arg << " "; std::cout << std::endl; return 0;