Commit 133c7d5075b6321915692c1de4b03c4254e73476

Authored by Henry Fredrick Schreiner
Committed by Henry Schreiner
1 parent 88c680a1

Allow suggestions for number of args

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) {
... ...