mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-29 20:23:55 +00:00
Moving error messages definitions to Error.h
This commit is contained in:
parent
04e01d2b70
commit
c1fb53f00d
@ -369,7 +369,7 @@ class App {
|
|||||||
|
|
||||||
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::PositionalFlag(name);
|
||||||
opt->set_custom_option("", 0);
|
opt->set_custom_option("", 0);
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
@ -389,7 +389,7 @@ class App {
|
|||||||
|
|
||||||
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::PositionalFlag(name);
|
||||||
opt->set_custom_option("", 0);
|
opt->set_custom_option("", 0);
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
@ -409,7 +409,7 @@ class App {
|
|||||||
|
|
||||||
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::PositionalFlag(name);
|
||||||
opt->set_custom_option("", 0);
|
opt->set_custom_option("", 0);
|
||||||
opt->multi_option_policy(CLI::MultiOptionPolicy::TakeLast);
|
opt->multi_option_policy(CLI::MultiOptionPolicy::TakeLast);
|
||||||
return opt;
|
return opt;
|
||||||
@ -428,7 +428,7 @@ class App {
|
|||||||
|
|
||||||
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::PositionalFlag(name);
|
||||||
opt->set_custom_option("", 0);
|
opt->set_custom_option("", 0);
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
@ -1100,7 +1100,7 @@ class App {
|
|||||||
std::vector<detail::ini_ret_t> values = detail::parse_ini(config_name_);
|
std::vector<detail::ini_ret_t> values = detail::parse_ini(config_name_);
|
||||||
while(!values.empty()) {
|
while(!values.empty()) {
|
||||||
if(!_parse_ini(values)) {
|
if(!_parse_ini(values)) {
|
||||||
throw ExtrasINIError(values.back().fullname);
|
throw INIError::Extras(values.back().fullname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(const FileError &) {
|
} catch(const FileError &) {
|
||||||
@ -1149,8 +1149,7 @@ class App {
|
|||||||
if(opt->get_required() || opt->count() != 0) {
|
if(opt->get_required() || opt->count() != 0) {
|
||||||
// Make sure enough -N arguments parsed (+N is already handled in parsing function)
|
// Make sure enough -N arguments parsed (+N is already handled in parsing function)
|
||||||
if(opt->get_expected() < 0 && opt->count() < static_cast<size_t>(-opt->get_expected()))
|
if(opt->get_expected() < 0 && opt->count() < static_cast<size_t>(-opt->get_expected()))
|
||||||
throw ArgumentMismatch(opt->single_name() + ": At least " + std::to_string(-opt->get_expected()) +
|
throw ArgumentMismatch::AtLeast(opt->single_name(), -opt->get_expected());
|
||||||
" required");
|
|
||||||
|
|
||||||
// Required but empty
|
// Required but empty
|
||||||
if(opt->get_required() && opt->count() == 0)
|
if(opt->get_required() && opt->count() == 0)
|
||||||
@ -1167,10 +1166,8 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto selected_subcommands = get_subcommands();
|
auto selected_subcommands = get_subcommands();
|
||||||
if(require_subcommand_min_ > 0 && selected_subcommands.empty())
|
if(require_subcommand_min_ > selected_subcommands.size())
|
||||||
throw RequiredError("Subcommand required");
|
throw RequiredError::Subcommand(require_subcommand_min_);
|
||||||
else if(require_subcommand_min_ > selected_subcommands.size())
|
|
||||||
throw RequiredError("Requires at least " + std::to_string(require_subcommand_min_) + " subcommands");
|
|
||||||
|
|
||||||
// Convert missing (pairs) to extras (string only)
|
// Convert missing (pairs) to extras (string only)
|
||||||
if(!(allow_extras_ || prefix_command_)) {
|
if(!(allow_extras_ || prefix_command_)) {
|
||||||
@ -1210,6 +1207,9 @@ class App {
|
|||||||
// Let's not go crazy with pointer syntax
|
// Let's not go crazy with pointer syntax
|
||||||
Option_p &op = *op_ptr;
|
Option_p &op = *op_ptr;
|
||||||
|
|
||||||
|
if(!op->get_configurable())
|
||||||
|
throw INIError::NotConfigurable(current.fullname);
|
||||||
|
|
||||||
if(op->results_.empty()) {
|
if(op->results_.empty()) {
|
||||||
// Flag parsing
|
// Flag parsing
|
||||||
if(op->get_expected() == 0) {
|
if(op->get_expected() == 0) {
|
||||||
@ -1226,10 +1226,10 @@ class App {
|
|||||||
for(size_t i = 0; i < ui; i++)
|
for(size_t i = 0; i < ui; i++)
|
||||||
op->results_.emplace_back("");
|
op->results_.emplace_back("");
|
||||||
} catch(const std::invalid_argument &) {
|
} catch(const std::invalid_argument &) {
|
||||||
throw ConversionError(current.fullname + ": Should be true/false or a number");
|
throw ConversionError::TrueFalse(current.fullname);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
throw ConversionError(current.fullname + ": too many inputs for a flag");
|
throw ConversionError::TooManyInputsFlag(current.fullname);
|
||||||
} else {
|
} else {
|
||||||
op->results_ = current.inputs;
|
op->results_ = current.inputs;
|
||||||
op->run_callback();
|
op->run_callback();
|
||||||
@ -1424,8 +1424,7 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(num > 0) {
|
if(num > 0) {
|
||||||
throw ArgumentMismatch(op->single_name() + ": " + std::to_string(num) + " required " +
|
throw ArgumentMismatch::TypedAtLeast(op->single_name(), num, op->get_type_name());
|
||||||
op->get_type_name() + " missing");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,14 +35,14 @@ enum class ExitCodes {
|
|||||||
IncorrectConstruction = 100,
|
IncorrectConstruction = 100,
|
||||||
BadNameString,
|
BadNameString,
|
||||||
OptionAlreadyAdded,
|
OptionAlreadyAdded,
|
||||||
File,
|
FileError,
|
||||||
ConversionError,
|
ConversionError,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
RequiredError,
|
RequiredError,
|
||||||
RequiresError,
|
RequiresError,
|
||||||
ExcludesError,
|
ExcludesError,
|
||||||
ExtrasError,
|
ExtrasError,
|
||||||
ExtrasINIError,
|
INIError,
|
||||||
InvalidError,
|
InvalidError,
|
||||||
HorribleError,
|
HorribleError,
|
||||||
OptionNotFound,
|
OptionNotFound,
|
||||||
@ -85,18 +85,50 @@ class ConstructionError : public Error {
|
|||||||
class IncorrectConstruction : public ConstructionError {
|
class IncorrectConstruction : public ConstructionError {
|
||||||
CLI11_ERROR_DEF(ConstructionError, IncorrectConstruction)
|
CLI11_ERROR_DEF(ConstructionError, IncorrectConstruction)
|
||||||
CLI11_ERROR_SIMPLE(IncorrectConstruction)
|
CLI11_ERROR_SIMPLE(IncorrectConstruction)
|
||||||
|
static IncorrectConstruction PositionalFlag(std::string name) {
|
||||||
|
return IncorrectConstruction(name + ": Flags cannot be positional");}
|
||||||
|
static IncorrectConstruction Set0Opt(std::string name) {
|
||||||
|
return IncorrectConstruction(name + ": Cannot set 0 expected, use a flag instead");}
|
||||||
|
static IncorrectConstruction ChangeNotVector(std::string name) {
|
||||||
|
return IncorrectConstruction(name + ": You can only change the expected arguments for vectors");}
|
||||||
|
static IncorrectConstruction AfterMultiOpt(std::string name) {
|
||||||
|
return IncorrectConstruction(name + ": You can't change expected arguments after you've changed the multi option policy!");}
|
||||||
|
static IncorrectConstruction MissingOption(std::string name) {
|
||||||
|
return IncorrectConstruction("Option " + name + " is not defined");}
|
||||||
|
static IncorrectConstruction MultiOptionPolicy(std::string name) {
|
||||||
|
return IncorrectConstruction(name + ": multi_option_policy only works for flags and single value options");}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown on construction of a bad name
|
/// Thrown on construction of a bad name
|
||||||
class BadNameString : public ConstructionError {
|
class BadNameString : public ConstructionError {
|
||||||
CLI11_ERROR_DEF(ConstructionError, BadNameString)
|
CLI11_ERROR_DEF(ConstructionError, BadNameString)
|
||||||
CLI11_ERROR_SIMPLE(BadNameString)
|
CLI11_ERROR_SIMPLE(BadNameString)
|
||||||
|
static BadNameString OneCharName(std::string name) {
|
||||||
|
return BadNameString("Invalid one char name: " + name);
|
||||||
|
}
|
||||||
|
static BadNameString BadLongName(std::string name) {
|
||||||
|
return BadNameString("Bad long name: " + name);
|
||||||
|
}
|
||||||
|
static BadNameString DashesOnly(std::string name) {
|
||||||
|
return BadNameString("Must have a name, not just dashes: " + name);
|
||||||
|
}
|
||||||
|
static BadNameString MultiPositionalNames(std::string name) {
|
||||||
|
return BadNameString("Only one positional name allowed, remove: " + name);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when an option already exists
|
/// Thrown when an option already exists
|
||||||
class OptionAlreadyAdded : public ConstructionError {
|
class OptionAlreadyAdded : public ConstructionError {
|
||||||
CLI11_ERROR_DEF(ConstructionError, OptionAlreadyAdded)
|
CLI11_ERROR_DEF(ConstructionError, OptionAlreadyAdded)
|
||||||
CLI11_ERROR_SIMPLE(OptionAlreadyAdded)
|
OptionAlreadyAdded(std::string name)
|
||||||
|
: OptionAlreadyAdded(name + " is already added", ExitCodes::OptionAlreadyAdded) {}
|
||||||
|
static OptionAlreadyAdded Requires(std::string name, std::string other) {
|
||||||
|
return OptionAlreadyAdded(name + " requires " + other, ExitCodes::OptionAlreadyAdded);
|
||||||
|
}
|
||||||
|
static OptionAlreadyAdded Excludes(std::string name, std::string other) {
|
||||||
|
return OptionAlreadyAdded(name + " excludes " + other, ExitCodes::OptionAlreadyAdded);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parsing errors
|
// Parsing errors
|
||||||
@ -129,7 +161,8 @@ class RuntimeError : public ParseError {
|
|||||||
/// Thrown when parsing an INI file and it is missing
|
/// Thrown when parsing an INI file and it is missing
|
||||||
class FileError : public ParseError {
|
class FileError : public ParseError {
|
||||||
CLI11_ERROR_DEF(ParseError, FileError)
|
CLI11_ERROR_DEF(ParseError, FileError)
|
||||||
FileError(std::string name) : FileError(name + " was not readable (missing?)", ExitCodes::File) {}
|
CLI11_ERROR_SIMPLE(FileError)
|
||||||
|
static FileError Missing(std::string name) {return FileError(name + " was not readable (missing?)");}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when conversion call back fails, such as when an int fails to coerce to a string
|
/// Thrown when conversion call back fails, such as when an int fails to coerce to a string
|
||||||
@ -138,6 +171,12 @@ class ConversionError : public ParseError {
|
|||||||
CLI11_ERROR_SIMPLE(ConversionError)
|
CLI11_ERROR_SIMPLE(ConversionError)
|
||||||
ConversionError(std::string member, std::string name)
|
ConversionError(std::string member, std::string name)
|
||||||
: ConversionError("The value " + member + "is not an allowed value for " + name) {}
|
: ConversionError("The value " + member + "is not an allowed value for " + name) {}
|
||||||
|
ConversionError(std::string name, std::vector<std::string> results)
|
||||||
|
: ConversionError("Could not convert: " + name + " = " + detail::join(results)) {}
|
||||||
|
static ConversionError TooManyInputsFlag(std::string name) {
|
||||||
|
return ConversionError(name + ": too many inputs for a flag");}
|
||||||
|
static ConversionError TrueFalse(std::string name) {
|
||||||
|
return ConversionError(name + ": Should be true/false or a number");}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when validation of results fails
|
/// Thrown when validation of results fails
|
||||||
@ -150,7 +189,15 @@ class ValidationError : public ParseError {
|
|||||||
/// Thrown when a required option is missing
|
/// Thrown when a required option is missing
|
||||||
class RequiredError : public ParseError {
|
class RequiredError : public ParseError {
|
||||||
CLI11_ERROR_DEF(ParseError, RequiredError)
|
CLI11_ERROR_DEF(ParseError, RequiredError)
|
||||||
CLI11_ERROR_SIMPLE(RequiredError)
|
RequiredError(std::string name) : RequiredError(name + " is required") {}
|
||||||
|
static RequiredError Subcommand(size_t min_subcom) {
|
||||||
|
if(min_subcom == 1)
|
||||||
|
return RequiredError("A subcommand");
|
||||||
|
else
|
||||||
|
return RequiredError("Requires at least " + std::to_string(min_subcom) + " subcommands", ExitCodes::RequiredError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when the wrong number of arguments has been received
|
/// Thrown when the wrong number of arguments has been received
|
||||||
@ -163,6 +210,13 @@ class ArgumentMismatch : public ParseError {
|
|||||||
: ("Expected at least " + std::to_string(-expected) + " arguments to " + name +
|
: ("Expected at least " + std::to_string(-expected) + " arguments to " + name +
|
||||||
", got " + std::to_string(recieved)),
|
", got " + std::to_string(recieved)),
|
||||||
ExitCodes::ArgumentMismatch) {}
|
ExitCodes::ArgumentMismatch) {}
|
||||||
|
|
||||||
|
static ArgumentMismatch AtLeast(std::string name, int num) {
|
||||||
|
return ArgumentMismatch(name + ": At least " + std::to_string(num) + " required");}
|
||||||
|
static ArgumentMismatch TypedAtLeast(std::string name, int num, std::string type) {
|
||||||
|
return ArgumentMismatch(name + ": " + std::to_string(num) + " required " + type + " missing");}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when a requires option is missing
|
/// Thrown when a requires option is missing
|
||||||
@ -190,9 +244,12 @@ class ExtrasError : public ParseError {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when extra values are found in an INI file
|
/// Thrown when extra values are found in an INI file
|
||||||
class ExtrasINIError : public ParseError {
|
class INIError : public ParseError {
|
||||||
CLI11_ERROR_DEF(ParseError, ExtrasINIError)
|
CLI11_ERROR_DEF(ParseError, INIError)
|
||||||
ExtrasINIError(std::string item) : ExtrasINIError("INI was not able to parse " + item, ExitCodes::ExtrasINIError) {}
|
CLI11_ERROR_SIMPLE(INIError)
|
||||||
|
static INIError Extras(std::string item) {return INIError("INI was not able to parse " + item);}
|
||||||
|
static INIError NotConfigurable(std::string item) {return INIError(item + ": This option is not allowed in a configuration file");}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when validation fails before parsing
|
/// Thrown when validation fails before parsing
|
||||||
@ -204,6 +261,7 @@ class InvalidError : public ParseError {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// This is just a safety check to verify selection and parsing match - you should not ever see it
|
/// This is just a safety check to verify selection and parsing match - you should not ever see it
|
||||||
|
/// Strings are directly added to this error, but again, it should never be seen.
|
||||||
class HorribleError : public ParseError {
|
class HorribleError : public ParseError {
|
||||||
CLI11_ERROR_DEF(ParseError, HorribleError)
|
CLI11_ERROR_DEF(ParseError, HorribleError)
|
||||||
CLI11_ERROR_SIMPLE(HorribleError)
|
CLI11_ERROR_SIMPLE(HorribleError)
|
||||||
|
@ -106,7 +106,7 @@ inline std::vector<ini_ret_t> parse_ini(const std::string &name) {
|
|||||||
|
|
||||||
std::ifstream input{name};
|
std::ifstream input{name};
|
||||||
if(!input.good())
|
if(!input.good())
|
||||||
throw FileError(name);
|
throw FileError::Missing(name);
|
||||||
|
|
||||||
return parse_ini(input);
|
return parse_ini(input);
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,12 @@ template <typename CRTP> class OptionBase {
|
|||||||
/// Ignore the case when matching (option, not value)
|
/// Ignore the case when matching (option, not value)
|
||||||
bool ignore_case_{false};
|
bool ignore_case_{false};
|
||||||
|
|
||||||
|
/// Allow this option to be given in a configuration file
|
||||||
|
bool configurable_{true};
|
||||||
|
|
||||||
/// Policy for multiple arguments when `expected_ == 1` (can be set on bool flags, too)
|
/// Policy for multiple arguments when `expected_ == 1` (can be set on bool flags, too)
|
||||||
MultiOptionPolicy multi_option_policy_{MultiOptionPolicy::Throw};
|
MultiOptionPolicy multi_option_policy_{MultiOptionPolicy::Throw};
|
||||||
|
|
||||||
|
|
||||||
template <typename T> void copy_to(T *other) const {
|
template <typename T> void copy_to(T *other) const {
|
||||||
other->group(group_);
|
other->group(group_);
|
||||||
@ -80,6 +84,9 @@ template <typename CRTP> class OptionBase {
|
|||||||
|
|
||||||
/// The status of ignore case
|
/// The status of ignore case
|
||||||
bool get_ignore_case() const { return ignore_case_; }
|
bool get_ignore_case() const { return ignore_case_; }
|
||||||
|
|
||||||
|
/// The status of configurable
|
||||||
|
bool get_configurable() const { return configurable_; }
|
||||||
|
|
||||||
/// The status of the multi option policy
|
/// The status of the multi option policy
|
||||||
MultiOptionPolicy get_multi_option_policy() const { return multi_option_policy_; }
|
MultiOptionPolicy get_multi_option_policy() const { return multi_option_policy_; }
|
||||||
@ -106,6 +113,12 @@ template <typename CRTP> class OptionBase {
|
|||||||
self->multi_option_policy(MultiOptionPolicy::Join);
|
self->multi_option_policy(MultiOptionPolicy::Join);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allow in a configuration file
|
||||||
|
CRTP *configurable(bool value = true) {
|
||||||
|
configurable_ = value;
|
||||||
|
return static_cast<CRTP *>(this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OptionDefaults : public OptionBase<OptionDefaults> {
|
class OptionDefaults : public OptionBase<OptionDefaults> {
|
||||||
@ -235,12 +248,11 @@ class Option : public OptionBase<Option> {
|
|||||||
if(expected_ == value)
|
if(expected_ == value)
|
||||||
return this;
|
return this;
|
||||||
else if(value == 0)
|
else if(value == 0)
|
||||||
throw IncorrectConstruction("Cannot set 0 expected, use a flag instead");
|
throw IncorrectConstruction::Set0Opt(single_name());
|
||||||
else if(!changeable_)
|
else if(!changeable_)
|
||||||
throw IncorrectConstruction("You can only change the expected arguments for vectors");
|
throw IncorrectConstruction::ChangeNotVector(single_name());
|
||||||
else if(value != 1 && multi_option_policy_ != MultiOptionPolicy::Throw)
|
else if(value != 1 && multi_option_policy_ != MultiOptionPolicy::Throw)
|
||||||
throw IncorrectConstruction(
|
throw IncorrectConstruction::AfterMultiOpt(single_name());
|
||||||
"You can't change expected arguments after you've changed the multi option policy!");
|
|
||||||
|
|
||||||
expected_ = value;
|
expected_ = value;
|
||||||
return this;
|
return this;
|
||||||
@ -269,7 +281,7 @@ class Option : public OptionBase<Option> {
|
|||||||
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::Requires(get_name(), opt->get_name());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +290,7 @@ class Option : public OptionBase<Option> {
|
|||||||
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->check_name(opt_name))
|
if(opt.get() != this && opt->check_name(opt_name))
|
||||||
return requires(opt.get());
|
return requires(opt.get());
|
||||||
throw IncorrectConstruction("Option " + opt_name + " is not defined");
|
throw IncorrectConstruction::MissingOption(opt_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Any number supported, any mix of string and Opt
|
/// Any number supported, any mix of string and Opt
|
||||||
@ -291,7 +303,7 @@ class Option : public OptionBase<Option> {
|
|||||||
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::Excludes(get_name(), opt->get_name());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +312,7 @@ class Option : public OptionBase<Option> {
|
|||||||
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->check_name(opt_name))
|
if(opt.get() != this && opt->check_name(opt_name))
|
||||||
return excludes(opt.get());
|
return excludes(opt.get());
|
||||||
throw IncorrectConstruction("Option " + opt_name + " is not defined");
|
throw IncorrectConstruction::MissingOption(opt_name);
|
||||||
}
|
}
|
||||||
/// Any number supported, any mix of string and Opt
|
/// Any number supported, any mix of string and Opt
|
||||||
template <typename A, typename B, typename... ARG> Option *excludes(A opt, B opt1, ARG... args) {
|
template <typename A, typename B, typename... ARG> Option *excludes(A opt, B opt1, ARG... args) {
|
||||||
@ -324,7 +336,7 @@ class Option : public OptionBase<Option> {
|
|||||||
|
|
||||||
for(const Option_p &opt : parent->options_)
|
for(const Option_p &opt : parent->options_)
|
||||||
if(opt.get() != this && *opt == *this)
|
if(opt.get() != this && *opt == *this)
|
||||||
throw OptionAlreadyAdded(opt->get_name() + " is already added");
|
throw OptionAlreadyAdded(opt->get_name());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -332,7 +344,7 @@ class Option : public OptionBase<Option> {
|
|||||||
/// Take the last argument if given multiple times
|
/// Take the last argument if given multiple times
|
||||||
Option *multi_option_policy(MultiOptionPolicy value = MultiOptionPolicy::Throw) {
|
Option *multi_option_policy(MultiOptionPolicy value = MultiOptionPolicy::Throw) {
|
||||||
if(get_expected() != 0 && get_expected() != 1)
|
if(get_expected() != 0 && get_expected() != 1)
|
||||||
throw IncorrectConstruction("multi_option_policy only works for flags and single value options!");
|
throw IncorrectConstruction::MultiOptionPolicy(single_name());
|
||||||
multi_option_policy_ = value;
|
multi_option_policy_ = value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -480,7 +492,7 @@ class Option : public OptionBase<Option> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(local_result)
|
if(local_result)
|
||||||
throw ConversionError("Could not convert: " + get_name() + "=" + detail::join(results_));
|
throw ConversionError(get_name(), results_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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)
|
||||||
|
@ -66,18 +66,18 @@ get_names(const std::vector<std::string> &input) {
|
|||||||
if(name.length() == 2 && valid_first_char(name[1]))
|
if(name.length() == 2 && valid_first_char(name[1]))
|
||||||
short_names.emplace_back(1, name[1]);
|
short_names.emplace_back(1, name[1]);
|
||||||
else
|
else
|
||||||
throw BadNameString("Invalid one char name: " + name);
|
throw BadNameString::OneCharName(name);
|
||||||
} else if(name.length() > 2 && name.substr(0, 2) == "--") {
|
} else if(name.length() > 2 && name.substr(0, 2) == "--") {
|
||||||
name = name.substr(2);
|
name = name.substr(2);
|
||||||
if(valid_name_string(name))
|
if(valid_name_string(name))
|
||||||
long_names.push_back(name);
|
long_names.push_back(name);
|
||||||
else
|
else
|
||||||
throw BadNameString("Bad long name: " + name);
|
throw BadNameString::BadLongName(name);
|
||||||
} else if(name == "-" || name == "--") {
|
} else if(name == "-" || name == "--") {
|
||||||
throw BadNameString("Must have a name, not just dashes");
|
throw BadNameString::DashesOnly(name);
|
||||||
} else {
|
} else {
|
||||||
if(pos_name.length() > 0)
|
if(pos_name.length() > 0)
|
||||||
throw BadNameString("Only one positional name allowed, remove: " + name);
|
throw BadNameString::MultiPositionalNames(name);
|
||||||
pos_name = name;
|
pos_name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -376,7 +376,7 @@ TEST_F(TApp, IniFailure) {
|
|||||||
out << "val=1" << std::endl;
|
out << "val=1" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::ExtrasINIError);
|
EXPECT_THROW(run(), CLI::INIError);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TApp, IniSubFailure) {
|
TEST_F(TApp, IniSubFailure) {
|
||||||
@ -392,7 +392,7 @@ TEST_F(TApp, IniSubFailure) {
|
|||||||
out << "val=1" << std::endl;
|
out << "val=1" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::ExtrasINIError);
|
EXPECT_THROW(run(), CLI::INIError);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TApp, IniNoSubFailure) {
|
TEST_F(TApp, IniNoSubFailure) {
|
||||||
@ -407,7 +407,7 @@ TEST_F(TApp, IniNoSubFailure) {
|
|||||||
out << "val=1" << std::endl;
|
out << "val=1" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::ExtrasINIError);
|
EXPECT_THROW(run(), CLI::INIError);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TApp, IniFlagConvertFailure) {
|
TEST_F(TApp, IniFlagConvertFailure) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user