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 5f6fdaafcf0090008b10d438e4cbcbbe7a3ec90f
parent 64db814bc7776fd9567faa466ffbb7813932d83d
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Wed, 12 Jun 2024 09:59:02 +0200

Parse args at the end on in order

Diffstat:
M include/args.h | +
M include/args.hpp | + -
M src/args.cpp | ++++++++++++++++++++++++++++ -----------------------------------
M src/help.cpp | +++ ---

4 files changed, 33 insertions(+), 39 deletions(-)


diff --git a/ include/args.h b/ include/args.h

@@ -91,6 +91,7 @@ enum ENUM_PARSE { MANGLE_ENUM(PARSE, NO_HELP) = 0x2, MANGLE_ENUM(PARSE, NO_EXIT) = 0x4, MANGLE_ENUM(PARSE, SILENT) = 0x8,
MANGLE_ENUM(PARSE, IN_ORDER) = 0x10,
}; #if !defined __cplusplus || defined WITH_C_BINDINGS

diff --git a/ include/args.hpp b/ include/args.hpp

@@ -48,7 +48,7 @@ class Parser { int handle_missing(bool shrt, const char *argv); int handle_excess(bool shrt, const char *argv);
void print_usage(FILE *stream) const;
void print_other_usages(FILE *stream) const;
void help(FILE *stream) const; void usage(FILE *stream) const; void see(FILE *stream) const;

diff --git a/ src/args.cpp b/ src/args.cpp

@@ -15,7 +15,6 @@ int parse(const argp_t *argp, int argc, char *argv[], unsigned flags, } void usage(const Parser *parser) { help(parser, stderr, Help::STD_USAGE); }
void help(const Parser *parser, FILE *stream, unsigned flags) { if (!parser || !stream) return;

@@ -58,30 +57,22 @@ Parser::Parser(const argp_t *argp, unsigned flags, void *input) } if (!opt.key) {
if (!(opt.flags & ALIAS)) {
// non alias without a key, silently ignoring
continue;
}
// non alias without a key, silently ignoring
if (!(opt.flags & ALIAS)) continue;
if (!key_last) {
// nothing to alias, silently ignoring
continue;
}
// nothing to alias, silently ignoring
if (!key_last) continue;
if (!trie.insert(opt.name, key_last)) {
// option not valid, silently ignoring
continue;
}
// option not valid, silently ignoring
if (!trie.insert(opt.name, key_last)) continue;
if (hidden) continue; if (opt.flags & Option::HIDDEN) continue; help_entries.back().push(opt.name); } else {
if (options.count(opt.key)) {
// duplicate key, silently ignoring
continue;
}
// duplicate key, silently ignoring
if (options.count(opt.key)) continue;
if (opt.name) trie.insert(opt.name, opt.key); options[key_last = opt.key] = &opt;

@@ -97,10 +88,8 @@ Parser::Parser(const argp_t *argp, unsigned flags, void *input) if (opt.name) help_entries.back().push(opt.name); if (std::isprint(opt.key)) help_entries.back().push(opt.key); } else {
if (!key_last) {
// nothing to alias, silently ignoring
continue;
}
// nothing to alias, silently ignoring
if (!key_last) continue;
if (hidden) continue; if (opt.flags & Option::HIDDEN) continue;

@@ -125,15 +114,17 @@ Parser::Parser(const argp_t *argp, unsigned flags, void *input) int Parser::parse(int argc, char *argv[], void *input) { const bool is_help = !(m_flags & NO_HELP);
int args = 0, err_code = 0, i;
std::vector<const char *> args;
int arg_cnt = 0, err_code = 0, i;
m_name = basename(argv[0]); argp->parse(Key::INIT, 0, this); for (i = 1; i < argc; i++) { if (argv[i][0] != '-') {
argp->parse(Key::ARG, argv[i], this);
args++;
if (m_flags & IN_ORDER) argp->parse(Key::ARG, argv[i], this);
else args.push_back(argv[i]);
arg_cnt++;
continue; }

@@ -194,15 +185,12 @@ int Parser::parse(int argc, char *argv[], void *input) { } const int key = trie.get(opt_s.data());
if (!key) { err_code = handle_unknown(0, argv[i]); goto error; } const auto *option = options[key];
const char *arg = nullptr;
if (!option->arg && is_eq) { err_code = handle_excess(0, argv[i]); goto error;

@@ -220,13 +208,18 @@ int Parser::parse(int argc, char *argv[], void *input) { } }
// parse previous arguments if IN_ORDER is not set
for (const auto arg : args) {
argp->parse(Key::ARG, arg, this);
}
// parse rest argv as normal arguments for (i = i + 1; i < argc; i++) { argp->parse(Key::ARG, argv[i], this);
args++;
arg_cnt++;
}
if (!args) argp->parse(Key::NO_ARGS, 0, this);
if (!arg_cnt) argp->parse(Key::NO_ARGS, 0, this);
argp->parse(Key::END, 0, this); argp->parse(Key::SUCCESS, 0, this);

@@ -248,8 +241,8 @@ int Parser::handle_unknown(bool shrt, const char *argv) { failure(this, 1, 0, unknown_fmt[shrt], argv + 1); see(stderr);
if(m_flags & NO_EXIT) return 1;
exit(1);
if (m_flags & NO_EXIT) return 1;
exit(1);
} int Parser::handle_missing(bool shrt, const char *argv) {

@@ -263,8 +256,8 @@ int Parser::handle_missing(bool shrt, const char *argv) { failure(this, 2, 0, missing_fmt[shrt], argv + 1); see(stderr);
if(m_flags & NO_EXIT) return 2;
exit(2);
if (m_flags & NO_EXIT) return 2;
exit(2);
} int Parser::handle_excess(bool shrt, const char *argv) {

@@ -273,8 +266,8 @@ int Parser::handle_excess(bool shrt, const char *argv) { failure(this, 3, 0, "option '%s' doesn't allow an argument\n", argv); see(stderr);
if(m_flags & NO_EXIT) return 3;
exit(3);
if (m_flags & NO_EXIT) return 3;
exit(3);
} const char *Parser::basename(const char *name) {

diff --git a/ src/help.cpp b/ src/help.cpp

@@ -30,7 +30,7 @@ bool Parser::help_entry_t::operator<(const help_entry_t &rhs) const { return std::strcmp(opt_long.front(), rhs.opt_long.front()) < 0; }
void Parser::print_usage(FILE *stream) const {
void Parser::print_other_usages(FILE *stream) const {
if (argp->doc) { std::istringstream iss(argp->doc); std::string s;

@@ -54,7 +54,7 @@ void Parser::help(FILE *stream) const { } std::fprintf(stream, "Usage: %s [OPTIONS...]", m_name);
print_usage(stream);
print_other_usages(stream);
if (!m1.empty()) std::fprintf(stream, "\n%s", m1.c_str()); std::fprintf(stream, "\n\n");

@@ -176,7 +176,7 @@ void Parser::usage(FILE *stream) const { } }
print_usage(stream);
print_other_usages(stream);
std::putc('\n', stream); }