poaflocParser 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