Commit 3d309dc0be32601ea98c6c36e5969a982fcb869e
1 parent
d28c230e
Adding fail if required values missing
Showing
5 changed files
with
37 additions
and
5 deletions
examples/simple.cpp
| ... | ... | @@ -8,7 +8,10 @@ int main(int argc, char **argv) { |
| 8 | 8 | CLI::Option *opt = app.add_option("-f,--file,file", file, "File name"); |
| 9 | 9 | |
| 10 | 10 | int count; |
| 11 | - CLI::Option *copt = app.add_flag("-c,--count", count, "Counter"); | |
| 11 | + CLI::Option *copt = app.add_option("-c,--count", count, "Counter"); | |
| 12 | + | |
| 13 | + int v; | |
| 14 | + CLI::Option *flag = app.add_flag("--flag", v, "Some flag that can be passed multiple times"); | |
| 12 | 15 | |
| 13 | 16 | double value; // = 3.14; |
| 14 | 17 | app.add_option("-d,--double", value, "Some Value"); |
| ... | ... | @@ -19,6 +22,7 @@ int main(int argc, char **argv) { |
| 19 | 22 | << ", opt count: " << opt->count() << std::endl; |
| 20 | 23 | std::cout << "Working on count: " << count << ", direct count: " << app.count("--count") |
| 21 | 24 | << ", opt count: " << copt->count() << std::endl; |
| 25 | + std::cout << "Recieved flag: " << v << " (" << flag->count() << ") times\n"; | |
| 22 | 26 | std::cout << "Some value: " << value << std::endl; |
| 23 | 27 | |
| 24 | 28 | return 0; | ... | ... |
include/CLI/App.hpp
| ... | ... | @@ -1196,7 +1196,9 @@ class App { |
| 1196 | 1196 | if(num_left_over > 0) { |
| 1197 | 1197 | args = remaining(false); |
| 1198 | 1198 | std::reverse(std::begin(args), std::end(args)); |
| 1199 | - throw ExtrasError("[" + detail::rjoin(args, " ") + "]"); | |
| 1199 | + throw ExtrasError((args.size() > 1 ? "The following argument was not expected: " | |
| 1200 | + : "The following arguments were not expected: ") + | |
| 1201 | + detail::rjoin(args, " ")); | |
| 1200 | 1202 | } |
| 1201 | 1203 | } |
| 1202 | 1204 | } |
| ... | ... | @@ -1415,7 +1417,7 @@ class App { |
| 1415 | 1417 | args.pop_back(); |
| 1416 | 1418 | already_ate_one = true; |
| 1417 | 1419 | } |
| 1418 | - } else | |
| 1420 | + } else { | |
| 1419 | 1421 | while(num > 0 && !args.empty()) { |
| 1420 | 1422 | num--; |
| 1421 | 1423 | std::string current_ = args.back(); |
| ... | ... | @@ -1424,6 +1426,12 @@ class App { |
| 1424 | 1426 | parse_order_.push_back(op.get()); |
| 1425 | 1427 | } |
| 1426 | 1428 | |
| 1429 | + if(num > 0) { | |
| 1430 | + throw RequiredError(op->single_name() + ": " + std::to_string(num) + " required " + | |
| 1431 | + op->get_type_name() + " missing"); | |
| 1432 | + } | |
| 1433 | + } | |
| 1434 | + | |
| 1427 | 1435 | if(!rest.empty()) { |
| 1428 | 1436 | rest = "-" + rest; |
| 1429 | 1437 | args.push_back(rest); |
| ... | ... | @@ -1499,6 +1507,10 @@ class App { |
| 1499 | 1507 | parse_order_.push_back(op.get()); |
| 1500 | 1508 | args.pop_back(); |
| 1501 | 1509 | } |
| 1510 | + if(num > 0) { | |
| 1511 | + throw RequiredError(op->single_name() + ": " + std::to_string(num) + " required " + | |
| 1512 | + op->get_type_name() + " missing"); | |
| 1513 | + } | |
| 1502 | 1514 | } |
| 1503 | 1515 | return; |
| 1504 | 1516 | } | ... | ... |
include/CLI/Option.hpp
| ... | ... | @@ -551,6 +551,9 @@ class Option : public OptionBase<Option> { |
| 551 | 551 | /// Set the type name displayed on this option |
| 552 | 552 | void set_type_name(std::string val) { typeval_ = val; } |
| 553 | 553 | |
| 554 | + /// Get the typename for this option | |
| 555 | + std::string get_type_name() const { return typeval_; } | |
| 556 | + | |
| 554 | 557 | ///@} |
| 555 | 558 | |
| 556 | 559 | protected: | ... | ... |
tests/AppTest.cpp
| ... | ... | @@ -230,6 +230,19 @@ TEST_F(TApp, TakeLastOpt) { |
| 230 | 230 | EXPECT_EQ(str, "two"); |
| 231 | 231 | } |
| 232 | 232 | |
| 233 | +TEST_F(TApp, MissingValueNonRequiredOpt) { | |
| 234 | + int count; | |
| 235 | + app.add_option("-c,--count", count); | |
| 236 | + | |
| 237 | + args = {"-c"}; | |
| 238 | + EXPECT_ANY_THROW(run()); | |
| 239 | + | |
| 240 | + app.reset(); | |
| 241 | + | |
| 242 | + args = {"--count"}; | |
| 243 | + EXPECT_ANY_THROW(run()); | |
| 244 | +} | |
| 245 | + | |
| 233 | 246 | TEST_F(TApp, RequiredOptsSingle) { |
| 234 | 247 | |
| 235 | 248 | std::string str; |
| ... | ... | @@ -1189,7 +1202,7 @@ TEST_F(TApp, OrderedModifingTransforms) { |
| 1189 | 1202 | TEST_F(TApp, ThrowingTransform) { |
| 1190 | 1203 | std::string val; |
| 1191 | 1204 | auto m = app.add_option("-m,--mess", val); |
| 1192 | - m->transform([](std::string x) -> std::string { throw CLI::ValidationError("My Message"); }); | |
| 1205 | + m->transform([](std::string) -> std::string { throw CLI::ValidationError("My Message"); }); | |
| 1193 | 1206 | |
| 1194 | 1207 | EXPECT_NO_THROW(run()); |
| 1195 | 1208 | app.reset(); | ... | ... |