Go to the documentation of this file.
127 #ifndef _POWERDXX_NIH_OPTIONS_HPP_
128 #define _POWERDXX_NIH_OPTIONS_HPP_
133 #include <type_traits>
159 template <
class OptionT,
class =
void>
162 template <
class OptionT>
163 struct enum_has_members<OptionT, std::void_t<decltype(OptionT::OPT_UNKNOWN),
164 decltype(OptionT::OPT_NOOPT),
165 decltype(OptionT::OPT_DASH),
166 decltype(OptionT::OPT_LDASH),
167 decltype(OptionT::OPT_DONE)>> : std::true_type {};
182 template <
class OptionT>
226 template <
class OptionT>
228 if (!def.
args || !def.
args[0]) {
return 0; }
230 for (
char const * pch = def.
args; *pch; ++pch) {
231 argc += (*pch ==
',' ? 1 : 0);
248 template <
class OptionT,
size_t DefCount>
251 "The enum must have the members OPT_UNKNOWN, OPT_NOOPT, OPT_DASH, OPT_LDASH and OPT_DONE");
261 char const *
const *
const argv;
277 OptionT::OPT_UNKNOWN, 0,
nullptr,
nullptr,
nullptr
284 OptionT::OPT_NOOPT, 0,
nullptr,
nullptr,
nullptr
291 OptionT::OPT_DASH, 0,
nullptr,
nullptr,
nullptr
298 OptionT::OPT_LDASH, 0,
nullptr,
nullptr,
nullptr
339 for (
auto ptr = file; *ptr; ++ptr) {
340 if (*ptr ==
'/' || *ptr ==
'\\') {
357 static bool match(
char const *
const lstr,
char const *
const rstr) {
359 for (; lstr[i] && rstr[i]; ++i) {
360 if (lstr[i] != rstr[i]) {
return false; }
362 return lstr[i] == rstr[i];
375 static bool bmatch(
char const *
const str,
376 char const *
const prefix) {
378 for (; str[i] && prefix[i]; ++i) {
379 if (str[i] != prefix[i]) {
return false; }
393 for (
auto const & def : this->
defs) {
394 if (def.sparam == ch) {
410 for (
auto const & def : this->
defs) {
411 if (
match(str, def.lparam)) {
430 char const *
const usage,
454 if (this->argp && this->argp[0] && this->argp[1]) {
457 if (
argCount(*this->current) == 0) {
463 this->argp =
nullptr;
464 this->argi +=
argCount(*this->current);
469 this->argp =
nullptr;
470 this->argi +=
argCount(*this->current) + 1;
475 this->argp =
nullptr;
482 if (this->argi >= this->argc) {
484 this->current =
nullptr;
489 this->current = &
get(this->argp[0]);
493 if (
bmatch(this->argv[this->argi],
"--")) {
494 if (!this->argv[this->argi][2]) {
498 this->current = &
get(this->argv[this->argi] + 2);
502 if (this->argv[this->argi][0] ==
'-') {
503 if (!this->argv[this->argi][1]) {
507 this->argp = this->argv[this->
argi] + 1;
508 this->current = &
get(this->argp[0]);
534 operator OptionT()
const {
558 if (this->argp && this->argp[0] && this->argp[1] && i > 0) {
559 if (this->argi + i - 1 >= this->argc) {
563 return this->argp + 1;
565 return this->argv[this->argi + i - 1];
568 if (this->argi + i < 0) {
572 if (this->argi + i < this->
argc) {
573 return this->argv[this->argi + i];
588 auto result =
"usage: %s %s\n\n"_fmt
592 size_t lparam_max = 0;
594 for (
auto const & def : this->
defs) {
596 auto const len = std::string{def.lparam}.size();
598 lparam_max >= len ? lparam_max : len;
600 auto const len = std::string{def.args}.size();
601 args_max = args_max >= len ? args_max : len;
604 for (
auto const & def : this->defs) {
606 auto const sparam = def.sparam ? def.sparam :
' ';
607 auto const sdash = def.sparam ?
'-' :
' ';
608 auto const lparam = def.lparam ? def.lparam :
"";
609 auto const ldash = lparam[0] ?
'-' :
' ';
610 auto const sep = def.sparam && lparam[0] ?
',' :
' ';
611 result +=
" %c%c%c %c%c%-*s "_fmt
613 ldash, ldash, lparam_max, lparam);
616 for (
auto it = def.args; it && *it; ++it, --len) {
617 result += *it ==
',' ?
' ' : *it;
619 result +=
"%-*s %s\n"_fmt(len,
"", def.usage);
644 char const *
const select = (*this)[i];
647 char const *
const argp = i == 0 ? this->
argp :
nullptr;
650 ptrdiff_t length = 1;
653 for (
int p = 0; p < this->
argc; ++p) {
655 for (
auto it = this->argv[p]; *it; ++it) {
658 remaining = n > 0 ? n : -1;
659 it[1] && --remaining;
663 if (!
argp && it == select) {
664 remaining = n > 0 ? n : -1;
671 remaining && (length = cmd.size() -
offset);
672 remaining > 0 && --remaining;
691 return show(this->showi);
Contains literal operators.
Definition: utility.hpp:147
const int argc
The number of command line arguments.
Definition: Options.hpp:251
std::string usage() const
Returns a string for usage output, created from the option definitions.
Definition: Options.hpp:586
size_t argCount(Parameter< OptionT > const &def)
Retrieves the count of arguments in an option definition.
Definition: Options.hpp:227
const char * operator[](int const i) const
Retrieve arguments to the current option.
Definition: Options.hpp:553
const char *const usageStr
A string literal for the usage() output.
Definition: Options.hpp:266
const Parameter< OptionT > opt_dash
The option definition to use for a single dash.
Definition: Options.hpp:290
Options & operator()()
Updates the internal state by parsing the next option.
Definition: Options.hpp:445
Underlined highlight(std::string const &str, ptrdiff_t const offs, ptrdiff_t const len=1)
Underline the given number of characters.
Definition: utility.cpp:12
Container for an option definition.
Definition: Options.hpp:183
const char * args
A comma separated list of arguments.
Definition: Options.hpp:208
int showi
The argument index to show if no argument is supplied to show().
Definition: Options.hpp:327
const char *const *const argv
The command line arguments.
Definition: Options.hpp:261
int offset() const
Returns the argument offset of the current parameter/argument.
Definition: Options.hpp:703
const Parameter< OptionT > & get(char const ch)
Finds the short option matching the given character.
Definition: Options.hpp:392
char sparam
The short version of this parameter.
Definition: Options.hpp:194
const Parameter< OptionT >(& defs)[DefCount]
A reference to the option definitions.
Definition: Options.hpp:271
int argi
The index of the command line argument containing the current option.
Definition: Options.hpp:305
const Parameter< OptionT > * current
Points to the current option definition.
Definition: Options.hpp:315
const char * argp
Points to the current short option character.
Definition: Options.hpp:310
static const char * removePath(char const *const file)
Returns a pointer to the file name portion of the given string.
Definition: Options.hpp:337
const Parameter< OptionT > opt_noopt
The option definition to use for non-options.
Definition: Options.hpp:283
A line of text and an underlining line.
Definition: utility.hpp:415
An instance of this class offers operators to retrieve command line options and arguments.
Definition: Options.hpp:249
const Parameter< OptionT > opt_ldash
The option definition to use for a single double-dash.
Definition: Options.hpp:297
const char * lparam
The long version of this parameter.
Definition: Options.hpp:201
OptionT option
The enum value to return for this option.
Definition: Options.hpp:187
Tests whether the given enum provides all the required definitions.
Definition: Options.hpp:160
static bool match(char const *const lstr, char const *const rstr)
Returns true if the given strings match.
Definition: Options.hpp:357
std::string show() const
Highlight the last recently accessed argument.
Definition: Options.hpp:690
utility::Underlined show(int const i, int const n=1) const
Provide a string containing the entire command line, with the indexed argument highlighted.
Definition: Options.hpp:639
const char * usage
A usage string.
Definition: Options.hpp:213
Options(int const argc, char const *const *const argv, char const *const usage, Parameter< OptionT > const (&defs)[DefCount])
Construct an options functor.
Definition: Options.hpp:429
Not invented here namespace, for code that substitutes already commonly available functionality.
Definition: Options.hpp:140
Implements generally useful functions.
static bool bmatch(char const *const str, char const *const prefix)
Returns true if the given string starts with the given prefix.
Definition: Options.hpp:375
const Parameter< OptionT > & get(char const *const str)
Finds the long option matching the given string.
Definition: Options.hpp:409
const Parameter< OptionT > opt_unknown
The option definition to use for unknown options.
Definition: Options.hpp:276