53 Argument(
char key,
const std::string& longkey,
const std::string& keytype,
54 const std::string& desc,
bool required)
65 virtual bool process(
int& argc,
const char*
const*& argv) = 0;
83 s +=
'-', s +=
key_, s +=
", ";
107 const std::string& keytype,
const std::string& desc,
108 bool required,
bool& dest)
109 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
114 bool process(
int& argc,
const char*
const*& argv)
final {
121 os << (
dest_ ?
"true" :
"false");
135 const std::string& keytype,
const std::string& desc,
136 bool required,
int& dest)
137 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
139 const char *
type_name() const final {
return "integer"; }
142 bool process(
int& argc,
const char*
const*& argv)
final {
146 long x = strtol(argv[0], &endptr, 10);
147 if (endptr !=
nullptr && *endptr == 0 &&
148 x <= std::numeric_limits<int>::max()) {
150 dest_ =
static_cast<int>(x);
171 const std::string& keytype,
const std::string& desc,
172 bool required,
unsigned int& dest)
173 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
175 const char *
type_name() const final {
return "unsigned"; }
178 bool process(
int& argc,
const char*
const*& argv)
final {
182 unsigned long x = strtoul(argv[0], &endptr, 10);
183 if (endptr !=
nullptr && *endptr == 0 &&
184 x <= std::numeric_limits<unsigned int>::max()) {
186 dest_ =
static_cast<unsigned int>(x);
207 const std::string& keytype,
const std::string& desc,
208 bool required,
size_t& dest)
209 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
211 const char *
type_name() const final {
return "size_t"; }
214 bool process(
int& argc,
const char*
const*& argv)
final {
218 unsigned long long x = strtoull(argv[0], &endptr, 10);
219 if (endptr !=
nullptr && *endptr == 0 &&
220 x <= std::numeric_limits<size_t>::max()) {
243 const std::string& keytype,
const std::string& desc,
244 bool required,
float& dest)
245 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
247 const char *
type_name() const final {
return "float"; }
250 bool process(
int& argc,
const char*
const*& argv)
final {
254 dest_ = strtof(argv[0], &endptr);
255 if (endptr !=
nullptr && *endptr == 0) {
276 const std::string& keytype,
const std::string& desc,
277 bool required,
double& dest)
278 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
280 const char *
type_name() const final {
return "double"; }
283 bool process(
int& argc,
const char*
const*& argv)
final {
287 dest_ = strtod(argv[0], &endptr);
288 if (endptr !=
nullptr && *endptr == 0) {
311 const std::string& keytype,
const std::string& desc,
312 bool required, std::uint32_t& dest)
313 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
315 const char *
type_name() const final {
return "bytes"; }
318 bool process(
int& argc,
const char*
const*& argv)
final {
323 static_cast<std::uint64_t
>(
324 dest_ =
static_cast<std::uint32_t
>(dest)) == dest) {
346 const std::string& keytype,
const std::string& desc,
347 bool required, std::uint64_t& dest)
348 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
350 const char *
type_name() const final {
return "bytes"; }
353 bool process(
int& argc,
const char*
const*& argv)
final {
378 const std::string& keytype,
const std::string& desc,
379 bool required, std::string& dest)
380 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) { }
382 const char *
type_name() const final {
return "string"; }
385 bool process(
int& argc,
const char*
const*& argv)
final {
394 os <<
'"' <<
dest_ <<
'"';
408 const std::string& keytype,
const std::string& desc,
409 bool required, std::vector<std::string>& dest)
410 :
Argument(key, longkey, keytype, desc, required),
dest_(dest) {
414 const char *
type_name() const final {
return "string list"; }
417 bool process(
int& argc,
const char*
const*& argv)
final {
420 dest_.emplace_back(argv[0]);
427 for (
size_t i = 0; i <
dest_.size(); ++i) {
430 os <<
'"' <<
dest_[i] <<
'"';
451 std::ostream& os,
const std::string& text,
452 size_t wraplen,
size_t indent_first,
size_t indent_rest,
size_t current,
453 size_t indent_newline) {
455 std::string::size_type t = 0;
456 size_t indent = indent_first;
458 while (t != text.size()) {
459 std::string::size_type to = t, lspace = t;
462 while (to != text.size() && to + current + indent < t + wraplen &&
470 if (to != text.size() && text[to] !=
'\n' && lspace != t)
474 os << std::string(indent,
' ') << text.substr(t, to - t) << std::endl;
477 indent = indent_rest;
480 if (to != text.size() && text[to] ==
'\n') {
481 indent = indent_newline;
518 const std::string& keytype,
bool& dest,
519 const std::string& desc) {
521 new ArgumentBool(key, longkey, keytype, desc,
false, dest));
526 const std::string& keytype,
bool& dest,
527 const std::string& desc) {
528 return add_bool(key, longkey, keytype, dest, desc);
532 const std::string& keytype,
int& dest,
533 const std::string& desc) {
535 new ArgumentInt(key, longkey, keytype, desc,
false, dest));
540 const std::string& keytype,
unsigned int& dest,
541 const std::string& desc) {
548 const std::string& keytype,
unsigned int& dest,
549 const std::string& desc) {
554 const std::string& keytype,
size_t& dest,
555 const std::string& desc) {
557 new ArgumentSizeT(key, longkey, keytype, desc,
false, dest));
562 const std::string& keytype,
float& dest,
563 const std::string& desc) {
565 new ArgumentFloat(key, longkey, keytype, desc,
false, dest));
570 const std::string& keytype,
double& dest,
571 const std::string& desc) {
578 const std::string& keytype, std::uint32_t& dest,
579 const std::string& desc) {
586 const std::string& keytype, std::uint64_t& dest,
587 const std::string& desc) {
594 const std::string& keytype, std::string& dest,
595 const std::string& desc) {
602 char key,
const std::string& longkey,
603 const std::string& keytype, std::vector<std::string>& dest,
604 const std::string& desc) {
614 char key,
const std::string& longkey,
bool& dest,
const std::string& desc) {
615 return add_bool(key, longkey,
"", dest, desc);
619 char key,
const std::string& longkey,
bool& dest,
const std::string& desc) {
620 return add_bool(key, longkey, dest, desc);
624 char key,
const std::string& longkey,
int& dest,
const std::string& desc) {
625 return add_int(key, longkey,
"", dest, desc);
629 unsigned int& dest,
const std::string& desc) {
634 unsigned int& dest,
const std::string& desc) {
639 size_t& dest,
const std::string& desc) {
640 return add_size_t(key, longkey,
"", dest, desc);
644 float& dest,
const std::string& desc) {
645 return add_float(key, longkey,
"", dest, desc);
649 double& dest,
const std::string& desc) {
650 return add_double(key, longkey,
"", dest, desc);
654 std::uint32_t& dest,
const std::string& desc) {
655 return add_bytes(key, longkey,
"", dest, desc);
659 std::uint64_t& dest,
const std::string& desc) {
660 return add_bytes(key, longkey,
"", dest, desc);
664 std::string& dest,
const std::string& desc) {
665 return add_string(key, longkey,
"", dest, desc);
669 char key,
const std::string& longkey,
670 std::vector<std::string>& dest,
const std::string& desc) {
677 const std::string& longkey,
bool& dest,
const std::string& desc) {
678 return add_bool(0, longkey,
"", dest, desc);
682 const std::string& longkey,
bool& dest,
const std::string& desc) {
683 return add_bool(0, longkey, dest, desc);
687 const std::string& longkey,
int& dest,
const std::string& desc) {
688 return add_int(0, longkey,
"", dest, desc);
692 unsigned int& dest,
const std::string& desc) {
697 unsigned int& dest,
const std::string& desc) {
702 size_t& dest,
const std::string& desc) {
703 return add_size_t(0, longkey,
"", dest, desc);
707 float& dest,
const std::string& desc) {
708 return add_float(0, longkey,
"", dest, desc);
712 double& dest,
const std::string& desc) {
713 return add_double(0, longkey,
"", dest, desc);
717 std::uint32_t& dest,
const std::string& desc) {
718 return add_bytes(0, longkey,
"", dest, desc);
722 std::uint64_t& dest,
const std::string& desc) {
723 return add_bytes(0, longkey,
"", dest, desc);
727 std::string& dest,
const std::string& desc) {
728 return add_string(0, longkey,
"", dest, desc);
732 const std::string& longkey,
733 std::vector<std::string>& dest,
const std::string& desc) {
740 const std::string& name,
int& dest,
const std::string& desc) {
746 const std::string& name,
unsigned int& dest,
const std::string& desc) {
753 const std::string& name,
unsigned int& dest,
const std::string& desc) {
758 const std::string& name,
size_t& dest,
const std::string& desc) {
764 const std::string& name,
float& dest,
const std::string& desc) {
770 const std::string& name,
double& dest,
const std::string& desc) {
776 const std::string& name, std::uint32_t& dest,
const std::string& desc) {
783 const std::string& name, std::uint64_t& dest,
const std::string& desc) {
790 const std::string& name, std::string& dest,
const std::string& desc) {
796 const std::string& name, std::vector<std::string>& dest,
797 const std::string& desc) {
806 const std::string& name,
int& dest,
const std::string& desc) {
812 const std::string& name,
unsigned int& dest,
const std::string& desc) {
819 const std::string& name,
unsigned int& dest,
const std::string& desc) {
824 const std::string& name,
size_t& dest,
const std::string& desc) {
830 const std::string& name,
float& dest,
const std::string& desc) {
836 const std::string& name,
double& dest,
const std::string& desc) {
843 const std::string& name, std::uint32_t& dest,
const std::string& desc) {
850 const std::string& name, std::uint64_t& dest,
const std::string& desc) {
857 const std::string& name, std::string& dest,
const std::string& desc) {
864 const std::string& name, std::vector<std::string>& dest,
865 const std::string& desc) {
876 return a->longkey_ < b->longkey_;
882 std::ios::fmtflags flags(os.flags());
887 for (ArgumentList::const_iterator it =
param_list_.begin();
902 os <<
"Author: " <<
author_ << std::endl;
909 os <<
"Parameters:" << std::endl;
911 for (ArgumentList::const_iterator it =
param_list_.begin();
923 os <<
"Options:" << std::endl;
925 for (ArgumentList::const_iterator it =
option_list_.begin();
944 int argc,
const char*
const* argv,
const Argument* arg, std::ostream& os) {
945 os <<
"Error: argument ";
947 os <<
'"' << argv[0] <<
'"';
950 << (argc == 0 ?
" is missing!" :
" is invalid!") << std::endl
957 int argc,
const char*
const* argv,
const Argument* arg, std::ostream& os) {
958 os <<
"Error: argument ";
960 os <<
'"' << argv[0] <<
'"';
963 << (argc == 0 ?
" is missing!" :
" is invalid!") << std::endl
970 int argc,
const char*
const* argv, std::ostream& os) {
975 for (
int i = 0; i < argc; ++i) {
976 if (strcmp(argv[i],
"-h") == 0 || strcmp(argv[i],
"--help") == 0) {
984 bool end_optlist =
false;
987 const char* arg = argv[0];
989 if (arg[0] ==
'-' && !end_optlist) {
1000 if ((arg + 2) == (*oi)->longkey_) {
1001 if (!(*oi)->process(argc, argv)) {
1006 os <<
"Option " << (*oi)->option_text()
1008 (*oi)->print_value(os);
1009 os <<
'.' << std::endl;
1015 os <<
"Error: unknown option \"" << arg <<
"\"."
1016 << std::endl << std::endl;
1025 os <<
"Invalid option \"" << arg <<
"\"." << std::endl;
1028 size_t offset = 1, arg_length = strlen(arg);
1029 int old_argc = argc;
1032 while (offset < arg_length && argc == old_argc) {
1033 ArgumentList::const_iterator oi =
option_list_.begin();
1035 if (arg[offset] == (*oi)->key_) {
1037 if (!(*oi)->process(argc, argv)) {
1043 << (*oi)->option_text()
1045 (*oi)->print_value(os);
1046 os <<
'.' << std::endl;
1052 os <<
"Error: unknown option \"";
1053 if (arg_length > 2) {
1055 os <<
"-" << arg[offset]
1056 <<
"\" at position " << offset
1057 <<
" in option sequence \"";
1059 os << arg <<
"\"." << std::endl << std::endl;
1069 if (!(*argi)->process(argc, argv)) {
1074 os <<
"Parameter " << (*argi)->param_text() <<
" set to ";
1075 (*argi)->print_value(os);
1076 os <<
'.' << std::endl;
1078 (*argi)->found_ =
true;
1079 if (!(*argi)->repeated_)
1083 os <<
"Error: unexpected extra argument "
1084 <<
"\"" << argv[0] <<
"\"." << std::endl << std::endl;
1094 for (ArgumentList::const_iterator it =
param_list_.begin();
1096 if ((*it)->required_ && !(*it)->found_) {
1097 os <<
"Error: argument for parameter " << (*it)->longkey_
1098 <<
" is required!" << std::endl;
1112 return process(argc, argv, std::cout);
1116 std::ios::fmtflags flags(os.flags());
1121 os <<
"Parameters:" << std::endl;
1123 for (ArgumentList::const_iterator it =
param_list_.begin();
1127 os <<
" " << std::setw(
static_cast<int>(maxlong))
1130 std::string typestr =
"(" + std::string(arg->
type_name()) +
")";
1140 os <<
"Options:" << std::endl;
1142 for (ArgumentList::const_iterator it =
option_list_.begin();
1146 os <<
" " << std::setw(
static_cast<int>(maxlong))
1149 std::string typestr =
"(" + std::string(arg->
type_name()) +
")";
specialization of argument for boolean flags (can only be set to true).
bool & dest_
reference to boolean to set to true
const char * type_name() const final
return formatted type name to user
ArgumentBool(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, bool &dest)
contructor filling most attributes
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
"process" argument: just set to true, no argument is used.
specialization of argument for SI/IEC suffixes byte size options or parameters
ArgumentBytes32(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, std::uint32_t &dest)
contructor filling most attributes
const char * type_name() const final
return formatted type name to user
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
parse byte size using SI/IEC parser.
specialization of argument for SI/IEC suffixes byte size options or parameters
ArgumentBytes64(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, std::uint64_t &dest)
contructor filling most attributes
const char * type_name() const final
return formatted type name to user
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
parse byte size using SI/IEC parser.
specialization of argument for double options or parameters
const char * type_name() const final
return formatted type name to user
ArgumentDouble(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, double &dest)
contructor filling most attributes
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
parse unsigned integer using sscanf.
specialization of argument for float options or parameters
const char * type_name() const final
return formatted type name to user
ArgumentFloat(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, float &dest)
contructor filling most attributes
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
parse unsigned integer using sscanf.
specialization of argument for integer options or parameters
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 * type_name() const final
return formatted type name to user
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
parse signed integer using sscanf.
specialization of argument for size_t options or parameters
ArgumentSizeT(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, size_t &dest)
contructor filling most attributes
const char * type_name() const final
return formatted type name to user
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
parse size_t using sscanf.
specialization of argument for string options or parameters
const char * type_name() const final
return formatted type name to user
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
"process" string argument just by storing it.
ArgumentString(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required, std::string &dest)
contructor filling most attributes
specialization of argument for multiple string options or parameters
const char * type_name() const final
return formatted type name to user
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
std::vector< std::string > & dest_
void print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
"process" string argument just by storing it in vector.
specialization of argument for unsigned integer options or parameters
const char * type_name() const final
return formatted type name to user
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 print_value(std::ostream &os) const final
format value to ostream
bool process(int &argc, const char *const *&argv) final
parse unsigned integer using sscanf.
base class of all options and parameters
std::string keytype_
option type description, e.g. "<#>" to indicate numbers
bool required_
required, process() fails if the option/parameter is not found.
virtual void print_value(std::ostream &os) const =0
format value to ostream
bool found_
found during processing of command line
std::string param_text() const
return 'longkey [keytype]'
virtual const char * type_name() const =0
return formatted type name to user
virtual bool process(int &argc, const char *const *&argv)=0
process one item from command line for this argument
virtual ~Argument()=default
empty virtual destructor
std::string desc_
longer description, which will be wrapped
bool repeated_
repeated argument, i.e. std::vector<std::string>
std::string option_text() const
return '-s, –longkey [keytype]'
Argument(char key, const std::string &longkey, const std::string &keytype, const std::string &desc, bool required)
contructor filling most attributes
std::string longkey_
long option key or name for parameters
char key_
single letter short option, or 0 is none
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.
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.
void print_param_error(int argc, const char *const *argv, const Argument *arg, std::ostream &os)
print error about parameter.
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, std::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)
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.
const char * program_name_
argv[0] for usage.
CmdlineParser()
Constructor.
void add_opt_param_bytes(const std::string &name, std::uint32_t &dest, const std::string &desc)
add optional SI/IEC suffixes byte size parameter [name] with description and store to dest
void set_verbose_process(bool verbose_process)
Set verbose processing of command line arguments.
unsigned int line_wrap_
set line wrap length
void add_bytes(char key, const std::string &longkey, std::uint32_t &dest, const std::string &desc)
add SI/IEC suffixes byte size option -key, –longkey and store to 32-bit dest
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
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
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
bool verbose_process_
verbose processing of arguments
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.
~CmdlineParser()
Delete all added arguments.
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
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
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
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
void add_param_float(const std::string &name, float &dest, const std::string &desc)
add float parameter [name] with description and store to dest
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 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 <#>'
void calc_option_max(const Argument *arg)
update maximum formatting width for new option
bool process(int argc, const char *const *argv, std::ostream &os)
parse command line options as specified by the options and parameters added.
#define TLX_VISIBILITY_HIDDEN
bool parse_si_iec_units(const char *str, std::uint64_t *out_size, char default_unit)
Parse a string like "343KB" or "44 GiB" into the corresponding size in bytes.