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:
M | args.hpp | | | 35 | +++++++++++++++++++++-------------- |
M | demo.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;