Commit 5da5d67111506a6661bb791b7469a0da0a696a82
1 parent
48e265dc
Throw exception on invalid positional argument
Fixes #169. It seems reasonable to throw an exception when an attempt is made to parse into positional parameters that don't exist.
Showing
3 changed files
with
21 additions
and
0 deletions
CHANGELOG.md
| @@ -13,6 +13,7 @@ options. The project adheres to semantic versioning. | @@ -13,6 +13,7 @@ options. The project adheres to semantic versioning. | ||
| 13 | ### Added | 13 | ### Added |
| 14 | 14 | ||
| 15 | * Iterator inputs to `parse_positional`. | 15 | * Iterator inputs to `parse_positional`. |
| 16 | +* Throw an exception if the option in `parse_positional` doesn't exist. | ||
| 16 | 17 | ||
| 17 | ### Bug Fixes | 18 | ### Bug Fixes |
| 18 | 19 |
include/cxxopts.hpp
| @@ -1659,6 +1659,10 @@ ParseResult::consume_positional(std::string a) | @@ -1659,6 +1659,10 @@ ParseResult::consume_positional(std::string a) | ||
| 1659 | return true; | 1659 | return true; |
| 1660 | } | 1660 | } |
| 1661 | } | 1661 | } |
| 1662 | + else | ||
| 1663 | + { | ||
| 1664 | + throw option_not_exists_exception(*m_next_positional); | ||
| 1665 | + } | ||
| 1662 | ++m_next_positional; | 1666 | ++m_next_positional; |
| 1663 | } | 1667 | } |
| 1664 | 1668 |
test/options.cpp
| @@ -216,6 +216,22 @@ TEST_CASE("No positional with extras", "[positional]") | @@ -216,6 +216,22 @@ TEST_CASE("No positional with extras", "[positional]") | ||
| 216 | CHECK(argv[1] == std::string("a")); | 216 | CHECK(argv[1] == std::string("a")); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | +TEST_CASE("Positional not valid", "[positional]") { | ||
| 220 | + cxxopts::Options options("positional_invalid", "invalid positional argument"); | ||
| 221 | + options.add_options() | ||
| 222 | + ("long", "a long option", cxxopts::value<std::string>()) | ||
| 223 | + ; | ||
| 224 | + | ||
| 225 | + options.parse_positional("something"); | ||
| 226 | + | ||
| 227 | + Argv av({"foobar", "bar", "baz"}); | ||
| 228 | + | ||
| 229 | + char** argv = av.argv(); | ||
| 230 | + auto argc = av.argc(); | ||
| 231 | + | ||
| 232 | + CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception); | ||
| 233 | +} | ||
| 234 | + | ||
| 219 | TEST_CASE("Empty with implicit value", "[implicit]") | 235 | TEST_CASE("Empty with implicit value", "[implicit]") |
| 220 | { | 236 | { |
| 221 | cxxopts::Options options("empty_implicit", "doesn't handle empty"); | 237 | cxxopts::Options options("empty_implicit", "doesn't handle empty"); |