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 |

commit2a2b4adf380a3a90c6a04413958986b622219bcf
parent4cda95db89f7f2106d3f7a9c0374c0d1490402db
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateSat, 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:
Margs.hpp|+++++++++++++++++++++--------------
Mdemo.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;