15 #include "CLI/Error.hpp" 16 #include "CLI/Macros.hpp" 17 #include "CLI/Split.hpp" 18 #include "CLI/StringTools.hpp" 19 #include "CLI/Validators.hpp" 23 using results_t = std::vector<std::string>;
24 using callback_t = std::function<bool(results_t)>;
29 using Option_p = std::unique_ptr<Option>;
31 enum class MultiOptionPolicy : char { Throw, TakeLast, TakeFirst, Join };
40 std::string
group_ = std::string(
"Options");
67 template <
typename T>
void copy_to(T *other)
const {
85 return static_cast<CRTP *
>(
this);
91 return static_cast<CRTP *
>(
this);
97 CRTP *always_capture_default(
bool value =
true) {
99 return static_cast<CRTP *
>(
this);
135 auto self =
static_cast<CRTP *
>(
this);
142 auto self =
static_cast<CRTP *
>(
this);
149 auto self =
static_cast<CRTP *
>(
this);
157 return static_cast<CRTP *
>(
this);
163 return static_cast<CRTP *
>(
this);
245 std::function<std::string()>
type_name_{[]() {
return std::string(); }};
295 std::string option_description,
296 std::function<
bool(results_t)> callback,
313 operator bool()
const {
return !
empty(); }
327 throw IncorrectConstruction::SetFlag(
get_name(
true,
true));
331 throw IncorrectConstruction::Set0Opt(
get_name());
339 throw IncorrectConstruction::ChangeNotVector(
get_name());
343 throw IncorrectConstruction::AfterMultiOpt(
get_name());
353 if(!validator_name.empty())
359 Option *
check(std::function<std::string(
const std::string &)> validator,
360 std::string validator_description =
"",
361 std::string validator_name =
"") {
362 validators_.emplace_back(validator, std::move(validator_description), std::move(validator_name));
370 if(!validator_name.empty())
377 std::string transform_description =
"",
378 std::string transform_name =
"") {
381 [func](std::string &val) {
383 return std::string{};
385 std::move(transform_description),
386 std::move(transform_name)));
394 [func](std::string &inout) {
396 return std::string{};
404 if(validator_name == validator.get_name()) {
408 if((validator_name.empty()) && (!
validators_.empty())) {
411 throw OptionNotFound(std::string(
"Validator ") + validator_name +
" Not Found");
415 auto tup =
needs_.insert(opt);
423 for(
const Option_p &opt : dynamic_cast<T *>(
parent_)->options_)
424 if(opt.get() !=
this && opt->check_name(opt_name))
425 return needs(opt.get());
426 throw IncorrectConstruction::MissingOption(opt_name);
430 template <
typename A,
typename B,
typename... ARG>
Option *
needs(A opt, B opt1, ARG... args) {
432 return needs(opt1, args...);
437 auto iterator = std::find(std::begin(
needs_), std::end(
needs_), opt);
439 if(iterator != std::end(
needs_)) {
462 for(
const Option_p &opt : dynamic_cast<T *>(
parent_)->options_)
463 if(opt.get() !=
this && opt->check_name(opt_name))
465 throw IncorrectConstruction::MissingOption(opt_name);
469 template <
typename A,
typename B,
typename... ARG>
Option *
excludes(A opt, B opt1, ARG... args) {
498 auto *parent =
dynamic_cast<T *
>(
parent_);
500 for(
const Option_p &opt : parent->options_)
501 if(opt.get() !=
this && *opt == *
this)
513 auto *parent =
dynamic_cast<T *
>(
parent_);
514 for(
const Option_p &opt : parent->options_)
515 if(opt.get() !=
this && *opt == *
this)
525 throw IncorrectConstruction::MultiOptionPolicy(
get_name());
552 CLI11_DEPRECATED(
"Use get_default_str() instead")
621 bool all_options =
false 626 std::vector<std::string> name_list;
630 name_list.push_back(
pname_);
632 for(
const std::string &sname :
snames_) {
633 name_list.push_back(
"-" + sname);
635 name_list.back() +=
"{" + get_flag_value(sname,
"") +
"}";
639 for(
const std::string &lname :
lnames_) {
640 name_list.push_back(
"--" + lname);
642 name_list.back() +=
"{" + get_flag_value(lname,
"") +
"}";
646 for(
const std::string &sname :
snames_)
647 name_list.push_back(
"-" + sname);
649 for(
const std::string &lname :
lnames_)
650 name_list.push_back(
"--" + lname);
653 return detail::join(name_list);
663 return std::string(
"--") +
lnames_[0];
667 return std::string(
"-") +
snames_[0];
686 for(std::string &result :
results_) {
687 auto err_msg = _validate(result);
706 local_result = !
callback_(partial_result);
710 local_result = !
callback_(partial_result);
713 results_t partial_result = {detail::join(
results_,
"\n")};
714 local_result = !
callback_(partial_result);
737 for(
const std::string &sname :
snames_)
740 for(
const std::string &lname :
lnames_)
746 for(
const std::string &sname : other.
snames_)
749 for(
const std::string &lname : other.
lnames_)
759 if(name.length() > 2 && name[0] ==
'-' && name[1] ==
'-')
761 else if(name.length() > 1 && name.front() ==
'-')
764 std::string local_pname =
pname_;
766 local_pname = detail::remove_underscore(local_pname);
767 name = detail::remove_underscore(name);
770 local_pname = detail::to_lower(local_pname);
771 name = detail::to_lower(name);
773 return name == local_pname;
793 std::string get_flag_value(std::string name, std::string input_value)
const {
794 static const std::string trueString{
"true"};
795 static const std::string falseString{
"false"};
796 static const std::string emptyString{
"{}"};
799 if(!((input_value.empty()) || (input_value == emptyString))) {
801 if(default_ind >= 0) {
804 throw(ArgumentMismatch::FlagOverride(name));
807 if(input_value != trueString) {
808 throw(ArgumentMismatch::FlagOverride(name));
814 if((input_value.empty()) || (input_value == emptyString)) {
822 auto val = detail::to_flag_value(input_value);
823 return (val == 1) ? falseString : (val == (-1) ? trueString : std::to_string(-val));
824 }
catch(
const std::invalid_argument &) {
834 _add_result(std::move(s));
841 results_added = _add_result(std::move(s));
849 _add_result(std::move(str));
859 template <
typename T,
860 enable_if_t<!is_vector<T>::value && !std::is_const<T>::value, detail::enabler> = detail::dummy>
866 retval = detail::lexical_cast(
results_[0], output);
869 case MultiOptionPolicy::TakeFirst:
870 retval = detail::lexical_cast(
results_.front(), output);
872 case MultiOptionPolicy::TakeLast:
874 retval = detail::lexical_cast(
results_.back(), output);
876 case MultiOptionPolicy::Throw:
878 case MultiOptionPolicy::Join:
879 retval = detail::lexical_cast(detail::join(
results_), output);
888 template <
typename T>
void results(std::vector<T> &output)
const {
893 output.emplace_back();
894 retval &= detail::lexical_cast(elem, output.back());
903 template <
typename T> T
as()
const {
933 if(option_type_size < 0)
973 std::string vtype = validator.get_description();
975 full_type_name +=
":" + vtype;
979 return full_type_name;
984 std::string _validate(std::string &result) {
988 err_msg = vali(result);
989 }
catch(
const ValidationError &err) {
990 err_msg = err.what();
998 int _add_result(std::string &&result) {
999 int result_count = 0;
1001 results_.push_back(std::move(result));
1004 if((result.find_first_of(
delimiter_) != std::string::npos)) {
1005 for(
const auto &var : CLI::detail::split(result,
delimiter_)) {
1012 results_.push_back(std::move(result));
1016 return result_count;
bool required_
True if this is a required option.
Definition: Option.hpp:43
int get_type_size() const
The number of arguments the option expects.
Definition: Option.hpp:540
bool get_ignore_underscore() const
The status of ignore_underscore.
Definition: Option.hpp:114
std::vector< std::string > results() const
Get a copy of the results.
Definition: Option.hpp:856
void results(T &output) const
get the results as a particular type
Definition: Option.hpp:861
Option * expected(int value)
Set the number of expected arguments (Flags don't use this)
Definition: Option.hpp:323
bool ignore_underscore_
Ignore underscores when matching (option, not value)
Definition: Option.hpp:49
std::string get_type_name() const
Get the full typename for this option.
Definition: Option.hpp:969
int get_items_expected() const
The total number of expected values (including the type) This is positive if exactly this number is e...
Definition: Option.hpp:589
Validator * get_validator(const std::string &validator_name="")
Get a named Validator.
Definition: Option.hpp:402
results_t results_
Results of parsing.
Definition: Option.hpp:286
Option(std::string option_name, std::string option_description, std::function< bool(results_t)> callback, App *parent)
Making an option by hand is not defined, it must be made by the App class.
Definition: Option.hpp:294
void results(std::vector< T > &output) const
get the results as a vector of a particular type
Definition: Option.hpp:888
std::string pname_
A positional name.
Definition: Option.hpp:227
CRTP * mandatory(bool value=true)
Support Plumbum term.
Definition: Option.hpp:95
OptionDefaults * disable_flag_override(bool value=true)
Disable overriding flag values with an '=' segment.
Definition: Option.hpp:194
Option * needs(std::string opt_name)
Can find a string if needed.
Definition: Option.hpp:422
Option * ignore_underscore(bool value=true)
Definition: Option.hpp:511
Option * add_result(std::vector< std::string > s)
Puts a result at the end.
Definition: Option.hpp:847
std::set< Option * > get_needs() const
The set of options needed.
Definition: Option.hpp:546
Option * transform(std::function< std::string(std::string)> func, std::string transform_description="", std::string transform_name="")
Adds a validator-like function that can change result.
Definition: Option.hpp:376
bool get_positional() const
True if the argument can be given directly.
Definition: Option.hpp:595
OptionDefaults * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times.
Definition: Option.hpp:176
bool remove_needs(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list...
Definition: Option.hpp:436
bool nonpositional() const
True if option has at least one non-positional name.
Definition: Option.hpp:598
Option * default_str(std::string val)
Set the default value string representation (does not change the contained value) ...
Definition: Option.hpp:953
App * parent_
Remember the parent app.
Definition: Option.hpp:276
void run_callback()
Process the callback.
Definition: Option.hpp:680
std::string envname_
If given, check the environment for this option.
Definition: Option.hpp:230
int get_expected() const
The number of times the option expects to be included.
Definition: Option.hpp:571
OptionDefaults * delimiter(char value='\0')
set a delimiter character to split up single arguments to treat as multiple inputs ...
Definition: Option.hpp:200
const std::vector< std::string > get_fnames() const
get the flag names with specified default values
Definition: Option.hpp:568
Option * default_function(const std::function< std::string()> &func)
Set a capture function for the default. Mostly used by App.
Definition: Option.hpp:939
const std::string & get_group() const
Get the group of this option.
Definition: Option.hpp:105
Option * needs(A opt, B opt1, ARG... args)
Any number supported, any mix of string and Opt.
Definition: Option.hpp:430
Some validators that are provided.
Definition: Validators.hpp:36
bool ignore_case_
Ignore the case when matching (option, not value)
Definition: Option.hpp:46
Option * needs(Option *opt)
Sets required options.
Definition: Option.hpp:414
Option * add_result(std::string s)
Puts a result at the end.
Definition: Option.hpp:833
std::vector< Validator > validators_
A list of validators to run on each value parsed.
Definition: Option.hpp:263
int expected_
The number of expected values, type_size_ must be < 0. Ignored for flag. N < 0 means at least -N valu...
Definition: Option.hpp:260
void clear()
Clear the parsed results (mostly for testing)
Definition: Option.hpp:316
bool check_fname(std::string name) const
Requires "--" to be removed from string.
Definition: Option.hpp:786
std::string group_
The group membership.
Definition: Option.hpp:40
Option * excludes(Option *opt)
Sets excluded options.
Definition: Option.hpp:448
bool get_always_capture_default() const
Return true if this will automatically capture the default value for help printing.
Definition: Option.hpp:126
bool check_name(std::string name) const
Check a name. Requires "-" or "--" for short / long, supports positional name.
Definition: Option.hpp:757
bool always_capture_default_
Automatically capture default value.
Definition: Option.hpp:61
const std::vector< std::string > get_lnames() const
Get the long names.
Definition: Option.hpp:562
CRTP * join()
Set the multi option policy to take last.
Definition: Option.hpp:148
std::set< Option * > get_excludes() const
The set of options excluded.
Definition: Option.hpp:549
Option * type_name_fn(std::function< std::string()> typefun)
Set the type function to run when displayed on this option.
Definition: Option.hpp:917
Option * check(std::function< std::string(const std::string &)> validator, std::string validator_description="", std::string validator_name="")
Adds a Validator. Takes a const string& and returns an error message (empty if conversion/check is ok...
Definition: Option.hpp:359
std::string description_
The description for help strings.
Definition: Option.hpp:237
bool get_disable_flag_override() const
The status of configurable.
Definition: Option.hpp:120
T as() const
return the results as a particular type
Definition: Option.hpp:903
MultiOptionPolicy multi_option_policy_
Policy for multiple arguments when expected_ == 1 (can be set on bool flags, too) ...
Definition: Option.hpp:64
callback_t callback_
Options store a callback to do all the work.
Definition: Option.hpp:279
MultiOptionPolicy get_multi_option_policy() const
The status of the multi option policy.
Definition: Option.hpp:129
bool operator==(const Option &other) const
If options share any of the same names, they are equal (not counting positional)
Definition: Option.hpp:736
std::string get_default_str() const
The default value (for help printing)
Definition: Option.hpp:556
bool disable_flag_override_
Disable overriding flag values with '=value'.
Definition: Option.hpp:55
Creates a command line program, with very few defaults.
Definition: App.hpp:59
std::vector< std::string > lnames_
A list of the long names (--a) without the leading dashes.
Definition: Option.hpp:217
bool get_required() const
True if this is a required option.
Definition: Option.hpp:108
Option * type_size(int option_type_size)
Set a custom option size.
Definition: Option.hpp:929
bool get_callback_run() const
See if the callback has been run already.
Definition: Option.hpp:910
Option * envname(std::string name)
Sets environment variable to read if no option given.
Definition: Option.hpp:487
Option * excludes(std::string opt_name)
Can find a string if needed.
Definition: Option.hpp:461
std::vector< std::string > fnames_
a list of flag names with specified default values;
Definition: Option.hpp:224
std::set< Option * > excludes_
A list of options that are excluded with this option.
Definition: Option.hpp:269
bool get_configurable() const
The status of configurable.
Definition: Option.hpp:117
Option * add_result(std::string s, int &results_added)
Puts a result at the end and get a count of the number of arguments actually added.
Definition: Option.hpp:840
size_t empty() const
True if the option was not passed.
Definition: Option.hpp:310
std::string default_str_
A human readable default value, either manually set, captured, or captured by default.
Definition: Option.hpp:240
Option * disable_flag_override(bool value=true)
disable flag overrides
Definition: Option.hpp:531
bool get_ignore_case() const
The status of ignore case.
Definition: Option.hpp:111
Option * each(std::function< void(std::string)> func)
Adds a user supplied function to run on each item passed in (communicate though lambda capture) ...
Definition: Option.hpp:392
int type_size_
Definition: Option.hpp:257
Definition: Option.hpp:169
CRTP * required(bool value=true)
Set the option as required.
Definition: Option.hpp:89
CRTP * group(std::string name)
Changes the group membership.
Definition: Option.hpp:83
Option * description(std::string option_description)
Set the description.
Definition: Option.hpp:607
const std::vector< std::string > get_snames() const
Get the short names.
Definition: Option.hpp:565
OptionDefaults * ignore_underscore(bool value=true)
Ignore underscores in the option name.
Definition: Option.hpp:188
bool callback_run_
Whether the callback has run (needed for INI parsing)
Definition: Option.hpp:289
char delimiter_
Specify a delimiter character for vector arguments.
Definition: Option.hpp:58
OptionDefaults * ignore_case(bool value=true)
Ignore the case of the option name.
Definition: Option.hpp:182
Definition: Option.hpp:35
Option * ignore_case(bool value=true)
Definition: Option.hpp:496
Thrown when an option already exists.
Definition: Error.hpp:128
Thrown when counting a non-existent option.
Definition: Error.hpp:312
bool check_sname(std::string name) const
Requires "-" to be removed from string.
Definition: Option.hpp:778
std::function< std::string()> type_name_
Definition: Option.hpp:245
Option * capture_default_str()
Capture the default value from the original value (if it can be captured)
Definition: Option.hpp:945
std::vector< std::pair< std::string, std::string > > default_flag_values_
Definition: Option.hpp:221
bool has_description() const
True if option has description.
Definition: Option.hpp:601
std::function< std::string()> default_function_
Run this function to capture a default (ignore if empty)
Definition: Option.hpp:248
bool configurable_
Allow this option to be given in a configuration file.
Definition: Option.hpp:52
std::vector< std::string > snames_
A list of the short names (-a) without the leading dashes.
Definition: Option.hpp:214
std::string get_defaultval() const
The default value (for help printing) DEPRECATED Use get_default_str() instead.
Definition: Option.hpp:553
callback_t get_callback() const
Get the callback function.
Definition: Option.hpp:559
Option * type_name(std::string typeval)
Set a custom option typestring.
Definition: Option.hpp:923
CRTP * take_last()
Set the multi option policy to take last.
Definition: Option.hpp:134
CRTP * delimiter(char value='\0')
Allow in a configuration file.
Definition: Option.hpp:161
bool check_lname(std::string name) const
Requires "--" to be removed from string.
Definition: Option.hpp:781
Option * transform(Validator validator, std::string validator_name="")
Adds a transforming validator with a built in type name.
Definition: Option.hpp:368
const std::string & get_description() const
Get the description.
Definition: Option.hpp:604
std::string get_name(bool positional=false, bool all_options=false) const
Gets a comma separated list of names. Will include / prefer the positional name if positional is true...
Definition: Option.hpp:620
Option * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times (or another policy)
Definition: Option.hpp:522
size_t count() const
Count the total number of times an option was passed.
Definition: Option.hpp:307
Definition: Option.hpp:206
Thrown when the wrong number of arguments has been received.
Definition: Error.hpp:239
Thrown when conversion call back fails, such as when an int fails to coerce to a string.
Definition: Error.hpp:182
void copy_to(T *other) const
Copy the contents to another similar class (one based on OptionBase)
Definition: Option.hpp:67
CRTP * take_first()
Set the multi option policy to take last.
Definition: Option.hpp:141
Validator & non_modifying(bool no_modify=true)
Specify whether the Validator can be modifying or not.
Definition: Validators.hpp:112
Option * default_val(std::string val)
Set the default value string representation and evaluate into the bound value.
Definition: Option.hpp:959
Option * check(Validator validator, std::string validator_name="")
Adds a Validator with a built in type name.
Definition: Option.hpp:350
char get_delimiter() const
Get the current delimeter char.
Definition: Option.hpp:123
std::set< Option * > needs_
A list of options that are required with this option.
Definition: Option.hpp:266
std::string get_envname() const
The environment variable associated to this value.
Definition: Option.hpp:543
CRTP * configurable(bool value=true)
Allow in a configuration file.
Definition: Option.hpp:155
bool remove_excludes(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list...
Definition: Option.hpp:475
Option * excludes(A opt, B opt1, ARG... args)
Any number supported, any mix of string and Opt.
Definition: Option.hpp:469
Thrown when validation of results fails.
Definition: Error.hpp:198