1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-05-03 14:03:52 +00:00

Updated names in Option, too

This commit is contained in:
Henry Fredrick Schreiner 2017-02-24 15:15:48 -05:00
parent c02130b7db
commit a8f5b32830
2 changed files with 121 additions and 121 deletions

View File

@ -109,7 +109,7 @@ protected:
/// Pointer to the config option /// Pointer to the config option
Option* config_ptr_ {nullptr}; Option* config_ptr_ {nullptr};
yy///@} ///@}
public: public:
@ -218,14 +218,14 @@ public:
return detail::lexical_cast(res[0][0], variable); return detail::lexical_cast(res[0][0], variable);
}; };
Option* retval = add_option(name, fun, description, defaulted); Option* opt = add_option(name, fun, description, defaulted);
retval->typeval = detail::type_name<T>(); opt->typeval_ = detail::type_name<T>();
if(defaulted) { if(defaulted) {
std::stringstream out; std::stringstream out;
out << variable; out << variable;
retval->defaultval = out.str(); opt->defaultval_ = out.str();
} }
return retval; return opt;
} }
/// Add option for vectors /// Add option for vectors
@ -248,13 +248,13 @@ public:
return variable.size() > 0 && retval; return variable.size() > 0 && retval;
}; };
Option* retval = add_option(name, fun, description, defaulted); Option* opt = add_option(name, fun, description, defaulted);
retval->allow_vector = true; opt->allow_vector_ = true;
retval->_expected = -1; opt->expected_ = -1;
retval->typeval = detail::type_name<T>(); opt->typeval_ = detail::type_name<T>();
if(defaulted) if(defaulted)
retval->defaultval = "[" + detail::join(variable) + "]"; opt->defaultval_ = "[" + detail::join(variable) + "]";
return retval; return opt;
} }
/// Add option for flag /// Add option for flag
@ -269,7 +269,7 @@ public:
Option* opt = add_option(name, fun, description, false); Option* opt = add_option(name, fun, description, false);
if(opt->get_positional()) if(opt->get_positional())
throw IncorrectConstruction("Flags cannot be positional"); throw IncorrectConstruction("Flags cannot be positional");
opt->_expected = 0; opt->expected_ = 0;
return opt; return opt;
} }
@ -291,7 +291,7 @@ public:
Option* opt = add_option(name, fun, description, false); Option* opt = add_option(name, fun, description, false);
if(opt->get_positional()) if(opt->get_positional())
throw IncorrectConstruction("Flags cannot be positional"); throw IncorrectConstruction("Flags cannot be positional");
opt->_expected = 0; opt->expected_ = 0;
return opt; return opt;
} }
@ -313,7 +313,7 @@ public:
Option* opt = add_option(name, fun, description, false); Option* opt = add_option(name, fun, description, false);
if(opt->get_positional()) if(opt->get_positional())
throw IncorrectConstruction("Flags cannot be positional"); throw IncorrectConstruction("Flags cannot be positional");
opt->_expected = 0; opt->expected_ = 0;
return opt; return opt;
} }
@ -323,12 +323,12 @@ public:
Option* add_set( Option* add_set(
std::string name, std::string name,
T &member, ///< The selected member of the set T &member, ///< The selected member of the set
std::set<T> _options, ///< The set of posibilities std::set<T> options, ///< The set of posibilities
std::string description="", std::string description="",
bool defaulted=false bool defaulted=false
) { ) {
CLI::callback_t fun = [&member, _options](CLI::results_t res){ CLI::callback_t fun = [&member, options](CLI::results_t res){
if(res.size()!=1) { if(res.size()!=1) {
return false; return false;
} }
@ -338,30 +338,30 @@ public:
bool retval = detail::lexical_cast(res[0][0], member); bool retval = detail::lexical_cast(res[0][0], member);
if(!retval) if(!retval)
return false; return false;
return std::find(std::begin(_options), std::end(_options), member) != std::end(_options); return std::find(std::begin(options), std::end(options), member) != std::end(options);
}; };
Option* retval = add_option(name, fun, description, defaulted); Option* opt = add_option(name, fun, description, defaulted);
retval->typeval = detail::type_name<T>(); opt->typeval_ = detail::type_name<T>();
retval->typeval += " in {" + detail::join(_options) + "}"; opt->typeval_ += " in {" + detail::join(options) + "}";
if(defaulted) { if(defaulted) {
std::stringstream out; std::stringstream out;
out << member; out << member;
retval->defaultval = out.str(); opt->defaultval_ = out.str();
} }
return retval; return opt;
} }
/// Add set of options, string only, ignore case /// Add set of options, string only, ignore case
Option* add_set_ignore_case( Option* add_set_ignore_case(
std::string name, std::string name,
std::string &member, ///< The selected member of the set std::string &member, ///< The selected member of the set
std::set<std::string> _options, ///< The set of posibilities std::set<std::string> options, ///< The set of posibilities
std::string description="", std::string description="",
bool defaulted=false bool defaulted=false
) { ) {
CLI::callback_t fun = [&member, _options](CLI::results_t res){ CLI::callback_t fun = [&member, options](CLI::results_t res){
if(res.size()!=1) { if(res.size()!=1) {
return false; return false;
} }
@ -369,9 +369,9 @@ public:
return false; return false;
} }
member = detail::to_lower(res.at(0).at(0)); member = detail::to_lower(res.at(0).at(0));
auto iter = std::find_if(std::begin(_options), std::end(_options), auto iter = std::find_if(std::begin(options), std::end(options),
[&member](std::string val){return detail::to_lower(val) == member;}); [&member](std::string val){return detail::to_lower(val) == member;});
if(iter == std::end(_options)) if(iter == std::end(options))
return false; return false;
else { else {
member = *iter; member = *iter;
@ -379,13 +379,13 @@ public:
} }
}; };
Option* retval = add_option(name, fun, description, defaulted); Option* opt = add_option(name, fun, description, defaulted);
retval->typeval = detail::type_name<std::string>(); opt->typeval_ = detail::type_name<std::string>();
retval->typeval += " in {" + detail::join(_options) + "}"; opt->typeval_ += " in {" + detail::join(options) + "}";
if(defaulted) { if(defaulted) {
retval->defaultval = detail::to_lower(member); opt->defaultval_ = detail::to_lower(member);
} }
return retval; return opt;
} }
@ -535,8 +535,8 @@ public:
std::string config_to_str() const { std::string config_to_str() const {
std::stringstream out; std::stringstream out;
for(const Option_p &opt : options_) { for(const Option_p &opt : options_) {
if(opt->lnames.size() > 0 && opt->count() > 0 && opt->get_expected() > 0) if(opt->lnames_.size() > 0 && opt->count() > 0 && opt->get_expected() > 0)
out << opt->lnames[0] << "=" << detail::join(opt->flatten_results()) << std::endl; out << opt->lnames_[0] << "=" << detail::join(opt->flatten_results()) << std::endl;
} }
return out.str(); return out.str();
} }
@ -781,8 +781,8 @@ protected:
// Get envname options if not yet passed // Get envname options if not yet passed
for(const Option_p& opt : options_) { for(const Option_p& opt : options_) {
if (opt->count() == 0 && opt->_envname != "") { if (opt->count() == 0 && opt->envname_ != "") {
char *ename = std::getenv(opt->_envname.c_str()); char *ename = std::getenv(opt->envname_.c_str());
if(ename != nullptr) { if(ename != nullptr) {
opt->get_new(); opt->get_new();
opt->add_result(0, std::string(ename)); opt->add_result(0, std::string(ename));
@ -804,11 +804,11 @@ protected:
&& (opt->count() < opt->get_expected() || opt->count() == 0)) && (opt->count() < opt->get_expected() || opt->count() == 0))
throw RequiredError(opt->get_name()); throw RequiredError(opt->get_name());
// Requires // Requires
for (const Option* opt_req : opt->_requires) for (const Option* opt_req : opt->requires_)
if (opt->count() > 0 && opt_req->count() == 0) if (opt->count() > 0 && opt_req->count() == 0)
throw RequiresError(opt->get_name(), opt_req->get_name()); throw RequiresError(opt->get_name(), opt_req->get_name());
// Excludes // Excludes
for (const Option* opt_ex : opt->_excludes) for (const Option* opt_ex : opt->excludes_)
if (opt->count() > 0 && opt_ex->count() != 0) if (opt->count() > 0 && opt_ex->count() != 0)
throw ExcludesError(opt->get_name(), opt_ex->get_name()); throw ExcludesError(opt->get_name(), opt_ex->get_name());
} }

View File

@ -32,71 +32,71 @@ protected:
/// @name Names /// @name Names
///@{ ///@{
/// A list of the short names (-a) without the leading dashes /// A list of the short names (`-a`) without the leading dashes
std::vector<std::string> snames; std::vector<std::string> snames_;
/// A list of the long names (--a) without the leading dashes /// A list of the long names (`--a`) without the leading dashes
std::vector<std::string> lnames; std::vector<std::string> lnames_;
/// A positional name /// A positional name
std::string pname; std::string pname_;
/// If given, check the environment for this option /// If given, check the environment for this option
std::string _envname; std::string envname_;
///@} ///@}
/// @name Help /// @name Help
///@{ ///@{
/// The description for help strings /// The description for help strings
std::string description; std::string description_;
/// A human readable default value, usually only set if default is true in creation /// A human readable default value, usually only set if default is true in creation
std::string defaultval; std::string defaultval_;
/// A human readable type value, set when App creates this /// A human readable type value, set when App creates this
std::string typeval; std::string typeval_;
/// The group membership /// The group membership
std::string _group {"Options"}; std::string group_ {"Options"};
/// True if this option has a default /// True if this option has a default
bool _default {false}; bool default_ {false};
///@} ///@}
/// @name Configuration /// @name Configuration
///@{ ///@{
/// True if this is a required option /// True if this is a required option
bool _required {false}; bool required_ {false};
/// The number of expected values, 0 for flag, -1 for unlimited vector /// The number of expected values, 0 for flag, -1 for unlimited vector
int _expected {1}; int expected_ {1};
/// A private setting to allow non-vector args to not be able to accept incorrect _expected values /// A private setting to allow non-vector args to not be able to accept incorrect expected values
bool allow_vector {false}; bool allow_vector_ {false};
/// Ignore the case when matching (option, not value) /// Ignore the case when matching (option, not value)
bool case_insensitive {false}; bool ignore_case_ {false};
/// A list of validators to run on each value parsed /// A list of validators to run on each value parsed
std::vector<std::function<bool(std::string)>> _validators; std::vector<std::function<bool(std::string)>> validators_;
/// A list of options that are required with this option /// A list of options that are required with this option
std::set<Option*> _requires; std::set<Option*> requires_;
/// A list of options that are excluded with this option /// A list of options that are excluded with this option
std::set<Option*> _excludes; std::set<Option*> excludes_;
///@} ///@}
/// @name Other /// @name Other
///@{ ///@{
/// Remember the parent app /// Remember the parent app
App* parent; App* parent_;
/// Options store a callback to do all the work /// Options store a callback to do all the work
callback_t callback; callback_t callback_;
///@} ///@}
@ -104,31 +104,31 @@ protected:
///@{ ///@{
/// Results of parsing /// Results of parsing
results_t results; results_t results_;
///@} ///@}
/// Making an option by hand is not defined, it must be made by the App class /// Making an option by hand is not defined, it must be made by the App class
Option(std::string name, std::string description = "", std::function<bool(results_t)> callback=[](results_t){return true;}, bool _default=true, App* parent = nullptr) : Option(std::string name, std::string description = "", std::function<bool(results_t)> callback=[](results_t){return true;}, bool default_=true, App* parent = nullptr) :
description(description), callback(callback), _default(_default), parent(parent) { description_(description), callback_(callback), default_(default_), parent_(parent) {
std::tie(snames, lnames, pname) = detail::get_names(detail::split_names(name)); std::tie(snames_, lnames_, pname_) = detail::get_names(detail::split_names(name));
} }
public: public:
// This class is "true" if optio passed. /// This class is true if option is passed.
operator bool() const { operator bool() const {
return results.size() > 0; return results_.size() > 0;
} }
/// Clear the parsed results (mostly for testing) /// Clear the parsed results (mostly for testing)
void clear() { void clear() {
results.clear(); results_.clear();
} }
/// Set the option as required /// Set the option as required
Option* required(bool value = true) { Option* required(bool value = true) {
_required = value; required_ = value;
return this; return this;
} }
@ -139,70 +139,70 @@ public:
/// True if this is a required option /// True if this is a required option
bool get_required() const { bool get_required() const {
return _required; return required_;
} }
/// Set the number of expected arguments (Flags bypass this) /// Set the number of expected arguments (Flags bypass this)
Option* expected(int value) { Option* expected(int value) {
if(value == 0) if(value == 0)
throw IncorrectConstruction("Cannot set 0 expected, use a flag instead"); throw IncorrectConstruction("Cannot set 0 expected, use a flag instead");
if(!allow_vector && value != 1) if(!allow_vector_ && value != 1)
throw IncorrectConstruction("You can only change the Expected arguments for vectors"); throw IncorrectConstruction("You can only change the Expected arguments for vectors");
_expected = value; expected_ = value;
return this; return this;
} }
/// The number of arguments the option expects /// The number of arguments the option expects
int get_expected() const { int get_expected() const {
return _expected; return expected_;
} }
/// True if this has a default value /// True if this has a default value
int get_default() const { int get_default() const {
return _default; return default_;
} }
/// True if the argument can be given directly /// True if the argument can be given directly
bool get_positional() const { bool get_positional() const {
return pname.length() > 0; return pname_.length() > 0;
} }
/// True if option has at least one non-positional name /// True if option has at least one non-positional name
bool nonpositional() const { bool nonpositional() const {
return (snames.size() + lnames.size()) > 0; return (snames_.size() + lnames_.size()) > 0;
} }
/// True if option has description /// True if option has description
bool has_description() const { bool has_description() const {
return description.length() > 0; return description_.length() > 0;
} }
/// Adds a validator /// Adds a validator
Option* check(std::function<bool(std::string)> validator) { Option* check(std::function<bool(std::string)> validator) {
_validators.push_back(validator); validators_.push_back(validator);
return this; return this;
} }
/// Changes the group membership /// Changes the group membership
Option* group(std::string name) { Option* group(std::string name) {
_group = name; group_ = name;
return this; return this;
} }
/// Get the group of this option /// Get the group of this option
const std::string& get_group() const { const std::string& get_group() const {
return _group; return group_;
} }
/// Get the description /// Get the description
const std::string& get_description() const { const std::string& get_description() const {
return description; return description_;
} }
/// Sets required options /// Sets required options
Option* requires(Option* opt) { Option* requires(Option* opt) {
auto tup = _requires.insert(opt); auto tup = requires_.insert(opt);
if(!tup.second) if(!tup.second)
throw OptionAlreadyAdded(get_name() + " requires " + opt->get_name()); throw OptionAlreadyAdded(get_name() + " requires " + opt->get_name());
return this; return this;
@ -217,7 +217,7 @@ public:
/// Sets excluded options /// Sets excluded options
Option* excludes(Option* opt) { Option* excludes(Option* opt) {
auto tup = _excludes.insert(opt); auto tup = excludes_.insert(opt);
if(!tup.second) if(!tup.second)
throw OptionAlreadyAdded(get_name() + " excludes " + opt->get_name()); throw OptionAlreadyAdded(get_name() + " excludes " + opt->get_name());
return this; return this;
@ -232,13 +232,13 @@ public:
/// Sets environment variable to read if no option given /// Sets environment variable to read if no option given
Option* envname(std::string name) { Option* envname(std::string name) {
_envname = name; envname_ = name;
return this; return this;
} }
/// The name and any extras needed for positionals /// The name and any extras needed for positionals
std::string help_positional() const { std::string help_positional() const {
std::string out = pname; std::string out = pname_;
if(get_expected()<1) if(get_expected()<1)
out = out + "x" + std::to_string(get_expected()); out = out + "x" + std::to_string(get_expected());
else if(get_expected()==-1) else if(get_expected()==-1)
@ -249,17 +249,17 @@ public:
// Just the pname // Just the pname
std::string get_pname() const { std::string get_pname() const {
return pname; return pname_;
} }
/// Process the callback /// Process the callback
void run_callback() const { void run_callback() const {
if(!callback(results)) if(!callback_(results_))
throw ConversionError(get_name() + "=" + detail::join(flatten_results())); throw ConversionError(get_name() + "=" + detail::join(flatten_results()));
if(_validators.size()>0) { if(validators_.size()>0) {
for(const std::string & result : flatten_results()) for(const std::string & result : flatten_results())
for(const std::function<bool(std::string)> &vali : _validators) for(const std::function<bool(std::string)> &vali : validators_)
if(!vali(result)) if(!vali(result))
throw ValidationError(get_name() + "=" + result); throw ValidationError(get_name() + "=" + result);
} }
@ -267,17 +267,17 @@ public:
/// If options share any of the same names, they are equal (not counting positional) /// If options share any of the same names, they are equal (not counting positional)
bool operator== (const Option& other) const { bool operator== (const Option& other) const {
for(const std::string &sname : snames) for(const std::string &sname : snames_)
if(other.check_sname(sname)) if(other.check_sname(sname))
return true; return true;
for(const std::string &lname : lnames) for(const std::string &lname : lnames_)
if(other.check_lname(lname)) if(other.check_lname(lname))
return true; return true;
// We need to do the inverse, just in case we are ignore_case // We need to do the inverse, just in case we are ignore_case
for(const std::string &sname : other.snames) for(const std::string &sname : other.snames_)
if(check_sname(sname)) if(check_sname(sname))
return true; return true;
for(const std::string &lname : other.lnames) for(const std::string &lname : other.lnames_)
if(check_lname(lname)) if(check_lname(lname))
return true; return true;
return false; return false;
@ -286,11 +286,11 @@ public:
/// Gets a , sep list of names. Does not include the positional name if opt_only=true. /// Gets a , sep list of names. Does not include the positional name if opt_only=true.
std::string get_name(bool opt_only=false) const { std::string get_name(bool opt_only=false) const {
std::vector<std::string> name_list; std::vector<std::string> name_list;
if(!opt_only && pname.length() > 0) if(!opt_only && pname_.length() > 0)
name_list.push_back(pname); name_list.push_back(pname_);
for(const std::string& sname : snames) for(const std::string& sname : snames_)
name_list.push_back("-"+sname); name_list.push_back("-"+sname);
for(const std::string& lname : lnames) for(const std::string& lname : lnames_)
name_list.push_back("--"+lname); name_list.push_back("--"+lname);
return detail::join(name_list); return detail::join(name_list);
} }
@ -301,8 +301,8 @@ public:
/// You are never expected to add an argument to the template here. /// You are never expected to add an argument to the template here.
template<typename T=App> template<typename T=App>
Option* ignore_case(bool value = true) { Option* ignore_case(bool value = true) {
case_insensitive = value; ignore_case_ = value;
for(const Option_p& opt : dynamic_cast<T*>(parent)->options_) for(const Option_p& opt : dynamic_cast<T*>(parent_)->options_)
if(opt.get() != this && *opt == *this) if(opt.get() != this && *opt == *this)
throw OptionAlreadyAdded(opt->get_name()); throw OptionAlreadyAdded(opt->get_name());
return this; return this;
@ -316,8 +316,8 @@ public:
else if (name.length()>1 && name.substr(0,1) == "-") else if (name.length()>1 && name.substr(0,1) == "-")
return check_sname(name.substr(1)); return check_sname(name.substr(1));
else { else {
std::string local_pname = pname; std::string local_pname = pname_;
if(case_insensitive) { if(ignore_case_) {
local_pname = detail::to_lower(local_pname); local_pname = detail::to_lower(local_pname);
name = detail::to_lower(name); name = detail::to_lower(name);
} }
@ -327,42 +327,42 @@ public:
/// Requires "-" to be removed from string /// Requires "-" to be removed from string
bool check_sname(std::string name) const { bool check_sname(std::string name) const {
if(case_insensitive) { if(ignore_case_) {
name = detail::to_lower(name); name = detail::to_lower(name);
return std::find_if(std::begin(snames), std::end(snames), return std::find_if(std::begin(snames_), std::end(snames_),
[&name](std::string local_sname){return detail::to_lower(local_sname) == name;}) [&name](std::string local_sname){return detail::to_lower(local_sname) == name;})
!= std::end(snames); != std::end(snames_);
} else } else
return std::find(std::begin(snames), std::end(snames), name) != std::end(snames); return std::find(std::begin(snames_), std::end(snames_), name) != std::end(snames_);
} }
/// Requires "--" to be removed from string /// Requires "--" to be removed from string
bool check_lname(std::string name) const { bool check_lname(std::string name) const {
if(case_insensitive) { if(ignore_case_) {
name = detail::to_lower(name); name = detail::to_lower(name);
return std::find_if(std::begin(lnames), std::end(lnames), return std::find_if(std::begin(lnames_), std::end(lnames_),
[&name](std::string local_sname){return detail::to_lower(local_sname) == name;}) [&name](std::string local_sname){return detail::to_lower(local_sname) == name;})
!= std::end(lnames); != std::end(lnames_);
} else } else
return std::find(std::begin(lnames), std::end(lnames), name) != std::end(lnames); return std::find(std::begin(lnames_), std::end(lnames_), name) != std::end(lnames_);
} }
/// Puts a result at position r /// Puts a result at position r
void add_result(int r, std::string s) { void add_result(int r, std::string s) {
results.at(r).push_back(s); results_.at(r).push_back(s);
} }
/// Starts a new results vector (used for r in add_result) /// Starts a new results vector (used for r in add_result)
int get_new() { int get_new() {
results.emplace_back(); results_.emplace_back();
return results.size() - 1; return results_.size() - 1;
} }
/// Count the total number of times an option was passed /// Count the total number of times an option was passed
int count() const { int count() const {
int out = 0; int out = 0;
for(const std::vector<std::string>& vec : results) for(const std::vector<std::string>& vec : results_)
out += vec.size(); out += vec.size();
return out; return out;
} }
@ -386,25 +386,25 @@ public:
std::stringstream out; std::stringstream out;
if(get_expected() != 0) { if(get_expected() != 0) {
if(typeval != "") if(typeval_ != "")
out << " " << typeval; out << " " << typeval_;
if(defaultval != "") if(defaultval_ != "")
out << "=" << defaultval; out << "=" << defaultval_;
if(get_expected() > 1) if(get_expected() > 1)
out << " x " << get_expected(); out << " x " << get_expected();
if(get_expected() == -1) if(get_expected() == -1)
out << " ..."; out << " ...";
} }
if(_envname != "") if(envname_ != "")
out << " (env:" << _envname << ")"; out << " (env:" << envname_ << ")";
if(_requires.size() > 0) { if(requires_.size() > 0) {
out << " Requires:"; out << " Requires:";
for(const Option* opt : _requires) for(const Option* opt : requires_)
out << " " << opt->get_name(); out << " " << opt->get_name();
} }
if(_excludes.size() > 0) { if(excludes_.size() > 0) {
out << " Excludes:"; out << " Excludes:";
for(const Option* opt : _excludes) for(const Option* opt : excludes_)
out << " " << opt->get_name(); out << " " << opt->get_name();
} }
return out.str(); return out.str();
@ -414,7 +414,7 @@ public:
/// Produce a flattened vector of results, vs. a vector of vectors. /// Produce a flattened vector of results, vs. a vector of vectors.
std::vector<std::string> flatten_results() const { std::vector<std::string> flatten_results() const {
std::vector<std::string> output; std::vector<std::string> output;
for(const std::vector<std::string> result : results) for(const std::vector<std::string> result : results_)
output.insert(std::end(output), std::begin(result), std::end(result)); output.insert(std::end(output), std::begin(result), std::end(result));
return output; return output;
} }