Commit 59b6de2550e66716dbad95a1db3325a702132361

Authored by Henry Fredrick Schreiner
Committed by Henry Schreiner
1 parent cb7c3ff8

Dropping missing(), now implemented correctly

examples/prefix_command.cpp
... ... @@ -15,7 +15,7 @@ int main(int argc, char **argv) {
15 15 }
16 16  
17 17 std::vector<std::string> more_comms = app.remaining();
18   -
  18 +
19 19 std::cout << "Prefix:";
20 20 for(int v : vals)
21 21 std::cout << v << ":";
... ...
include/CLI/App.hpp
... ... @@ -584,7 +584,8 @@ class App {
584 584 App *add_subcommand(std::string name, std::string description = "", bool help = true) {
585 585 subcommands_.emplace_back(new App(description, help, detail::dummy));
586 586 subcommands_.back()->name_ = name;
587   - subcommands_.back()->allow_extras();
  587 + subcommands_.back()->allow_extras_ = allow_extras_;
  588 + subcommands_.back()->prefix_command_ = prefix_command_;
588 589 subcommands_.back()->parent_ = this;
589 590 subcommands_.back()->ignore_case_ = ignore_case_;
590 591 subcommands_.back()->fallthrough_ = fallthrough_;
... ... @@ -863,23 +864,34 @@ class App {
863 864 const std::vector<Option *> &parse_order() const { return parse_order_; }
864 865  
865 866 /// This retuns the missing options from the current subcommand
866   - std::vector<std::string> remaining() const {
  867 + std::vector<std::string> remaining(bool recurse = false) const {
867 868 std::vector<std::string> miss_list;
868   - for(const std::pair<detail::Classifer, std::string>& miss : missing_) {
  869 + for(const std::pair<detail::Classifer, std::string> &miss : missing_) {
869 870 miss_list.push_back(std::get<1>(miss));
870 871 }
  872 + if(recurse) {
  873 + for(const App_p &sub : subcommands_) {
  874 + std::vector<std::string> output = sub->remaining(recurse);
  875 + miss_list.assign(std::begin(output), std::end(output));
  876 + }
  877 + }
871 878 return miss_list;
872 879 }
873   -
  880 +
874 881 /// This returns the number of remaining options, minus the -- seperator
875   - size_t remaining_size() const {
876   - return std::count_if(
877   - std::begin(missing_), std::end(missing_),
878   - [](const std::pair<detail::Classifer, std::string> &val) {
879   - return val.first != detail::Classifer::POSITIONAL_MARK;
880   - });
  882 + size_t remaining_size(bool recurse = false) const {
  883 + size_t count = std::count_if(
  884 + std::begin(missing_), std::end(missing_), [](const std::pair<detail::Classifer, std::string> &val) {
  885 + return val.first != detail::Classifer::POSITIONAL_MARK;
  886 + });
  887 + if(recurse) {
  888 + for(const App_p &sub : subcommands_) {
  889 + count += sub->remaining_size(recurse);
  890 + }
  891 + }
  892 + return count;
881 893 }
882   -
  894 +
883 895 ///@}
884 896  
885 897 protected:
... ... @@ -896,13 +908,6 @@ class App {
896 908 app->_validate();
897 909 }
898 910  
899   - /// Return missing from the master
900   - missing_t *missing() {
901   - if(parent_ != nullptr)
902   - return parent_->missing();
903   - return &missing_;
904   - }
905   -
906 911 /// Internal function to run (App) callback, top down
907 912 void run_callback() {
908 913 pre_callback();
... ... @@ -1028,14 +1033,14 @@ class App {
1028 1033  
1029 1034 // Convert missing (pairs) to extras (string only)
1030 1035 if(parent_ == nullptr) {
1031   - args = remaining();
  1036 + args = remaining(true);
1032 1037 std::reverse(std::begin(args), std::end(args));
  1038 + }
1033 1039  
1034   - size_t num_left_over = remaining_size();
  1040 + size_t num_left_over = remaining_size();
1035 1041  
1036   - if(num_left_over > 0 && !(allow_extras_ || prefix_command_))
1037   - throw ExtrasError("[" + detail::rjoin(args, " ") + "]");
1038   - }
  1042 + if(num_left_over > 0 && !(allow_extras_ || prefix_command_))
  1043 + throw ExtrasError("[" + detail::rjoin(args, " ") + "]");
1039 1044 }
1040 1045  
1041 1046 /// Parse one ini param, return false if not found in any subcommand, remove if it is
... ... @@ -1102,7 +1107,7 @@ class App {
1102 1107 detail::Classifer classifer = positional_only ? detail::Classifer::NONE : _recognize(args.back());
1103 1108 switch(classifer) {
1104 1109 case detail::Classifer::POSITIONAL_MARK:
1105   - missing()->emplace_back(classifer, args.back());
  1110 + missing_.emplace_back(classifer, args.back());
1106 1111 args.pop_back();
1107 1112 positional_only = true;
1108 1113 break;
... ... @@ -1154,11 +1159,11 @@ class App {
1154 1159 return parent_->_parse_positional(args);
1155 1160 else {
1156 1161 args.pop_back();
1157   - missing()->emplace_back(detail::Classifer::NONE, positional);
  1162 + missing_.emplace_back(detail::Classifer::NONE, positional);
1158 1163  
1159 1164 if(prefix_command_) {
1160 1165 while(!args.empty()) {
1161   - missing()->emplace_back(detail::Classifer::NONE, args.back());
  1166 + missing_.emplace_back(detail::Classifer::NONE, args.back());
1162 1167 args.pop_back();
1163 1168 }
1164 1169 }
... ... @@ -1204,7 +1209,7 @@ class App {
1204 1209 // Otherwise, add to missing
1205 1210 else {
1206 1211 args.pop_back();
1207   - missing()->emplace_back(detail::Classifer::SHORT, current);
  1212 + missing_.emplace_back(detail::Classifer::SHORT, current);
1208 1213 return;
1209 1214 }
1210 1215 }
... ... @@ -1268,7 +1273,7 @@ class App {
1268 1273 // Otherwise, add to missing
1269 1274 else {
1270 1275 args.pop_back();
1271   - missing()->emplace_back(detail::Classifer::LONG, current);
  1276 + missing_.emplace_back(detail::Classifer::LONG, current);
1272 1277 return;
1273 1278 }
1274 1279 }
... ...
tests/AppTest.cpp
... ... @@ -917,7 +917,7 @@ TEST_F(TApp, AllowExtras) {
917 917 EXPECT_FALSE(val);
918 918  
919 919 args = {"-x", "-f"};
920   -
  920 +
921 921 EXPECT_NO_THROW(run());
922 922 EXPECT_TRUE(val);
923 923 EXPECT_EQ(app.remaining(), std::vector<std::string>({"-x"}));
... ...
tests/SubcommandTest.cpp
... ... @@ -291,20 +291,18 @@ TEST_F(TApp, SubComExtras) {
291 291 EXPECT_EQ(sub->remaining(), std::vector<std::string>());
292 292  
293 293 app.reset();
294   -
  294 +
295 295 args = {"extra1", "extra2", "sub"};
296 296 run();
297 297 EXPECT_EQ(app.remaining(), std::vector<std::string>({"extra1", "extra2"}));
298 298 EXPECT_EQ(sub->remaining(), std::vector<std::string>());
299   -
300   - app.reset();
301   -
302   - //args = {"sub", "extra"};
303   - //run();
304   - //EXPECT_EQ(app.remaining(), std::vector<std::string>());
305   - //EXPECT_EQ(sub->remaining(), std::vector<std::string>({"extra"}));
306 299  
  300 + app.reset();
307 301  
  302 + // args = {"sub", "extra"};
  303 + // run();
  304 + // EXPECT_EQ(app.remaining(), std::vector<std::string>());
  305 + // EXPECT_EQ(sub->remaining(), std::vector<std::string>({"extra"}));
308 306 }
309 307  
310 308 TEST_F(TApp, Required1SubCom) {
... ...