Commit 133c7d5075b6321915692c1de4b03c4254e73476
Committed by
Henry Schreiner
1 parent
88c680a1
Allow suggestions for number of args
Showing
3 changed files
with
32 additions
and
12 deletions
include/CLI/App.hpp
| ... | ... | @@ -1371,10 +1371,10 @@ class App { |
| 1371 | 1371 | } |
| 1372 | 1372 | |
| 1373 | 1373 | // Unlimited vector parser |
| 1374 | - if(num == -1) { | |
| 1375 | - bool already_ate_one = false; // Make sure we always eat one | |
| 1374 | + if(num < 0) { | |
| 1375 | + int collected = 0; // Make sure we always eat the minimum | |
| 1376 | 1376 | while(!args.empty() && _recognize(args.back()) == detail::Classifer::NONE) { |
| 1377 | - if(already_ate_one) { | |
| 1377 | + if(collected >= -num) { | |
| 1378 | 1378 | // We could break here for allow extras, but we don't |
| 1379 | 1379 | |
| 1380 | 1380 | // If any positionals remain, don't keep eating |
| ... | ... | @@ -1390,8 +1390,11 @@ class App { |
| 1390 | 1390 | op->add_result(args.back()); |
| 1391 | 1391 | parse_order_.push_back(op.get()); |
| 1392 | 1392 | args.pop_back(); |
| 1393 | - already_ate_one = true; | |
| 1393 | + collected++; | |
| 1394 | 1394 | } |
| 1395 | + //if(collected < -num) | |
| 1396 | + // throw ArgumentMismatch(op->single_name() + ": At least " + std::to_string(-num) + " required"); | |
| 1397 | + | |
| 1395 | 1398 | } else { |
| 1396 | 1399 | while(num > 0 && !args.empty()) { |
| 1397 | 1400 | num--; |
| ... | ... | @@ -1453,11 +1456,11 @@ class App { |
| 1453 | 1456 | } else if(num == 0) { |
| 1454 | 1457 | op->add_result(""); |
| 1455 | 1458 | parse_order_.push_back(op.get()); |
| 1456 | - } else if(num == -1) { | |
| 1459 | + } else if(num < 0) { | |
| 1457 | 1460 | // Unlimited vector parser |
| 1458 | - bool already_ate_one = false; // Make sure we always eat one | |
| 1461 | + int collected = 0; // Make sure we always eat the minimum | |
| 1459 | 1462 | while(!args.empty() && _recognize(args.back()) == detail::Classifer::NONE) { |
| 1460 | - if(already_ate_one) { | |
| 1463 | + if(collected >= -num) { | |
| 1461 | 1464 | // We could break here for allow extras, but we don't |
| 1462 | 1465 | |
| 1463 | 1466 | // If any positionals remain, don't keep eating |
| ... | ... | @@ -1473,8 +1476,10 @@ class App { |
| 1473 | 1476 | op->add_result(args.back()); |
| 1474 | 1477 | parse_order_.push_back(op.get()); |
| 1475 | 1478 | args.pop_back(); |
| 1476 | - already_ate_one = true; | |
| 1479 | + collected++; | |
| 1477 | 1480 | } |
| 1481 | + //if(collected < -num) | |
| 1482 | + // throw ArgumentMismatch(op->single_name() + ": At least " + std::to_string(-num) + " required"); | |
| 1478 | 1483 | } else { |
| 1479 | 1484 | while(num > 0 && !args.empty()) { |
| 1480 | 1485 | num--; | ... | ... |
include/CLI/Error.hpp
| ... | ... | @@ -183,8 +183,8 @@ class ExcludesError : public ParseError { |
| 183 | 183 | class ExtrasError : public ParseError { |
| 184 | 184 | CLI11_ERROR_DEF(ParseError, ExtrasError) |
| 185 | 185 | ExtrasError(std::vector<std::string> args) |
| 186 | - : ExtrasError((args.size() > 1 ? "The following argument was not expected: " | |
| 187 | - : "The following arguments were not expected: ") + | |
| 186 | + : ExtrasError((args.size() > 1 ? "The following arguments were not expected: " | |
| 187 | + : "The following argument was not expected: ") + | |
| 188 | 188 | detail::rjoin(args, " "), |
| 189 | 189 | ExitCodes::ExtrasError) {} |
| 190 | 190 | }; | ... | ... |
tests/AppTest.cpp
| ... | ... | @@ -235,12 +235,27 @@ TEST_F(TApp, MissingValueNonRequiredOpt) { |
| 235 | 235 | app.add_option("-c,--count", count); |
| 236 | 236 | |
| 237 | 237 | args = {"-c"}; |
| 238 | - EXPECT_ANY_THROW(run()); | |
| 238 | + EXPECT_THROW(run(), CLI::ArgumentMismatch); | |
| 239 | 239 | |
| 240 | 240 | app.reset(); |
| 241 | 241 | |
| 242 | 242 | args = {"--count"}; |
| 243 | - EXPECT_ANY_THROW(run()); | |
| 243 | + EXPECT_THROW(run(), CLI::ArgumentMismatch); | |
| 244 | +} | |
| 245 | + | |
| 246 | +TEST_F(TApp, MissingValueMoreThan) { | |
| 247 | + std::vector<int> vals1; | |
| 248 | + std::vector<int> vals2; | |
| 249 | + app.add_option("-v", vals1)->expected(-2); | |
| 250 | + app.add_option("--vals", vals2)->expected(-2); | |
| 251 | + | |
| 252 | + args = {"-v", "2"}; | |
| 253 | + EXPECT_THROW(run(), CLI::ArgumentMismatch); | |
| 254 | + | |
| 255 | + app.reset(); | |
| 256 | + | |
| 257 | + args = {"--vals","4"}; | |
| 258 | + EXPECT_THROW(run(), CLI::ArgumentMismatch); | |
| 244 | 259 | } |
| 245 | 260 | |
| 246 | 261 | TEST_F(TApp, NotRequiredOptsSingle) { | ... | ... |