48 bool repeated_ =
false;
52 Argument(
char key,
const std::string& longkey,
const std::string& keytype,
53 const std::string& desc,
bool required)
54 : key_(key), longkey_(longkey), keytype_(keytype), desc_(desc),
55 required_(required) { }
64 virtual bool process(
int& argc,
const char*
const*& argv) = 0;
71 std::string s = longkey_;
72 if (!keytype_.empty()) {
82 s +=
'-', s += key_, s +=
", ";
87 s +=
"--", s += longkey_;
88 if (!keytype_.empty()) {
106 const std::string& keytype,
const std::string& desc,
107 bool required,
bool& dest)
108 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
113 bool process(
int& argc,
const char*
const*& argv)
final {
120 os << (dest_ ?
"true" :
"false");
134 const std::string& keytype,
const std::string& desc,
135 bool required,
int& dest)
136 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
138 const char *
type_name() const final {
return "integer"; }
141 bool process(
int& argc,
const char*
const*& argv)
final {
145 long x = strtol(argv[0], &endptr, 10);
146 if (endptr !=
nullptr && *endptr == 0 &&
147 x <= std::numeric_limits<int>::max()) {
149 dest_ =
static_cast<int>(x);
170 const std::string& keytype,
const std::string& desc,
171 bool required,
unsigned int& dest)
172 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
174 const char *
type_name() const final {
return "unsigned"; }
177 bool process(
int& argc,
const char*
const*& argv)
final {
181 unsigned long x = strtoul(argv[0], &endptr, 10);
182 if (endptr !=
nullptr && *endptr == 0 &&
183 x <= std::numeric_limits<unsigned int>::max()) {
185 dest_ =
static_cast<unsigned int>(x);
206 const std::string& keytype,
const std::string& desc,
207 bool required,
size_t& dest)
208 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
210 const char *
type_name() const final {
return "size_t"; }
213 bool process(
int& argc,
const char*
const*& argv)
final {
217 unsigned long long x = strtoull(argv[0], &endptr, 10);
218 if (endptr !=
nullptr && *endptr == 0 &&
219 x <= std::numeric_limits<size_t>::max()) {
242 const std::string& keytype,
const std::string& desc,
243 bool required,
float& dest)
244 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
246 const char *
type_name() const final {
return "float"; }
249 bool process(
int& argc,
const char*
const*& argv)
final {
253 dest_ = strtof(argv[0], &endptr);
254 if (endptr !=
nullptr && *endptr == 0) {
275 const std::string& keytype,
const std::string& desc,
276 bool required,
double& dest)
277 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
279 const char *
type_name() const final {
return "double"; }
282 bool process(
int& argc,
const char*
const*& argv)
final {
286 dest_ = strtod(argv[0], &endptr);
287 if (endptr !=
nullptr && *endptr == 0) {
310 const std::string& keytype,
const std::string& desc,
311 bool required, uint32_t& dest)
312 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
314 const char *
type_name() const final {
return "bytes"; }
317 bool process(
int& argc,
const char*
const*& argv)
final {
322 static_cast<uint64_t
>(
323 dest_ =
static_cast<uint32_t
>(dest)) == dest) {
345 const std::string& keytype,
const std::string& desc,
346 bool required, uint64_t& dest)
347 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
349 const char *
type_name() const final {
return "bytes"; }
352 bool process(
int& argc,
const char*
const*& argv)
final {
377 const std::string& keytype,
const std::string& desc,
378 bool required, std::string& dest)
379 : Argument(key, longkey, keytype, desc, required), dest_(dest) { }
381 const char *
type_name() const final {
return "string"; }
384 bool process(
int& argc,
const char*
const*& argv)
final {
393 os <<
'"' << dest_ <<
'"';
407 const std::string& keytype,
const std::string& desc,
408 bool required, std::vector<std::string>& dest)
409 : Argument(key, longkey, keytype, desc, required), dest_(dest) {
413 const char *
type_name() const final {
return "string list"; }
416 bool process(
int& argc,
const char*
const*& argv)
final {
419 dest_.emplace_back(argv[0]);
426 for (
size_t i = 0; i < dest_.size(); ++i) {
429 os <<
'"' << dest_[i] <<
'"';
450 std::ostream& os,
const std::string& text,
451 size_t wraplen,
size_t indent_first,
size_t indent_rest,
size_t current,
452 size_t indent_newline) {
454 std::string::size_type t = 0;
455 size_t indent = indent_first;
457 while (t != text.size()) {
458 std::string::size_type to = t, lspace = t;
461 while (to != text.size() && to + current + indent < t + wraplen &&
469 if (to != text.size() && text[to] !=
'\n' && lspace != t)
473 os << std::string(indent,
' ') << text.substr(t, to - t) << std::endl;
476 indent = indent_rest;
479 if (to != text.size() && text[to] ==
'\n') {
480 indent = indent_newline;
517 const std::string& keytype,
bool& dest,
518 const std::string& desc) {
520 new ArgumentBool(key, longkey, keytype, desc,
false, dest));
525 const std::string& keytype,
bool& dest,
526 const std::string& desc) {
527 return add_bool(key, longkey, keytype, dest, desc);
531 const std::string& keytype,
int& dest,
532 const std::string& desc) {
534 new ArgumentInt(key, longkey, keytype, desc,
false, dest));
539 const std::string& keytype,
unsigned int& dest,
540 const std::string& desc) {
547 const std::string& keytype,
unsigned int& dest,
548 const std::string& desc) {
553 const std::string& keytype,
size_t& dest,
554 const std::string& desc) {
556 new ArgumentSizeT(key, longkey, keytype, desc,
false, dest));
561 const std::string& keytype,
float& dest,
562 const std::string& desc) {
564 new ArgumentFloat(key, longkey, keytype, desc,
false, dest));
569 const std::string& keytype,
double& dest,
570 const std::string& desc) {
577 const std::string& keytype, uint32_t& dest,
578 const std::string& desc) {
585 const std::string& keytype, uint64_t& dest,
586 const std::string& desc) {
593 const std::string& keytype, std::string& dest,
594 const std::string& desc) {
601 char key,
const std::string& longkey,
602 const std::string& keytype, std::vector<std::string>& dest,
603 const std::string& desc) {
613 char key,
const std::string& longkey,
bool& dest,
const std::string& desc) {
614 return add_bool(key, longkey,
"", dest, desc);
618 char key,
const std::string& longkey,
bool& dest,
const std::string& desc) {
619 return add_bool(key, longkey, dest, desc);
623 char key,
const std::string& longkey,
int& dest,
const std::string& desc) {
624 return add_int(key, longkey,
"", dest, desc);
628 unsigned int& dest,
const std::string& desc) {
633 unsigned int& dest,
const std::string& desc) {
638 size_t& dest,
const std::string& desc) {
639 return add_size_t(key, longkey,
"", dest, desc);
643 float& dest,
const std::string& desc) {
644 return add_float(key, longkey,
"", dest, desc);
648 double& dest,
const std::string& desc) {
649 return add_double(key, longkey,
"", dest, desc);
653 uint32_t& dest,
const std::string& desc) {
654 return add_bytes(key, longkey,
"", dest, desc);
658 uint64_t& dest,
const std::string& desc) {
659 return add_bytes(key, longkey,
"", dest, desc);
663 std::string& dest,
const std::string& desc) {
664 return add_string(key, longkey,
"", dest, desc);
668 char key,
const std::string& longkey,
669 std::vector<std::string>& dest,
const std::string& desc) {
676 const std::string& longkey,
bool& dest,
const std::string& desc) {
677 return add_bool(0, longkey,
"", dest, desc);
681 const std::string& longkey,
bool& dest,
const std::string& desc) {
682 return add_bool(0, longkey, dest, desc);
686 const std::string& longkey,
int& dest,
const std::string& desc) {
687 return add_int(0, longkey,
"", dest, desc);
691 unsigned int& dest,
const std::string& desc) {
696 unsigned int& dest,
const std::string& desc) {
701 size_t& dest,
const std::string& desc) {
702 return add_size_t(0, longkey,
"", dest, desc);
706 float& dest,
const std::string& desc) {
707 return add_float(0, longkey,
"", dest, desc);
711 double& dest,
const std::string& desc) {
712 return add_double(0, longkey,
"", dest, desc);
716 uint32_t& dest,
const std::string& desc) {
717 return add_bytes(0, longkey,
"", dest, desc);
721 uint64_t& dest,
const std::string& desc) {
722 return add_bytes(0, longkey,
"", dest, desc);
726 std::string& dest,
const std::string& desc) {
727 return add_string(0, longkey,
"", dest, desc);
731 const std::string& longkey,
732 std::vector<std::string>& dest,
const std::string& desc) {
739 const std::string& name,
int& dest,
const std::string& desc) {
745 const std::string& name,
unsigned int& dest,
const std::string& desc) {
752 const std::string& name,
unsigned int& dest,
const std::string& desc) {
757 const std::string& name,
size_t& dest,
const std::string& desc) {
763 const std::string& name,
float& dest,
const std::string& desc) {
769 const std::string& name,
double& dest,
const std::string& desc) {
775 const std::string& name, uint32_t& dest,
const std::string& desc) {
782 const std::string& name, uint64_t& dest,
const std::string& desc) {
789 const std::string& name, std::string& dest,
const std::string& desc) {
795 const std::string& name, std::vector<std::string>& dest,
796 const std::string& desc) {
805 const std::string& name,
int& dest,
const std::string& desc) {
811 const std::string& name,
unsigned int& dest,
const std::string& desc) {
818 const std::string& name,
unsigned int& dest,
const std::string& desc) {
823 const std::string& name,
size_t& dest,
const std::string& desc) {
829 const std::string& name,
float& dest,
const std::string& desc) {
835 const std::string& name,
double& dest,
const std::string& desc) {
842 const std::string& name, uint32_t& dest,
const std::string& desc) {
849 const std::string& name, uint64_t& dest,
const std::string& desc) {
856 const std::string& name, std::string& dest,
const std::string& desc) {
863 const std::string& name, std::vector<std::string>& dest,
864 const std::string& desc) {
875 return a->longkey_ < b->longkey_;
881 std::ios::fmtflags flags(os.flags());
886 for (ArgumentList::const_iterator it =
param_list_.begin();
890 os << (arg->required_ ?
" <" :
" [") << arg->longkey_
891 << (arg->repeated_ ?
" ..." :
"") << (arg->required_ ?
'>' :
']');
901 os <<
"Author: " <<
author_ << std::endl;
908 os <<
"Parameters:" << std::endl;
910 for (ArgumentList::const_iterator it =
param_list_.begin();
915 << std::left << arg->param_text();
922 os <<
"Options:" << std::endl;
924 for (ArgumentList::const_iterator it =
option_list_.begin();
929 << std::left << arg->option_text();
943 int argc,
const char*
const* argv,
const Argument* arg, std::ostream& os) {
944 os <<
"Error: argument ";
946 os <<
'"' << argv[0] <<
'"';
948 os <<
" for " << arg->type_name() <<
" option " << arg->option_text()
949 << (argc == 0 ?
" is missing!" :
" is invalid!") << std::endl
956 int argc,
const char*
const* argv,
const Argument* arg, std::ostream& os) {
957 os <<
"Error: argument ";
959 os <<
'"' << argv[0] <<
'"';
961 os <<
" for " << arg->type_name() <<
" parameter " << arg->param_text()
962 << (argc == 0 ?
" is missing!" :
" is invalid!") << std::endl
969 int argc,
const char*
const* argv, std::ostream& os) {
974 for (
int i = 0; i < argc; ++i) {
975 if (strcmp(argv[i],
"-h") == 0 || strcmp(argv[i],
"--help") == 0) {
983 bool end_optlist =
false;
986 const char* arg = argv[0];
988 if (arg[0] ==
'-' && !end_optlist) {
999 if ((arg + 2) == (*oi)->longkey_) {
1000 if (!(*oi)->process(argc, argv)) {
1005 os <<
"Option " << (*oi)->option_text()
1007 (*oi)->print_value(os);
1008 os <<
'.' << std::endl;
1014 os <<
"Error: unknown option \"" << arg <<
"\"."
1015 << std::endl << std::endl;
1024 os <<
"Invalid option \"" << arg <<
"\"." << std::endl;
1027 size_t offset = 1, arg_length = strlen(arg);
1028 int old_argc = argc;
1031 while (offset < arg_length && argc == old_argc) {
1032 ArgumentList::const_iterator oi =
option_list_.begin();
1034 if (arg[offset] == (*oi)->key_) {
1036 if (!(*oi)->process(argc, argv)) {
1042 << (*oi)->option_text()
1044 (*oi)->print_value(os);
1045 os <<
'.' << std::endl;
1051 os <<
"Error: unknown option \"";
1052 if (arg_length > 2) {
1054 os <<
"-" << arg[offset]
1055 <<
"\" at position " << offset
1056 <<
" in option sequence \"";
1058 os << arg <<
"\"." << std::endl << std::endl;
1068 if (!(*argi)->process(argc, argv)) {
1073 os <<
"Parameter " << (*argi)->param_text() <<
" set to ";
1074 (*argi)->print_value(os);
1075 os <<
'.' << std::endl;
1077 (*argi)->found_ =
true;
1078 if (!(*argi)->repeated_)
1082 os <<
"Error: unexpected extra argument "
1083 <<
"\"" << argv[0] <<
"\"." << std::endl << std::endl;
1093 for (ArgumentList::const_iterator it =
param_list_.begin();
1095 if ((*it)->required_ && !(*it)->found_) {
1096 os <<
"Error: argument for parameter " << (*it)->longkey_
1097 <<
" is required!" << std::endl;
1111 return process(argc, argv, std::cout);
1115 std::ios::fmtflags flags(os.flags());
1120 os <<
"Parameters:" << std::endl;
1122 for (ArgumentList::const_iterator it =
param_list_.begin();
1126 os <<
" " << std::setw(
static_cast<int>(maxlong))
1127 << std::left << arg->param_text();
1129 std::string typestr =
"(" + std::string(arg->type_name()) +
")";
1132 arg->print_value(os);
1139 os <<
"Options:" << std::endl;
1141 for (ArgumentList::const_iterator it =
option_list_.begin();
1145 os <<
" " << std::setw(
static_cast<int>(maxlong))
1146 << std::left << arg->option_text();
1148 std::string typestr =
"(" + std::string(arg->type_name()) +
")";
1151 arg->print_value(os);
base class of all options and parameters
ArgumentBytes32(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, uint32_t &dest)
contructor filling most attributes
void add_flag(char key, const std::string &longkey, bool &dest, const std::string &desc)
add boolean option flag -key, –longkey with description and store to dest.
std::string keytype_
option type description, e.g. "<#>" to indicate numbers
void add_opt_param_uint(const std::string &name, unsigned int &dest, const std::string &desc)
add optional unsigned integer parameter [name] with description and store to dest.
bool required_
required, process() fails if the option/parameter is not found.
ArgumentSizeT(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, size_t &dest)
contructor filling most attributes
void print_param_error(int argc, const char *const *argv, const Argument *arg, std::ostream &os)
print error about parameter.
virtual void print_value(std::ostream &os) const =0
format value to ostream
void add_size_t(char key, const std::string &longkey, size_t &dest, const std::string &desc)
add size_t option -key, –longkey with description and store to dest
void add_param_bytes(const std::string &name, uint32_t &dest, const std::string &desc)
add SI/IEC suffixes byte size parameter [name] with description and store to dest
ArgumentList option_list_
list of options available
void set_author(const std::string &author)
Set author of program, will be wrapped.
void add_param_stringlist(const std::string &name, std::vector< std::string > &dest, const std::string &desc)
add string list parameter [name] with description and store to dest.
size_t option_max_width_
formatting width for options, '-s, –switch <#>'
void add_bool(char key, const std::string &longkey, bool &dest, const std::string &desc)
add boolean option flag -key, –longkey with description and store to dest
CmdlineParser & sort()
sort options by key (but not the positional parameters)
std::string param_text() const
return 'longkey [keytype]'
void add_opt_param_int(const std::string &name, int &dest, const std::string &desc)
add optional signed integer parameter [name] with description and store to dest
void add_param_size_t(const std::string &name, size_t &dest, const std::string &desc)
add size_t parameter [name] with description and store to dest
void add_param_uint(const std::string &name, unsigned int &dest, const std::string &desc)
add unsigned integer parameter [name] with description and store to dest.
ArgumentInt(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, int &dest)
contructor filling most attributes
const char * program_name_
argv[0] for usage.
CmdlineParser()
Constructor.
void set_verbose_process(bool verbose_process)
Set verbose processing of command line arguments.
void add_opt_param_bytes(const std::string &name, uint32_t &dest, const std::string &desc)
add optional SI/IEC suffixes byte size parameter [name] with description and store to dest
virtual bool process(int &argc, const char *const *&argv)=0
process one item from command line for this argument
unsigned int line_wrap_
set line wrap length
void add_double(char key, const std::string &longkey, double &dest, const std::string &desc)
add double option -key, –longkey with description and store to dest
virtual ~Argument()=default
empty virtual destructor
void add_opt_param_float(const std::string &name, float &dest, const std::string &desc)
add optional float parameter [name] with description and store to dest
virtual const char * type_name() const =0
return formatted type name to user
static void output_wrap(std::ostream &os, const std::string &text, size_t wraplen, size_t indent_first=0, size_t indent_rest=0, size_t current=0, size_t indent_newline=0)
Wrap a long string at spaces into lines.
void print_result()
print nicely formatted result of processing to std::cout
std::string desc_
longer description, which will be wrapped
bool & dest_
reference to boolean to set to true
bool verbose_process_
verbose processing of arguments
ArgumentBytes64(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, uint64_t &dest)
contructor filling most attributes
ArgumentDouble(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, double &dest)
contructor filling most attributes
void add_opt_param_size_t(const std::string &name, size_t &dest, const std::string &desc)
add optional size_t parameter [name] with description and store to dest
ArgumentList param_list_
list of parameters, both required and optional
void calc_param_max(const Argument *arg)
update maximum formatting width for new parameter
void add_opt_param_double(const std::string &name, double &dest, const std::string &desc)
add optional double parameter [name] with description and store to dest
void add_param_double(const std::string &name, double &dest, const std::string &desc)
add double parameter [name] with description and store to dest
std::string author_
user set author of program, will be wrapped
void set_description(const std::string &description)
Set description of program, text will be wrapped.
ArgumentBool(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, bool &dest)
contructor filling most attributes
void add_bytes(char key, const std::string &longkey, uint32_t &dest, const std::string &desc)
add SI/IEC suffixes byte size option -key, –longkey and store to 32-bit dest
~CmdlineParser()
Delete all added arguments.
ArgumentUnsigned(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, unsigned int &dest)
contructor filling most attributes
void add_param_unsigned(const std::string &name, unsigned int &dest, const std::string &desc)
add unsigned integer parameter [name] with description and store to dest
const char * type_name() const final
void add_int(char key, const std::string &longkey, int &dest, const std::string &desc)
add signed integer option -key, –longkey with description and store to dest
std::string option_text() const
return '-s, –longkey [keytype]'
void add_param_string(const std::string &name, std::string &dest, const std::string &desc)
add string parameter [name] with description and store to dest
void add_opt_param_unsigned(const std::string &name, unsigned int &dest, const std::string &desc)
add optional unsigned integer parameter [name] with description and store to dest
void add_param_int(const std::string &name, int &dest, const std::string &desc)
add signed integer parameter [name] with description and store to dest
void add_opt_param_string(const std::string &name, std::string &dest, const std::string &desc)
add optional string parameter [name] with description and store to dest
void add_unsigned(char key, const std::string &longkey, unsigned int &dest, const std::string &desc)
add unsigned integer option -key, –longkey with description and store to dest
ArgumentStringlist(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, std::vector< std::string > &dest)
contructor filling most attributes
void print_option_error(int argc, const char *const *argv, const Argument *arg, std::ostream &os)
print error about option.
void add_string(char key, const std::string &longkey, std::string &dest, const std::string &desc)
add string option -key, –longkey and store to dest
void add_float(char key, const std::string &longkey, float &dest, const std::string &desc)
add float option -key, –longkey with description and store to dest
Argument(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required)
contructor filling most attributes
std::vector< std::string > & dest_
void add_param_float(const std::string &name, float &dest, const std::string &desc)
add float parameter [name] with description and store to dest
ArgumentFloat(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, float &dest)
contructor filling most attributes
void add_opt_param_stringlist(const std::string &name, std::vector< std::string > &dest, const std::string &desc)
add optional string parameter [name] with description and store to dest
void add_stringlist(char key, const std::string &longkey, std::vector< std::string > &dest, const std::string &desc)
add string list option -key, –longkey and store to dest
static constexpr int max_type_name_
maximum length of a type_name() result
void print_usage()
output to std::cout nicely formatted usage information including description of all parameters and op...
std::string description_
user set description of program, will be wrapped
void print_value(std::ostream &os) const final
bool process(int &argc, const char *const *&argv) final
"process" argument: just set to true, no argument is used.
void add_uint(char key, const std::string &longkey, unsigned int &dest, const std::string &desc)
add unsigned integer option -key, –longkey with description and store to dest.
size_t param_max_width_
formatting width for parameters, 'param <#>'
ArgumentString(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, std::string &dest)
contructor filling most attributes
void calc_option_max(const Argument *arg)
update maximum formatting width for new option
std::string longkey_
long option key or name for parameters
char key_
single letter short option, or 0 is none
#define TLX_VISIBILITY_HIDDEN
bool parse_si_iec_units(const char *str, uint64_t *out_size, char default_unit)
Parse a string like "343KB" or "44 GiB" into the corresponding size in bytes.
static void sort(Iterator begin, Iterator end, Comparator cmp=Comparator())
Call best known sorting network for up to sixteen elements with given comparison method.