poafloc

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

commit 2a2b4adf380a3a90c6a04413958986b622219bcf
parent 4cda95db89f7f2106d3f7a9c0374c0d1490402db
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Sat, 8 Jun 2024 21: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 | +++++++++++++++++++++ --------------
M demo.cpp | +++++++++ -------------

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;