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,7 +15,7 @@ int main(int argc, char **argv) {
15 } 15 }
16 16
17 std::vector<std::string> more_comms = app.remaining(); 17 std::vector<std::string> more_comms = app.remaining();
18 - 18 +
19 std::cout << "Prefix:"; 19 std::cout << "Prefix:";
20 for(int v : vals) 20 for(int v : vals)
21 std::cout << v << ":"; 21 std::cout << v << ":";
include/CLI/App.hpp
@@ -584,7 +584,8 @@ class App { @@ -584,7 +584,8 @@ class App {
584 App *add_subcommand(std::string name, std::string description = "", bool help = true) { 584 App *add_subcommand(std::string name, std::string description = "", bool help = true) {
585 subcommands_.emplace_back(new App(description, help, detail::dummy)); 585 subcommands_.emplace_back(new App(description, help, detail::dummy));
586 subcommands_.back()->name_ = name; 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 subcommands_.back()->parent_ = this; 589 subcommands_.back()->parent_ = this;
589 subcommands_.back()->ignore_case_ = ignore_case_; 590 subcommands_.back()->ignore_case_ = ignore_case_;
590 subcommands_.back()->fallthrough_ = fallthrough_; 591 subcommands_.back()->fallthrough_ = fallthrough_;
@@ -863,23 +864,34 @@ class App { @@ -863,23 +864,34 @@ class App {
863 const std::vector<Option *> &parse_order() const { return parse_order_; } 864 const std::vector<Option *> &parse_order() const { return parse_order_; }
864 865
865 /// This retuns the missing options from the current subcommand 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 std::vector<std::string> miss_list; 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 miss_list.push_back(std::get<1>(miss)); 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 return miss_list; 878 return miss_list;
872 } 879 }
873 - 880 +
874 /// This returns the number of remaining options, minus the -- seperator 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 protected: 897 protected:
@@ -896,13 +908,6 @@ class App { @@ -896,13 +908,6 @@ class App {
896 app->_validate(); 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 /// Internal function to run (App) callback, top down 911 /// Internal function to run (App) callback, top down
907 void run_callback() { 912 void run_callback() {
908 pre_callback(); 913 pre_callback();
@@ -1028,14 +1033,14 @@ class App { @@ -1028,14 +1033,14 @@ class App {
1028 1033
1029 // Convert missing (pairs) to extras (string only) 1034 // Convert missing (pairs) to extras (string only)
1030 if(parent_ == nullptr) { 1035 if(parent_ == nullptr) {
1031 - args = remaining(); 1036 + args = remaining(true);
1032 std::reverse(std::begin(args), std::end(args)); 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 /// Parse one ini param, return false if not found in any subcommand, remove if it is 1046 /// Parse one ini param, return false if not found in any subcommand, remove if it is
@@ -1102,7 +1107,7 @@ class App { @@ -1102,7 +1107,7 @@ class App {
1102 detail::Classifer classifer = positional_only ? detail::Classifer::NONE : _recognize(args.back()); 1107 detail::Classifer classifer = positional_only ? detail::Classifer::NONE : _recognize(args.back());
1103 switch(classifer) { 1108 switch(classifer) {
1104 case detail::Classifer::POSITIONAL_MARK: 1109 case detail::Classifer::POSITIONAL_MARK:
1105 - missing()->emplace_back(classifer, args.back()); 1110 + missing_.emplace_back(classifer, args.back());
1106 args.pop_back(); 1111 args.pop_back();
1107 positional_only = true; 1112 positional_only = true;
1108 break; 1113 break;
@@ -1154,11 +1159,11 @@ class App { @@ -1154,11 +1159,11 @@ class App {
1154 return parent_->_parse_positional(args); 1159 return parent_->_parse_positional(args);
1155 else { 1160 else {
1156 args.pop_back(); 1161 args.pop_back();
1157 - missing()->emplace_back(detail::Classifer::NONE, positional); 1162 + missing_.emplace_back(detail::Classifer::NONE, positional);
1158 1163
1159 if(prefix_command_) { 1164 if(prefix_command_) {
1160 while(!args.empty()) { 1165 while(!args.empty()) {
1161 - missing()->emplace_back(detail::Classifer::NONE, args.back()); 1166 + missing_.emplace_back(detail::Classifer::NONE, args.back());
1162 args.pop_back(); 1167 args.pop_back();
1163 } 1168 }
1164 } 1169 }
@@ -1204,7 +1209,7 @@ class App { @@ -1204,7 +1209,7 @@ class App {
1204 // Otherwise, add to missing 1209 // Otherwise, add to missing
1205 else { 1210 else {
1206 args.pop_back(); 1211 args.pop_back();
1207 - missing()->emplace_back(detail::Classifer::SHORT, current); 1212 + missing_.emplace_back(detail::Classifer::SHORT, current);
1208 return; 1213 return;
1209 } 1214 }
1210 } 1215 }
@@ -1268,7 +1273,7 @@ class App { @@ -1268,7 +1273,7 @@ class App {
1268 // Otherwise, add to missing 1273 // Otherwise, add to missing
1269 else { 1274 else {
1270 args.pop_back(); 1275 args.pop_back();
1271 - missing()->emplace_back(detail::Classifer::LONG, current); 1276 + missing_.emplace_back(detail::Classifer::LONG, current);
1272 return; 1277 return;
1273 } 1278 }
1274 } 1279 }
tests/AppTest.cpp
@@ -917,7 +917,7 @@ TEST_F(TApp, AllowExtras) { @@ -917,7 +917,7 @@ TEST_F(TApp, AllowExtras) {
917 EXPECT_FALSE(val); 917 EXPECT_FALSE(val);
918 918
919 args = {"-x", "-f"}; 919 args = {"-x", "-f"};
920 - 920 +
921 EXPECT_NO_THROW(run()); 921 EXPECT_NO_THROW(run());
922 EXPECT_TRUE(val); 922 EXPECT_TRUE(val);
923 EXPECT_EQ(app.remaining(), std::vector<std::string>({"-x"})); 923 EXPECT_EQ(app.remaining(), std::vector<std::string>({"-x"}));
tests/SubcommandTest.cpp
@@ -291,20 +291,18 @@ TEST_F(TApp, SubComExtras) { @@ -291,20 +291,18 @@ TEST_F(TApp, SubComExtras) {
291 EXPECT_EQ(sub->remaining(), std::vector<std::string>()); 291 EXPECT_EQ(sub->remaining(), std::vector<std::string>());
292 292
293 app.reset(); 293 app.reset();
294 - 294 +
295 args = {"extra1", "extra2", "sub"}; 295 args = {"extra1", "extra2", "sub"};
296 run(); 296 run();
297 EXPECT_EQ(app.remaining(), std::vector<std::string>({"extra1", "extra2"})); 297 EXPECT_EQ(app.remaining(), std::vector<std::string>({"extra1", "extra2"}));
298 EXPECT_EQ(sub->remaining(), std::vector<std::string>()); 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 TEST_F(TApp, Required1SubCom) { 308 TEST_F(TApp, Required1SubCom) {