Allow unrecognised options. (#105)
Allows unrecognised options to be left alone by the parser without throwing an exception.
This commit is contained in:
parent
00e8ecc482
commit
ca6e9f70eb
@ -1095,6 +1095,7 @@ namespace cxxopts
|
||||
ParseResult(
|
||||
const std::unordered_map<std::string, std::shared_ptr<OptionDetails>>&,
|
||||
std::vector<std::string>,
|
||||
bool allow_unrecognised,
|
||||
int&, char**&);
|
||||
|
||||
size_t
|
||||
@ -1174,6 +1175,8 @@ namespace cxxopts
|
||||
std::unordered_set<std::string> m_positional_set;
|
||||
std::unordered_map<std::shared_ptr<OptionDetails>, OptionValue> m_results;
|
||||
|
||||
bool m_allow_unrecognised;
|
||||
|
||||
std::vector<KeyValue> m_sequential;
|
||||
};
|
||||
|
||||
@ -1187,6 +1190,7 @@ namespace cxxopts
|
||||
, m_custom_help("[OPTION...]")
|
||||
, m_positional_help("positional parameters")
|
||||
, m_show_positional(false)
|
||||
, m_allow_unrecognised(false)
|
||||
, m_next_positional(m_positional.end())
|
||||
{
|
||||
}
|
||||
@ -1212,6 +1216,13 @@ namespace cxxopts
|
||||
return *this;
|
||||
}
|
||||
|
||||
Options&
|
||||
allow_unrecognised_options()
|
||||
{
|
||||
m_allow_unrecognised = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ParseResult
|
||||
parse(int& argc, char**& argv);
|
||||
|
||||
@ -1275,6 +1286,7 @@ namespace cxxopts
|
||||
std::string m_custom_help;
|
||||
std::string m_positional_help;
|
||||
bool m_show_positional;
|
||||
bool m_allow_unrecognised;
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<OptionDetails>> m_options;
|
||||
std::vector<std::string> m_positional;
|
||||
@ -1431,11 +1443,13 @@ ParseResult::ParseResult
|
||||
(
|
||||
const std::unordered_map<std::string, std::shared_ptr<OptionDetails>>& options,
|
||||
std::vector<std::string> positional,
|
||||
bool allow_unrecognised,
|
||||
int& argc, char**& argv
|
||||
)
|
||||
: m_options(options)
|
||||
, m_positional(std::move(positional))
|
||||
, m_next_positional(m_positional.begin())
|
||||
, m_allow_unrecognised(allow_unrecognised)
|
||||
{
|
||||
parse(argc, argv);
|
||||
}
|
||||
@ -1641,7 +1655,7 @@ inline
|
||||
ParseResult
|
||||
Options::parse(int& argc, char**& argv)
|
||||
{
|
||||
ParseResult result(m_options, m_positional, argc, argv);
|
||||
ParseResult result(m_options, m_positional, m_allow_unrecognised, argc, argv);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1697,7 +1711,15 @@ ParseResult::parse(int& argc, char**& argv)
|
||||
|
||||
if (iter == m_options.end())
|
||||
{
|
||||
throw option_not_exists_exception(name);
|
||||
if (m_allow_unrecognised)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
//error
|
||||
throw option_not_exists_exception(name);
|
||||
}
|
||||
}
|
||||
|
||||
auto value = iter->second;
|
||||
@ -1726,7 +1748,19 @@ ParseResult::parse(int& argc, char**& argv)
|
||||
|
||||
if (iter == m_options.end())
|
||||
{
|
||||
throw option_not_exists_exception(name);
|
||||
if (m_allow_unrecognised)
|
||||
{
|
||||
// keep unrecognised options in argument list, skip to next argument
|
||||
argv[nextKeep] = argv[current];
|
||||
++nextKeep;
|
||||
++current;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
//error
|
||||
throw option_not_exists_exception(name);
|
||||
}
|
||||
}
|
||||
|
||||
auto opt = iter->second;
|
||||
|
||||
@ -37,7 +37,9 @@ int main(int argc, char* argv[])
|
||||
|
||||
bool apple = false;
|
||||
|
||||
options.add_options()
|
||||
options
|
||||
.allow_unrecognised_options()
|
||||
.add_options()
|
||||
("a,apple", "an apple", cxxopts::value<bool>(apple))
|
||||
("b,bob", "Bob")
|
||||
("t,true", "True", cxxopts::value<bool>()->default_value("true"))
|
||||
|
||||
@ -473,3 +473,33 @@ TEST_CASE("std::optional", "[optional]") {
|
||||
CHECK(*optional == "foo");
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Unrecognised options", "[options]") {
|
||||
cxxopts::Options options("unknown_options", " - test unknown options");
|
||||
|
||||
options.add_options()
|
||||
("long", "a long option")
|
||||
("s,short", "a short option");
|
||||
|
||||
Argv av({
|
||||
"unknown_options",
|
||||
"--unknown",
|
||||
"--long",
|
||||
"-su",
|
||||
"--another_unknown",
|
||||
});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
SECTION("Default behaviour") {
|
||||
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception);
|
||||
}
|
||||
|
||||
SECTION("After allowing unrecognised options") {
|
||||
options.allow_unrecognised_options();
|
||||
CHECK_NOTHROW(options.parse(argc, argv));
|
||||
REQUIRE(argc == 3);
|
||||
CHECK_THAT(argv[1], Catch::Equals("--unknown"));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user