mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-29 20:23:55 +00:00
Moving code to Error, better ArgumentMismatch throwing
This commit is contained in:
parent
4d5bff2393
commit
f6c9ce6109
@ -452,7 +452,7 @@ class App {
|
|||||||
CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
|
CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
|
||||||
bool retval = detail::lexical_cast(res[0], member);
|
bool retval = detail::lexical_cast(res[0], member);
|
||||||
if(!retval)
|
if(!retval)
|
||||||
throw ConversionError("The value " + res[0] + "is not an allowed value for " + simple_name);
|
throw ConversionError(res[0], simple_name);
|
||||||
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -475,7 +475,7 @@ class App {
|
|||||||
CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
|
CLI::callback_t fun = [&member, options, simple_name](CLI::results_t res) {
|
||||||
bool retval = detail::lexical_cast(res[0], member);
|
bool retval = detail::lexical_cast(res[0], member);
|
||||||
if(!retval)
|
if(!retval)
|
||||||
throw ConversionError("The value " + res[0] + "is not an allowed value for " + simple_name);
|
throw ConversionError(res[0], simple_name);
|
||||||
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -504,7 +504,7 @@ class App {
|
|||||||
return detail::to_lower(val) == member;
|
return detail::to_lower(val) == member;
|
||||||
});
|
});
|
||||||
if(iter == std::end(options))
|
if(iter == std::end(options))
|
||||||
throw ConversionError("The value " + member + "is not an allowed value for " + simple_name);
|
throw ConversionError(member, simple_name);
|
||||||
else {
|
else {
|
||||||
member = *iter;
|
member = *iter;
|
||||||
return true;
|
return true;
|
||||||
@ -533,7 +533,7 @@ class App {
|
|||||||
return detail::to_lower(val) == member;
|
return detail::to_lower(val) == member;
|
||||||
});
|
});
|
||||||
if(iter == std::end(options))
|
if(iter == std::end(options))
|
||||||
throw ConversionError("The value " + member + "is not an allowed value for " + simple_name);
|
throw ConversionError(member, simple_name);
|
||||||
else {
|
else {
|
||||||
member = *iter;
|
member = *iter;
|
||||||
return true;
|
return true;
|
||||||
@ -1149,12 +1149,7 @@ class App {
|
|||||||
|
|
||||||
// Required but empty
|
// Required but empty
|
||||||
if(opt->get_required() && opt->count() == 0)
|
if(opt->get_required() && opt->count() == 0)
|
||||||
throw RequiredError(opt->help_name() + " is required");
|
throw RequiredError(opt->single_name() + " is required");
|
||||||
|
|
||||||
// Partially filled
|
|
||||||
if(opt->get_expected() > 0 && static_cast<int>(opt->count()) < opt->get_expected())
|
|
||||||
throw RequiredError(opt->help_name() + " requires " + std::to_string(opt->get_expected()) +
|
|
||||||
" arguments");
|
|
||||||
}
|
}
|
||||||
// Requires
|
// Requires
|
||||||
for(const Option *opt_req : opt->requires_)
|
for(const Option *opt_req : opt->requires_)
|
||||||
@ -1409,8 +1404,8 @@ class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(num > 0) {
|
if(num > 0) {
|
||||||
throw RequiredError(op->single_name() + ": " + std::to_string(num) + " required " +
|
throw ArgumentMismatch(op->single_name() + ": " + std::to_string(num) + " required " +
|
||||||
op->get_type_name() + " missing");
|
op->get_type_name() + " missing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1490,8 +1485,8 @@ class App {
|
|||||||
args.pop_back();
|
args.pop_back();
|
||||||
}
|
}
|
||||||
if(num > 0) {
|
if(num > 0) {
|
||||||
throw RequiredError(op->single_name() + ": " + std::to_string(num) + " required " +
|
throw ArgumentMismatch(op->single_name() + ": " + std::to_string(num) + " required " +
|
||||||
op->get_type_name() + " missing");
|
op->get_type_name() + " missing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -126,19 +126,22 @@ 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 msg) : FileError(msg, ExitCodes::File) {}
|
FileError(std::string name) : FileError(name + " was not readable (missing?)", ExitCodes::File) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 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
|
||||||
class ConversionError : public ParseError {
|
class ConversionError : public ParseError {
|
||||||
CLI11_ERROR_DEF(ParseError, ConversionError)
|
CLI11_ERROR_DEF(ParseError, ConversionError)
|
||||||
CLI11_ERROR_SIMPLE(ConversionError)
|
CLI11_ERROR_SIMPLE(ConversionError)
|
||||||
|
ConversionError(std::string member, std::string name)
|
||||||
|
: ConversionError("The value " + member + "is not an allowed value for " + name) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when validation of results fails
|
/// Thrown when validation of results fails
|
||||||
class ValidationError : public ParseError {
|
class ValidationError : public ParseError {
|
||||||
CLI11_ERROR_DEF(ParseError, ValidationError)
|
CLI11_ERROR_DEF(ParseError, ValidationError)
|
||||||
CLI11_ERROR_SIMPLE(ValidationError)
|
CLI11_ERROR_SIMPLE(ValidationError)
|
||||||
|
ValidationError(std::string name, std::string msg) : ValidationError(name + ": " + msg) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Thrown when a required option is missing
|
/// Thrown when a required option is missing
|
||||||
@ -150,6 +153,7 @@ class RequiredError : public ParseError {
|
|||||||
/// Thrown when the wrong number of arguments has been recieved
|
/// Thrown when the wrong number of arguments has been recieved
|
||||||
class ArgumentMismatch : ParseError {
|
class ArgumentMismatch : ParseError {
|
||||||
CLI11_ERROR_DEF(ParseError, ArgumentMismatch)
|
CLI11_ERROR_DEF(ParseError, ArgumentMismatch)
|
||||||
|
CLI11_ERROR_SIMPLE(ArgumentMismatch)
|
||||||
ArgumentMismatch(std::string name, int expected, size_t recieved)
|
ArgumentMismatch(std::string name, int expected, size_t recieved)
|
||||||
: ArgumentMismatch(expected > 0 ? ("Expected exactly " + std::to_string(expected) + " arguments to " + name +
|
: ArgumentMismatch(expected > 0 ? ("Expected exactly " + std::to_string(expected) + " arguments to " + name +
|
||||||
", got " + std::to_string(recieved))
|
", got " + std::to_string(recieved))
|
||||||
|
@ -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 + " was not readable (missing?)");
|
throw FileError(name);
|
||||||
|
|
||||||
return parse_ini(input);
|
return parse_ini(input);
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ class Option : public OptionBase<Option> {
|
|||||||
for(const std::function<std::string(std::string &)> &vali : validators_) {
|
for(const std::function<std::string(std::string &)> &vali : validators_) {
|
||||||
std::string err_msg = vali(result);
|
std::string err_msg = vali(result);
|
||||||
if(!err_msg.empty())
|
if(!err_msg.empty())
|
||||||
throw ValidationError(single_name() + ": " + err_msg);
|
throw ValidationError(single_name(), err_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,6 +243,26 @@ TEST_F(TApp, MissingValueNonRequiredOpt) {
|
|||||||
EXPECT_ANY_THROW(run());
|
EXPECT_ANY_THROW(run());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TApp, NotRequiredOptsSingle) {
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
app.add_option("--str", str);
|
||||||
|
|
||||||
|
args = {"--str"};
|
||||||
|
|
||||||
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TApp, NotRequiredOptsSingleShort) {
|
||||||
|
|
||||||
|
std::string str;
|
||||||
|
app.add_option("-s", str);
|
||||||
|
|
||||||
|
args = {"-s"};
|
||||||
|
|
||||||
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(TApp, RequiredOptsSingle) {
|
TEST_F(TApp, RequiredOptsSingle) {
|
||||||
|
|
||||||
std::string str;
|
std::string str;
|
||||||
@ -250,7 +270,7 @@ TEST_F(TApp, RequiredOptsSingle) {
|
|||||||
|
|
||||||
args = {"--str"};
|
args = {"--str"};
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::RequiredError);
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TApp, RequiredOptsSingleShort) {
|
TEST_F(TApp, RequiredOptsSingleShort) {
|
||||||
@ -260,7 +280,7 @@ TEST_F(TApp, RequiredOptsSingleShort) {
|
|||||||
|
|
||||||
args = {"-s"};
|
args = {"-s"};
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::RequiredError);
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TApp, RequiredOptsDouble) {
|
TEST_F(TApp, RequiredOptsDouble) {
|
||||||
@ -270,7 +290,7 @@ TEST_F(TApp, RequiredOptsDouble) {
|
|||||||
|
|
||||||
args = {"--str", "one"};
|
args = {"--str", "one"};
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::RequiredError);
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
|
|
||||||
app.reset();
|
app.reset();
|
||||||
args = {"--str", "one", "two"};
|
args = {"--str", "one", "two"};
|
||||||
@ -287,7 +307,7 @@ TEST_F(TApp, RequiredOptsDoubleShort) {
|
|||||||
|
|
||||||
args = {"-s", "one"};
|
args = {"-s", "one"};
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::RequiredError);
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
|
|
||||||
app.reset();
|
app.reset();
|
||||||
args = {"-s", "one", "two"};
|
args = {"-s", "one", "two"};
|
||||||
@ -414,7 +434,17 @@ TEST_F(TApp, NotRequiedExpectedDouble) {
|
|||||||
|
|
||||||
args = {"--str", "one"};
|
args = {"--str", "one"};
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::RequiredError);
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TApp, NotRequiedExpectedDoubleShort) {
|
||||||
|
|
||||||
|
std::vector<std::string> strs;
|
||||||
|
app.add_option("-s", strs)->expected(2);
|
||||||
|
|
||||||
|
args = {"-s", "one"};
|
||||||
|
|
||||||
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TApp, EnumTest) {
|
TEST_F(TApp, EnumTest) {
|
||||||
|
@ -91,5 +91,5 @@ TEST_F(TApp, BuiltinComplexFail) {
|
|||||||
|
|
||||||
args = {"-c", "4"};
|
args = {"-c", "4"};
|
||||||
|
|
||||||
EXPECT_THROW(run(), CLI::RequiredError);
|
EXPECT_THROW(run(), CLI::ArgumentMismatch);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user