poafloc

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

commit fc5fd6d67d7b63502daeaad8e19df559d782a209
parent c45774b431a3c3f91c0f6e2400265cb16395ccf1
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Sat,  8 Jun 2024 20:42:51 +0200

Add --usage option

Diffstat:
Margs.hpp | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+), 0 deletions(-)

diff --git a/args.hpp b/args.hpp @@ -104,6 +104,10 @@ class Parser { help_entries.emplace_back(nullptr, "Give this help list", false); help_entries.back().push("help"); help_entries.back().push('?'); + + help_entries.emplace_back(nullptr, "Give a short usage message", + false); + help_entries.back().push("usage"); } int parse(int argc, char *argv[], void *input) { @@ -161,6 +165,11 @@ class Parser { help(argv[0]); } + if (opt_s == "usage") { + if (eq) goto excess; + usage(argv[0]); + } + const int key = trie.get(opt_s); if (!key) goto unknown; @@ -364,6 +373,72 @@ class Parser { exit(0); } + void usage(const char *name) const { + static const std::size_t limit = 60; + static std::size_t count = 0; + + static const auto print = [](const std::string &message) { + if (count + size(message) > limit) { + std::cout << "\n "; + count = 6; + } + std::cout << message; + count += size(message); + }; + + std::string message = std::format("Usage: {}", name); + + message += " [-"; + for (int i = 0; true; i++) { + const auto &opt = argp->options[i]; + if (!opt.name && !opt.key) break; + if (!std::isprint(opt.key)) continue; + if (opt.arg) continue; + + message += (char)opt.key; + } + message += "?]"; + + std::cout << message; + count = size(message); + + for (int i = 0; true; i++) { + const auto &opt = argp->options[i]; + if (!opt.name && !opt.key) break; + if (!std::isprint(opt.key)) continue; + if (!opt.arg) continue; + + if (opt.options & Option::ARG_OPTIONAL) { + print(std::format(" [-{}[{}]]", (char)opt.key, opt.arg)); + } else { + print(std::format(" [-{} {}]", (char)opt.key, opt.arg)); + } + } + + for (int i = 0; true; i++) { + const auto &opt = argp->options[i]; + if (!opt.name && !opt.key) break; + if (!opt.name) continue; + + if (!opt.arg) print(std::format(" [--{}]", opt.name)); + else { + if (opt.options & Option::ARG_OPTIONAL) { + print(std::format(" [--{}[={}]]", opt.name, opt.arg)); + } else { + print(std::format(" [--{}={}]", opt.name, opt.arg)); + } + } + } + + print(" [--help]"); + print(" [--usage] "); + if (argp->doc) print(argp->doc); + + std::cout << std::endl; + + exit(0); + } + const argp_t *argp; std::unordered_map<int, const option_t *> options;