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 f329d651df3844b0df7a5c997c11004114d70c4f
parent 3cdb743888aa56c5e5301858e24973284a311946
author Dimitrije Dobrota <mail@dimitrijedobrota.com>
date Sat, 8 Jun 2024 20:58:50 +0200

Add groups to options for better --help

Diffstat:
M args.hpp | ++++++++++++++++++++++++++++++++++ --------
M demo.cpp | +++++++++ ----

2 files changed, 43 insertions(+), 12 deletions(-)


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

@@ -19,6 +19,7 @@ class Parser { const char *arg; const uint8_t options; const char *message;
const int group;
}; enum Option {

@@ -47,11 +48,17 @@ class Parser { Parser(argp_t *argp) : argp(argp) { bool hidden = false;
int key_last = 0;
int group = 0, key_last = 0;
for (int i = 0; true; i++) { const auto &opt = argp->options[i];
if (!opt.name && !opt.key) break;
if (!opt.name && !opt.key && !opt.message) break;
if (!opt.name && !opt.key) {
group = opt.group ? opt.group : group + 1;
help_entries.emplace_back(nullptr, opt.message, group);
continue;
}
if (!opt.key) { if ((opt.options & ALIAS) == 0) {

@@ -84,7 +91,8 @@ class Parser { if ((opt.options & ALIAS) == 0) { if ((hidden = opt.options & Option::HIDDEN)) continue;
help_entries.emplace_back(opt.arg, opt.message, arg_opt);
help_entries.emplace_back(opt.arg, opt.message, group,
arg_opt);
if (opt.name) help_entries.back().push(opt.name); if (std::isprint(opt.key)) {

@@ -109,12 +117,11 @@ class Parser { std::sort(begin(help_entries), end(help_entries));
help_entries.emplace_back(nullptr, "Give this help list", false);
help_entries.emplace_back(nullptr, "Give this help list", -1);
help_entries.back().push("help"); help_entries.back().push('?');
help_entries.emplace_back(nullptr, "Give a short usage message",
false);
help_entries.emplace_back(nullptr, "Give a short usage message", -1);
help_entries.back().push("usage"); }

@@ -281,15 +288,25 @@ class Parser { const char *arg; const char *message;
int group;
bool opt;
help_entry_t(const char *arg, const char *message, bool opt)
: arg(arg), message(message), opt(opt) {}
help_entry_t(const char *arg, const char *message, int group,
bool opt = false)
: arg(arg), message(message), group(group), opt(opt) {}
void push(char sh) { opt_short.push_back(sh); } void push(const char *lg) { opt_long.push_back(lg); } bool operator<(const help_entry_t &rhs) const {
if (group && rhs.group) {
if (group < 0 && rhs.group < 0) return group < rhs.group;
if (group < 0 || rhs.group < 0) return rhs.group < 0;
return group < rhs.group;
}
if (group || rhs.group) return !group;
if (opt_long.empty() && rhs.opt_long.empty()) return opt_short.front() < rhs.opt_short.front();

@@ -331,9 +348,18 @@ class Parser { if (!m1.empty()) std::cout << "\n" << m1; std::cout << "\n\n";
bool first = true;
for (const auto &entry : help_entries) { bool prev = false;
if (entry.opt_short.empty() && entry.opt_long.empty()) {
if (!first) std::cout << "\n";
if (entry.message) std::cout << " " << entry.message << ":\n";
continue;
}
first = false;
std::string message = " "; for (const char c : entry.opt_short) { if (!prev) prev = true;

diff --git a/ demo.cpp b/ demo.cpp

@@ -41,12 +41,17 @@ using enum Parser::Option; // clang-format off static const Parser::option_t options[] = {
{ "output", 'o', "file", ARG_OPTIONAL, "Output file, default stdout"},
{ 0, 'i', "file", 0, "Input file"},
{ "debug", 777, 0, 0, "Execute program in debugging mode"},
{ "hex", 'h', 0, 0, "Output in hex format"},
{ 0, 'R', 0, 0, "random 0-group option"},
{ 0, 0, 0, 0, "Program mode", 1},
{ "hex", 'h', 0, 0, "Output in hex format"},
{"hexadecimal", 0, 0, ALIAS | HIDDEN}, {"relocatable", 'r', 0, 0, "Output in relocatable format"},
{ 0, 0, 0, 0, "For developers", 4},
{ "debug", 777, 0, 0, "Enable debugging mode"},
{ 0, 0, 0, 0, "Input/output", 3},
{ "output", 'o', "file", ARG_OPTIONAL, "Output file, default stdout"},
{ 0, 'i', "file", 0, "Input file"},
{ 0, 0, 0, 0, "Informational Options", -1},
{0}, }; // clang-format on