CLI11  1.9.0
App.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 // Distributed under the 3-Clause BSD License. See accompanying
4 // file LICENSE or https://github.com/CLIUtils/CLI11 for details.
5 
6 #include <algorithm>
7 #include <functional>
8 #include <iostream>
9 #include <iterator>
10 #include <memory>
11 #include <numeric>
12 #include <sstream>
13 #include <string>
14 #include <utility>
15 #include <vector>
16 
17 // CLI Library includes
18 #include "CLI/ConfigFwd.hpp"
19 #include "CLI/Error.hpp"
20 #include "CLI/FormatterFwd.hpp"
21 #include "CLI/Macros.hpp"
22 #include "CLI/Option.hpp"
23 #include "CLI/Split.hpp"
24 #include "CLI/StringTools.hpp"
25 #include "CLI/TypeTools.hpp"
26 
27 namespace CLI {
28 
29 #ifndef CLI11_PARSE
30 #define CLI11_PARSE(app, argc, argv) \
31  try { \
32  (app).parse((argc), (argv)); \
33  } catch(const CLI::ParseError &e) { \
34  return (app).exit(e); \
35  }
36 #endif
37 
38 namespace detail {
40 struct AppFriend;
41 } // namespace detail
42 
43 namespace FailureMessage {
44 std::string simple(const App *app, const Error &e);
45 std::string help(const App *app, const Error &e);
46 } // namespace FailureMessage
47 
49 
50 enum class config_extras_mode : char { error = 0, ignore, capture };
51 
52 class App;
53 
54 using App_p = std::shared_ptr<App>;
55 
56 class Option_group;
58 
61 class App {
62  friend Option;
63  friend detail::AppFriend;
64 
65  protected:
66  // This library follows the Google style guide for member names ending in underscores
67 
70 
72  std::string name_{};
73 
75  std::string description_{};
76 
78  bool allow_extras_{false};
79 
83 
85  bool prefix_command_{false};
86 
88  bool has_automatic_name_{false};
89 
91  bool required_{false};
92 
94  bool disabled_{false};
95 
97  bool pre_parse_called_{false};
98 
101  bool immediate_callback_{false};
102 
104  std::function<void(std::size_t)> pre_parse_callback_{};
105 
107  std::function<void()> parse_complete_callback_{};
109  std::function<void()> final_callback_{};
110 
114 
117 
119  std::vector<Option_p> options_{};
120 
124 
126  std::string footer_{};
127 
129  std::function<std::string()> footer_callback_{};
130 
132  Option *help_ptr_{nullptr};
133 
136 
138  std::shared_ptr<FormatterBase> formatter_{new Formatter()};
139 
141  std::function<std::string(const App *, const Error &e)> failure_message_{FailureMessage::simple};
142 
146 
147  using missing_t = std::vector<std::pair<detail::Classifier, std::string>>;
148 
153 
155  std::vector<Option *> parse_order_{};
156 
158  std::vector<App *> parsed_subcommands_{};
159 
161  std::set<App *> exclude_subcommands_{};
162 
165  std::set<Option *> exclude_options_{};
166 
169  std::set<App *> need_subcommands_{};
170 
173  std::set<Option *> need_options_{};
174 
178 
180  std::vector<App_p> subcommands_{};
181 
183  bool ignore_case_{false};
184 
186  bool ignore_underscore_{false};
187 
189  bool fallthrough_{false};
190 
193 #ifdef _WIN32
194  true
195 #else
196  false
197 #endif
198  };
200  bool positionals_at_end_{false};
201 
202  enum class startup_mode : char { stable, enabled, disabled };
206 
208  bool configurable_{false};
209 
212 
214  App *parent_{nullptr};
215 
217  std::size_t parsed_{0};
218 
220  std::size_t require_subcommand_min_{0};
221 
223  std::size_t require_subcommand_max_{0};
224 
226  std::size_t require_option_min_{0};
227 
229  std::size_t require_option_max_{0};
230 
232  std::string group_{"Subcommands"};
233 
235  std::vector<std::string> aliases_{};
236 
240 
242  Option *config_ptr_{nullptr};
243 
245  std::shared_ptr<Config> config_formatter_{new ConfigINI()};
246 
248 
250  App(std::string app_description, std::string app_name, App *parent)
251  : name_(std::move(app_name)), description_(std::move(app_description)), parent_(parent) {
252  // Inherit if not from a nullptr
253  if(parent_ != nullptr) {
254  if(parent_->help_ptr_ != nullptr)
256  if(parent_->help_all_ptr_ != nullptr)
259 
262 
263  // INHERITABLE
275  group_ = parent_->group_;
280  }
281  }
282 
283  public:
286 
288  explicit App(std::string app_description = "", std::string app_name = "")
289  : App(app_description, app_name, nullptr) {
290  set_help_flag("-h,--help", "Print this help message and exit");
291  }
292 
293  App(const App &) = delete;
294  App &operator=(const App &) = delete;
295 
297  virtual ~App() = default;
298 
305  App *callback(std::function<void()> app_callback) {
306  if(immediate_callback_) {
307  parse_complete_callback_ = std::move(app_callback);
308  } else {
309  final_callback_ = std::move(app_callback);
310  }
311  return this;
312  }
313 
316  App *final_callback(std::function<void()> app_callback) {
317  final_callback_ = std::move(app_callback);
318  return this;
319  }
320 
323  App *parse_complete_callback(std::function<void()> pc_callback) {
324  parse_complete_callback_ = std::move(pc_callback);
325  return this;
326  }
327 
330  App *preparse_callback(std::function<void(std::size_t)> pp_callback) {
331  pre_parse_callback_ = std::move(pp_callback);
332  return this;
333  }
334 
336  App *name(std::string app_name = "") {
337 
338  if(parent_ != nullptr) {
339  auto oname = name_;
340  name_ = app_name;
341  auto &res = _compare_subcommand_names(*this, *_get_fallthrough_parent());
342  if(!res.empty()) {
343  name_ = oname;
344  throw(OptionAlreadyAdded(app_name + " conflicts with existing subcommand names"));
345  }
346  } else {
347  name_ = app_name;
348  }
349  has_automatic_name_ = false;
350  return this;
351  }
352 
354  App *alias(std::string app_name) {
355  if(!detail::valid_name_string(app_name)) {
356  throw(IncorrectConstruction("alias is not a valid name string"));
357  }
358 
359  if(parent_ != nullptr) {
360  aliases_.push_back(app_name);
361  auto &res = _compare_subcommand_names(*this, *_get_fallthrough_parent());
362  if(!res.empty()) {
363  aliases_.pop_back();
364  throw(OptionAlreadyAdded("alias already matches an existing subcommand: " + app_name));
365  }
366  } else {
367  aliases_.push_back(app_name);
368  }
369 
370  return this;
371  }
372 
374  App *allow_extras(bool allow = true) {
375  allow_extras_ = allow;
376  return this;
377  }
378 
380  App *required(bool require = true) {
381  required_ = require;
382  return this;
383  }
384 
386  App *disabled(bool disable = true) {
387  disabled_ = disable;
388  return this;
389  }
390 
392  App *disabled_by_default(bool disable = true) {
393  if(disable) {
395  } else {
397  }
398  return this;
399  }
400 
403  App *enabled_by_default(bool enable = true) {
404  if(enable) {
406  } else {
409  }
410  return this;
411  }
412 
414  App *immediate_callback(bool immediate = true) {
415  immediate_callback_ = immediate;
416  if(immediate_callback_) {
419  }
420  } else if(!(final_callback_) && parse_complete_callback_) {
422  }
423  return this;
424  }
425 
427  App *validate_positionals(bool validate = true) {
428  validate_positionals_ = validate;
429  return this;
430  }
431 
433  App *allow_config_extras(bool allow = true) {
434  if(allow) {
436  allow_extras_ = true;
437  } else {
439  }
440  return this;
441  }
442 
445  allow_config_extras_ = mode;
446  return this;
447  }
448 
450  App *prefix_command(bool allow = true) {
451  prefix_command_ = allow;
452  return this;
453  }
454 
456  App *ignore_case(bool value = true) {
457  if(value && !ignore_case_) {
458  ignore_case_ = true;
459  auto *p = (parent_ != nullptr) ? _get_fallthrough_parent() : this;
460  auto &match = _compare_subcommand_names(*this, *p);
461  if(!match.empty()) {
462  ignore_case_ = false; // we are throwing so need to be exception invariant
463  throw OptionAlreadyAdded("ignore case would cause subcommand name conflicts: " + match);
464  }
465  }
466  ignore_case_ = value;
467  return this;
468  }
469 
472  App *allow_windows_style_options(bool value = true) {
474  return this;
475  }
476 
478  App *positionals_at_end(bool value = true) {
479  positionals_at_end_ = value;
480  return this;
481  }
482 
484  App *configurable(bool value = true) {
485  configurable_ = value;
486  return this;
487  }
488 
490  App *ignore_underscore(bool value = true) {
491  if(value && !ignore_underscore_) {
492  ignore_underscore_ = true;
493  auto *p = (parent_ != nullptr) ? _get_fallthrough_parent() : this;
494  auto &match = _compare_subcommand_names(*this, *p);
495  if(!match.empty()) {
496  ignore_underscore_ = false;
497  throw OptionAlreadyAdded("ignore underscore would cause subcommand name conflicts: " + match);
498  }
499  }
500  ignore_underscore_ = value;
501  return this;
502  }
503 
505  App *formatter(std::shared_ptr<FormatterBase> fmt) {
506  formatter_ = fmt;
507  return this;
508  }
509 
511  App *formatter_fn(std::function<std::string(const App *, std::string, AppFormatMode)> fmt) {
512  formatter_ = std::make_shared<FormatterLambda>(fmt);
513  return this;
514  }
515 
517  App *config_formatter(std::shared_ptr<Config> fmt) {
518  config_formatter_ = fmt;
519  return this;
520  }
521 
523  bool parsed() const { return parsed_ > 0; }
524 
527 
531 
546  Option *add_option(std::string option_name,
547  callback_t option_callback,
548  std::string option_description = "",
549  bool defaulted = false,
550  std::function<std::string()> func = {}) {
551  Option myopt{option_name, option_description, option_callback, this};
552 
553  if(std::find_if(std::begin(options_), std::end(options_), [&myopt](const Option_p &v) {
554  return *v == myopt;
555  }) == std::end(options_)) {
556  options_.emplace_back();
557  Option_p &option = options_.back();
558  option.reset(new Option(option_name, option_description, option_callback, this));
559 
560  // Set the default string capture function
561  option->default_function(func);
562 
563  // For compatibility with CLI11 1.7 and before, capture the default string here
564  if(defaulted)
565  option->capture_default_str();
566 
567  // Transfer defaults to the new option
568  option_defaults_.copy_to(option.get());
569 
570  // Don't bother to capture if we already did
571  if(!defaulted && option->get_always_capture_default())
572  option->capture_default_str();
573 
574  return option.get();
575  }
576  // we know something matches now find what it is so we can produce more error information
577  for(auto &opt : options_) {
578  auto &matchname = opt->matching_name(myopt);
579  if(!matchname.empty()) {
580  throw(OptionAlreadyAdded("added option matched existing option name: " + matchname));
581  }
582  }
583  // this line should not be reached the above loop should trigger the throw
584  throw(OptionAlreadyAdded("added option matched existing option name")); // LCOV_EXCL_LINE
585  }
586 
588  template <typename AssignTo,
589  typename ConvertTo = AssignTo,
590  enable_if_t<!std::is_const<ConvertTo>::value, detail::enabler> = detail::dummy>
591  Option *add_option(std::string option_name,
592  AssignTo &variable,
593  std::string option_description = "",
594  bool defaulted = false) {
595 
596  auto fun = [&variable](const CLI::results_t &res) { // comment for spacing
597  return detail::lexical_conversion<AssignTo, ConvertTo>(res, variable);
598  };
599 
600  Option *opt = add_option(option_name, fun, option_description, defaulted, [&variable]() {
601  return CLI::detail::checked_to_string<AssignTo, ConvertTo>(variable);
602  });
603  opt->type_name(detail::type_name<ConvertTo>());
604  // these must be actual lvalues since (std::max) sometimes is defined in terms of references and references
605  // to structs used in the evaluation can be temporary so that would cause issues.
608  opt->type_size((std::max)(Tcount, XCcount));
611  return opt;
612  }
613 
615  template <typename T>
616  Option *add_option_function(std::string option_name,
617  const std::function<void(const T &)> &func,
618  std::string option_description = "") {
619 
620  auto fun = [func](const CLI::results_t &res) {
621  T variable;
622  bool result = detail::lexical_conversion<T, T>(res, variable);
623  if(result) {
624  func(variable);
625  }
626  return result;
627  };
628 
629  Option *opt = add_option(option_name, std::move(fun), option_description, false);
630  opt->type_name(detail::type_name<T>());
633  return opt;
634  }
635 
637  Option *add_option(std::string option_name) {
638  return add_option(option_name, CLI::callback_t(), std::string{}, false);
639  }
640 
642  template <typename T,
643  enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
645  Option *add_option(std::string option_name, T &option_description) {
646  return add_option(option_name, CLI::callback_t(), option_description, false);
647  }
648 
650  Option *set_help_flag(std::string flag_name = "", const std::string &help_description = "") {
651  // take flag_description by const reference otherwise add_flag tries to assign to help_description
652  if(help_ptr_ != nullptr) {
654  help_ptr_ = nullptr;
655  }
656 
657  // Empty name will simply remove the help flag
658  if(!flag_name.empty()) {
659  help_ptr_ = add_flag(flag_name, help_description);
660  help_ptr_->configurable(false);
661  }
662 
663  return help_ptr_;
664  }
665 
667  Option *set_help_all_flag(std::string help_name = "", const std::string &help_description = "") {
668  // take flag_description by const reference otherwise add_flag tries to assign to flag_description
669  if(help_all_ptr_ != nullptr) {
671  help_all_ptr_ = nullptr;
672  }
673 
674  // Empty name will simply remove the help all flag
675  if(!help_name.empty()) {
676  help_all_ptr_ = add_flag(help_name, help_description);
677  help_all_ptr_->configurable(false);
678  }
679 
680  return help_all_ptr_;
681  }
682 
683  private:
685  Option *_add_flag_internal(std::string flag_name, CLI::callback_t fun, std::string flag_description) {
686  Option *opt;
687  if(detail::has_default_flag_values(flag_name)) {
688  // check for default values and if it has them
689  auto flag_defaults = detail::get_default_flag_values(flag_name);
691  opt = add_option(std::move(flag_name), std::move(fun), std::move(flag_description), false);
692  for(const auto &fname : flag_defaults)
693  opt->fnames_.push_back(fname.first);
694  opt->default_flag_values_ = std::move(flag_defaults);
695  } else {
696  opt = add_option(std::move(flag_name), std::move(fun), std::move(flag_description), false);
697  }
698  // flags cannot have positional values
699  if(opt->get_positional()) {
700  auto pos_name = opt->get_name(true);
701  remove_option(opt);
702  throw IncorrectConstruction::PositionalFlag(pos_name);
703  }
705  opt->expected(0);
706  opt->required(false);
707  return opt;
708  }
709 
710  public:
712  Option *add_flag(std::string flag_name) { return _add_flag_internal(flag_name, CLI::callback_t(), std::string{}); }
713 
717  template <typename T,
718  enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
720  Option *add_flag(std::string flag_name, T &flag_description) {
721  return _add_flag_internal(flag_name, CLI::callback_t(), flag_description);
722  }
723 
726  template <typename T,
728  Option *add_flag(std::string flag_name,
729  T &flag_count,
730  std::string flag_description = "") {
731  flag_count = 0;
732  CLI::callback_t fun = [&flag_count](const CLI::results_t &res) {
733  try {
734  detail::sum_flag_vector(res, flag_count);
735  } catch(const std::invalid_argument &) {
736  return false;
737  }
738  return true;
739  };
740  return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description))
742  }
743 
746  template <typename T,
747  enable_if_t<!is_vector<T>::value && !std::is_const<T>::value &&
748  (!std::is_integral<T>::value || is_bool<T>::value) &&
749  !std::is_constructible<std::function<void(int)>, T>::value,
751  Option *add_flag(std::string flag_name,
752  T &flag_result,
753  std::string flag_description = "") {
754 
755  CLI::callback_t fun = [&flag_result](const CLI::results_t &res) {
756  return CLI::detail::lexical_cast(res[0], flag_result);
757  };
758  return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description))->run_callback_for_default();
759  }
760 
762  template <typename T,
763  enable_if_t<!std::is_assignable<std::function<void(int64_t)>, T>::value, detail::enabler> = detail::dummy>
764  Option *add_flag(std::string flag_name,
765  std::vector<T> &flag_results,
766  std::string flag_description = "") {
767  CLI::callback_t fun = [&flag_results](const CLI::results_t &res) {
768  bool retval = true;
769  for(const auto &elem : res) {
770  flag_results.emplace_back();
771  retval &= detail::lexical_cast(elem, flag_results.back());
772  }
773  return retval;
774  };
775  return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description))
778  }
779 
781  Option *add_flag_callback(std::string flag_name,
782  std::function<void(void)> function,
783  std::string flag_description = "") {
784 
785  CLI::callback_t fun = [function](const CLI::results_t &res) {
786  bool trigger{false};
787  auto result = CLI::detail::lexical_cast(res[0], trigger);
788  if(result && trigger) {
789  function();
790  }
791  return result;
792  };
793  return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
794  }
795 
797  Option *add_flag_function(std::string flag_name,
798  std::function<void(int64_t)> function,
799  std::string flag_description = "") {
800 
801  CLI::callback_t fun = [function](const CLI::results_t &res) {
802  int64_t flag_count = 0;
803  detail::sum_flag_vector(res, flag_count);
804  function(flag_count);
805  return true;
806  };
807  return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description))
809  }
810 
811 #ifdef CLI11_CPP14
812  Option *add_flag(std::string flag_name,
814  std::function<void(int64_t)> function,
815  std::string flag_description = "") {
816  return add_flag_function(std::move(flag_name), std::move(function), std::move(flag_description));
817  }
818 #endif
819 
821  template <typename T>
822  Option *add_set(std::string option_name,
823  T &member,
824  std::set<T> options,
825  std::string option_description = "") {
826 
827  Option *opt = add_option(option_name, member, std::move(option_description));
828  opt->check(IsMember{options});
829  return opt;
830  }
831 
833  template <typename T>
834  Option *add_mutable_set(std::string option_name,
835  T &member,
836  const std::set<T> &options,
837  std::string option_description = "") {
838 
839  Option *opt = add_option(option_name, member, std::move(option_description));
840  opt->check(IsMember{&options});
841  return opt;
842  }
843 
845  template <typename T>
846  Option *add_set(std::string option_name,
847  T &member,
848  std::set<T> options,
849  std::string option_description,
850  bool defaulted) {
851 
852  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
853  opt->check(IsMember{options});
854  return opt;
855  }
856 
858  template <typename T>
859  Option *add_mutable_set(std::string option_name,
860  T &member,
861  const std::set<T> &options,
862  std::string option_description,
863  bool defaulted) {
864 
865  Option *opt = add_option(option_name, member, std::move(option_description), defaulted);
866  opt->check(IsMember{&options});
867  return opt;
868  }
869 
871  template <typename T, typename XC = double>
872  Option *add_complex(std::string option_name,
873  T &variable,
874  std::string option_description = "",
875  bool defaulted = false,
876  std::string label = "COMPLEX") {
877 
878  CLI::callback_t fun = [&variable](const results_t &res) {
879  XC x, y;
880  bool worked;
881  if(res.size() >= 2 && !res[1].empty()) {
882  auto str1 = res[1];
883  if(str1.back() == 'i' || str1.back() == 'j')
884  str1.pop_back();
885  worked = detail::lexical_cast(res[0], x) && detail::lexical_cast(str1, y);
886  } else {
887  auto str1 = res.front();
888  auto nloc = str1.find_last_of('-');
889  if(nloc != std::string::npos && nloc > 0) {
890  worked = detail::lexical_cast(str1.substr(0, nloc), x);
891  str1 = str1.substr(nloc);
892  if(str1.back() == 'i' || str1.back() == 'j')
893  str1.pop_back();
894  worked = worked && detail::lexical_cast(str1, y);
895  } else {
896  if(str1.back() == 'i' || str1.back() == 'j') {
897  str1.pop_back();
898  worked = detail::lexical_cast(str1, y);
899  x = XC{0};
900  } else {
901  worked = detail::lexical_cast(str1, x);
902  y = XC{0};
903  }
904  }
905  }
906  if(worked)
907  variable = T{x, y};
908  return worked;
909  };
910 
911  auto default_function = [&variable]() { return CLI::detail::checked_to_string<T, T>(variable); };
912 
913  CLI::Option *opt =
914  add_option(option_name, std::move(fun), std::move(option_description), defaulted, default_function);
915 
916  opt->type_name(label)->type_size(1, 2)->delimiter('+')->run_callback_for_default();
917  return opt;
918  }
919 
921  Option *set_config(std::string option_name = "",
922  std::string default_filename = "",
923  const std::string &help_message = "Read an ini file",
924  bool config_required = false) {
925 
926  // Remove existing config if present
927  if(config_ptr_ != nullptr) {
929  config_ptr_ = nullptr; // need to remove the config_ptr completely
930  }
931 
932  // Only add config if option passed
933  if(!option_name.empty()) {
934  config_ptr_ = add_option(option_name, help_message);
935  if(config_required) {
937  }
938  if(!default_filename.empty()) {
939  config_ptr_->default_str(std::move(default_filename));
940  }
941  config_ptr_->configurable(false);
942  }
943 
944  return config_ptr_;
945  }
946 
948  bool remove_option(Option *opt) {
949  // Make sure no links exist
950  for(Option_p &op : options_) {
951  op->remove_needs(opt);
952  op->remove_excludes(opt);
953  }
954 
955  if(help_ptr_ == opt)
956  help_ptr_ = nullptr;
957  if(help_all_ptr_ == opt)
958  help_all_ptr_ = nullptr;
959 
960  auto iterator =
961  std::find_if(std::begin(options_), std::end(options_), [opt](const Option_p &v) { return v.get() == opt; });
962  if(iterator != std::end(options_)) {
963  options_.erase(iterator);
964  return true;
965  }
966  return false;
967  }
968 
970  template <typename T = Option_group>
971  T *add_option_group(std::string group_name, std::string group_description = "") {
972  auto option_group = std::make_shared<T>(std::move(group_description), group_name, nullptr);
973  auto ptr = option_group.get();
974  // move to App_p for overload resolution on older gcc versions
975  App_p app_ptr = std::dynamic_pointer_cast<App>(option_group);
976  add_subcommand(std::move(app_ptr));
977  return ptr;
978  }
979 
983 
985  App *add_subcommand(std::string subcommand_name = "", std::string subcommand_description = "") {
986  if(!subcommand_name.empty() && !detail::valid_name_string(subcommand_name)) {
987  throw IncorrectConstruction("subcommand name is not valid");
988  }
989  CLI::App_p subcom = std::shared_ptr<App>(new App(std::move(subcommand_description), subcommand_name, this));
990  return add_subcommand(std::move(subcom));
991  }
992 
995  if(!subcom)
996  throw IncorrectConstruction("passed App is not valid");
997  auto ckapp = (name_.empty() && parent_ != nullptr) ? _get_fallthrough_parent() : this;
998  auto &mstrg = _compare_subcommand_names(*subcom, *ckapp);
999  if(!mstrg.empty()) {
1000  throw(OptionAlreadyAdded("subcommand name or alias matches existing subcommand: " + mstrg));
1001  }
1002  subcom->parent_ = this;
1003  subcommands_.push_back(std::move(subcom));
1004  return subcommands_.back().get();
1005  }
1006 
1008  bool remove_subcommand(App *subcom) {
1009  // Make sure no links exist
1010  for(App_p &sub : subcommands_) {
1011  sub->remove_excludes(subcom);
1012  sub->remove_needs(subcom);
1013  }
1014 
1015  auto iterator = std::find_if(
1016  std::begin(subcommands_), std::end(subcommands_), [subcom](const App_p &v) { return v.get() == subcom; });
1017  if(iterator != std::end(subcommands_)) {
1018  subcommands_.erase(iterator);
1019  return true;
1020  }
1021  return false;
1022  }
1025  App *get_subcommand(const App *subcom) const {
1026  if(subcom == nullptr)
1027  throw OptionNotFound("nullptr passed");
1028  for(const App_p &subcomptr : subcommands_)
1029  if(subcomptr.get() == subcom)
1030  return subcomptr.get();
1031  throw OptionNotFound(subcom->get_name());
1032  }
1033 
1035  App *get_subcommand(std::string subcom) const {
1036  auto subc = _find_subcommand(subcom, false, false);
1037  if(subc == nullptr)
1038  throw OptionNotFound(subcom);
1039  return subc;
1040  }
1042  App *get_subcommand(int index = 0) const {
1043  if(index >= 0) {
1044  auto uindex = static_cast<unsigned>(index);
1045  if(uindex < subcommands_.size())
1046  return subcommands_[uindex].get();
1047  }
1048  throw OptionNotFound(std::to_string(index));
1049  }
1050 
1053  if(subcom == nullptr)
1054  throw OptionNotFound("nullptr passed");
1055  for(const App_p &subcomptr : subcommands_)
1056  if(subcomptr.get() == subcom)
1057  return subcomptr;
1058  throw OptionNotFound(subcom->get_name());
1059  }
1060 
1062  CLI::App_p get_subcommand_ptr(std::string subcom) const {
1063  for(const App_p &subcomptr : subcommands_)
1064  if(subcomptr->check_name(subcom))
1065  return subcomptr;
1066  throw OptionNotFound(subcom);
1067  }
1068 
1070  CLI::App_p get_subcommand_ptr(int index = 0) const {
1071  if(index >= 0) {
1072  auto uindex = static_cast<unsigned>(index);
1073  if(uindex < subcommands_.size())
1074  return subcommands_[uindex];
1075  }
1076  throw OptionNotFound(std::to_string(index));
1077  }
1078 
1080  App *get_option_group(std::string group_name) const {
1081  for(const App_p &app : subcommands_) {
1082  if(app->name_.empty() && app->group_ == group_name) {
1083  return app.get();
1084  }
1085  }
1086  throw OptionNotFound(group_name);
1087  }
1088 
1092  std::size_t count() const { return parsed_; }
1093 
1096  std::size_t count_all() const {
1097  std::size_t cnt{0};
1098  for(auto &opt : options_) {
1099  cnt += opt->count();
1100  }
1101  for(auto &sub : subcommands_) {
1102  cnt += sub->count_all();
1103  }
1104  if(!get_name().empty()) { // for named subcommands add the number of times the subcommand was called
1105  cnt += parsed_;
1106  }
1107  return cnt;
1108  }
1109 
1111  App *group(std::string group_name) {
1112  group_ = group_name;
1113  return this;
1114  }
1115 
1120  return this;
1121  }
1122 
1126  App *require_subcommand(int value) {
1127  if(value < 0) {
1129  require_subcommand_max_ = static_cast<std::size_t>(-value);
1130  } else {
1131  require_subcommand_min_ = static_cast<std::size_t>(value);
1132  require_subcommand_max_ = static_cast<std::size_t>(value);
1133  }
1134  return this;
1135  }
1136 
1139  App *require_subcommand(std::size_t min, std::size_t max) {
1142  return this;
1143  }
1144 
1147  require_option_min_ = 1;
1148  require_option_max_ = 0;
1149  return this;
1150  }
1151 
1155  App *require_option(int value) {
1156  if(value < 0) {
1157  require_option_min_ = 0;
1158  require_option_max_ = static_cast<std::size_t>(-value);
1159  } else {
1160  require_option_min_ = static_cast<std::size_t>(value);
1161  require_option_max_ = static_cast<std::size_t>(value);
1162  }
1163  return this;
1164  }
1165 
1168  App *require_option(std::size_t min, std::size_t max) {
1169  require_option_min_ = min;
1170  require_option_max_ = max;
1171  return this;
1172  }
1173 
1176  App *fallthrough(bool value = true) {
1177  fallthrough_ = value;
1178  return this;
1179  }
1180 
1183  explicit operator bool() const { return parsed_ > 0; }
1184 
1188 
1192  virtual void pre_callback() {}
1193 
1197  //
1199  void clear() {
1200 
1201  parsed_ = 0;
1202  pre_parse_called_ = false;
1203 
1204  missing_.clear();
1205  parsed_subcommands_.clear();
1206  for(const Option_p &opt : options_) {
1207  opt->clear();
1208  }
1209  for(const App_p &subc : subcommands_) {
1210  subc->clear();
1211  }
1212  }
1213 
1216  void parse(int argc, const char *const *argv) {
1217  // If the name is not set, read from command line
1218  if(name_.empty() || has_automatic_name_) {
1219  has_automatic_name_ = true;
1220  name_ = argv[0];
1221  }
1222 
1223  std::vector<std::string> args;
1224  args.reserve(static_cast<std::size_t>(argc) - 1);
1225  for(int i = argc - 1; i > 0; i--)
1226  args.emplace_back(argv[i]);
1227  parse(std::move(args));
1228  }
1229 
1234  void parse(std::string commandline, bool program_name_included = false) {
1235 
1236  if(program_name_included) {
1237  auto nstr = detail::split_program_name(commandline);
1238  if((name_.empty()) || (has_automatic_name_)) {
1239  has_automatic_name_ = true;
1240  name_ = nstr.first;
1241  }
1242  commandline = std::move(nstr.second);
1243  } else
1244  detail::trim(commandline);
1245  // the next section of code is to deal with quoted arguments after an '=' or ':' for windows like operations
1246  if(!commandline.empty()) {
1247  commandline = detail::find_and_modify(commandline, "=", detail::escape_detect);
1249  commandline = detail::find_and_modify(commandline, ":", detail::escape_detect);
1250  }
1251 
1252  auto args = detail::split_up(std::move(commandline));
1253  // remove all empty strings
1254  args.erase(std::remove(args.begin(), args.end(), std::string{}), args.end());
1255  std::reverse(args.begin(), args.end());
1256 
1257  parse(std::move(args));
1258  }
1259 
1262  void parse(std::vector<std::string> &args) {
1263  // Clear if parsed
1264  if(parsed_ > 0)
1265  clear();
1266 
1267  // parsed_ is incremented in commands/subcommands,
1268  // but placed here to make sure this is cleared when
1269  // running parse after an error is thrown, even by _validate or _configure.
1270  parsed_ = 1;
1271  _validate();
1272  _configure();
1273  // set the parent as nullptr as this object should be the top now
1274  parent_ = nullptr;
1275  parsed_ = 0;
1276 
1277  _parse(args);
1278  run_callback();
1279  }
1280 
1282  void parse(std::vector<std::string> &&args) {
1283  // Clear if parsed
1284  if(parsed_ > 0)
1285  clear();
1286 
1287  // parsed_ is incremented in commands/subcommands,
1288  // but placed here to make sure this is cleared when
1289  // running parse after an error is thrown, even by _validate or _configure.
1290  parsed_ = 1;
1291  _validate();
1292  _configure();
1293  // set the parent as nullptr as this object should be the top now
1294  parent_ = nullptr;
1295  parsed_ = 0;
1296 
1297  _parse(std::move(args));
1298  run_callback();
1299  }
1300 
1302  void failure_message(std::function<std::string(const App *, const Error &e)> function) {
1303  failure_message_ = function;
1304  }
1305 
1307  int exit(const Error &e, std::ostream &out = std::cout, std::ostream &err = std::cerr) const {
1308 
1310  if(dynamic_cast<const CLI::RuntimeError *>(&e) != nullptr)
1311  return e.get_exit_code();
1312 
1313  if(dynamic_cast<const CLI::CallForHelp *>(&e) != nullptr) {
1314  out << help();
1315  return e.get_exit_code();
1316  }
1317 
1318  if(dynamic_cast<const CLI::CallForAllHelp *>(&e) != nullptr) {
1319  out << help("", AppFormatMode::All);
1320  return e.get_exit_code();
1321  }
1322 
1323  if(e.get_exit_code() != static_cast<int>(ExitCodes::Success)) {
1324  if(failure_message_)
1325  err << failure_message_(this, e) << std::flush;
1326  }
1327 
1328  return e.get_exit_code();
1329  }
1330 
1334 
1336  std::size_t count(std::string option_name) const { return get_option(option_name)->count(); }
1337 
1340  std::vector<App *> get_subcommands() const { return parsed_subcommands_; }
1341 
1344  std::vector<const App *> get_subcommands(const std::function<bool(const App *)> &filter) const {
1345  std::vector<const App *> subcomms(subcommands_.size());
1346  std::transform(std::begin(subcommands_), std::end(subcommands_), std::begin(subcomms), [](const App_p &v) {
1347  return v.get();
1348  });
1349 
1350  if(filter) {
1351  subcomms.erase(std::remove_if(std::begin(subcomms),
1352  std::end(subcomms),
1353  [&filter](const App *app) { return !filter(app); }),
1354  std::end(subcomms));
1355  }
1356 
1357  return subcomms;
1358  }
1359 
1362  std::vector<App *> get_subcommands(const std::function<bool(App *)> &filter) {
1363  std::vector<App *> subcomms(subcommands_.size());
1364  std::transform(std::begin(subcommands_), std::end(subcommands_), std::begin(subcomms), [](const App_p &v) {
1365  return v.get();
1366  });
1367 
1368  if(filter) {
1369  subcomms.erase(
1370  std::remove_if(std::begin(subcomms), std::end(subcomms), [&filter](App *app) { return !filter(app); }),
1371  std::end(subcomms));
1372  }
1373 
1374  return subcomms;
1375  }
1376 
1378  bool got_subcommand(const App *subcom) const {
1379  // get subcom needed to verify that this was a real subcommand
1380  return get_subcommand(subcom)->parsed_ > 0;
1381  }
1382 
1384  bool got_subcommand(std::string subcommand_name) const { return get_subcommand(subcommand_name)->parsed_ > 0; }
1385 
1388  if(opt == nullptr) {
1389  throw OptionNotFound("nullptr passed");
1390  }
1391  exclude_options_.insert(opt);
1392  return this;
1393  }
1394 
1396  App *excludes(App *app) {
1397  if(app == nullptr) {
1398  throw OptionNotFound("nullptr passed");
1399  }
1400  if(app == this) {
1401  throw OptionNotFound("cannot self reference in needs");
1402  }
1403  auto res = exclude_subcommands_.insert(app);
1404  // subcommand exclusion should be symmetric
1405  if(res.second) {
1406  app->exclude_subcommands_.insert(this);
1407  }
1408  return this;
1409  }
1410 
1411  App *needs(Option *opt) {
1412  if(opt == nullptr) {
1413  throw OptionNotFound("nullptr passed");
1414  }
1415  need_options_.insert(opt);
1416  return this;
1417  }
1418 
1419  App *needs(App *app) {
1420  if(app == nullptr) {
1421  throw OptionNotFound("nullptr passed");
1422  }
1423  if(app == this) {
1424  throw OptionNotFound("cannot self reference in needs");
1425  }
1426  need_subcommands_.insert(app);
1427  return this;
1428  }
1429 
1432  auto iterator = std::find(std::begin(exclude_options_), std::end(exclude_options_), opt);
1433  if(iterator == std::end(exclude_options_)) {
1434  return false;
1435  }
1436  exclude_options_.erase(iterator);
1437  return true;
1438  }
1439 
1441  bool remove_excludes(App *app) {
1442  auto iterator = std::find(std::begin(exclude_subcommands_), std::end(exclude_subcommands_), app);
1443  if(iterator == std::end(exclude_subcommands_)) {
1444  return false;
1445  }
1446  auto other_app = *iterator;
1447  exclude_subcommands_.erase(iterator);
1448  other_app->remove_excludes(this);
1449  return true;
1450  }
1451 
1453  bool remove_needs(Option *opt) {
1454  auto iterator = std::find(std::begin(need_options_), std::end(need_options_), opt);
1455  if(iterator == std::end(need_options_)) {
1456  return false;
1457  }
1458  need_options_.erase(iterator);
1459  return true;
1460  }
1461 
1463  bool remove_needs(App *app) {
1464  auto iterator = std::find(std::begin(need_subcommands_), std::end(need_subcommands_), app);
1465  if(iterator == std::end(need_subcommands_)) {
1466  return false;
1467  }
1468  need_subcommands_.erase(iterator);
1469  return true;
1470  }
1471 
1475 
1477  App *footer(std::string footer_string) {
1478  footer_ = std::move(footer_string);
1479  return this;
1480  }
1482  App *footer(std::function<std::string()> footer_function) {
1483  footer_callback_ = std::move(footer_function);
1484  return this;
1485  }
1488  std::string config_to_str(bool default_also = false, bool write_description = false) const {
1489  return config_formatter_->to_config(this, default_also, write_description, "");
1490  }
1491 
1494  std::string help(std::string prev = "", AppFormatMode mode = AppFormatMode::Normal) const {
1495  if(prev.empty())
1496  prev = get_name();
1497  else
1498  prev += " " + get_name();
1499 
1500  // Delegate to subcommand if needed
1501  auto selected_subcommands = get_subcommands();
1502  if(!selected_subcommands.empty()) {
1503  return selected_subcommands.at(0)->help(prev, mode);
1504  }
1505  return formatter_->make_help(this, prev, mode);
1506  }
1507 
1511 
1513  std::shared_ptr<FormatterBase> get_formatter() const { return formatter_; }
1514 
1516  std::shared_ptr<Config> get_config_formatter() const { return config_formatter_; }
1517 
1519  std::shared_ptr<ConfigBase> get_config_formatter_base() const {
1520  return std::dynamic_pointer_cast<ConfigBase>(config_formatter_);
1521  }
1522 
1524  std::string get_description() const { return description_; }
1525 
1527  App *description(std::string app_description) {
1528  description_ = std::move(app_description);
1529  return this;
1530  }
1531 
1533  std::vector<const Option *> get_options(const std::function<bool(const Option *)> filter = {}) const {
1534  std::vector<const Option *> options(options_.size());
1535  std::transform(std::begin(options_), std::end(options_), std::begin(options), [](const Option_p &val) {
1536  return val.get();
1537  });
1538 
1539  if(filter) {
1540  options.erase(std::remove_if(std::begin(options),
1541  std::end(options),
1542  [&filter](const Option *opt) { return !filter(opt); }),
1543  std::end(options));
1544  }
1545 
1546  return options;
1547  }
1548 
1550  std::vector<Option *> get_options(const std::function<bool(Option *)> filter = {}) {
1551  std::vector<Option *> options(options_.size());
1552  std::transform(std::begin(options_), std::end(options_), std::begin(options), [](const Option_p &val) {
1553  return val.get();
1554  });
1555 
1556  if(filter) {
1557  options.erase(
1558  std::remove_if(std::begin(options), std::end(options), [&filter](Option *opt) { return !filter(opt); }),
1559  std::end(options));
1560  }
1561 
1562  return options;
1563  }
1564 
1566  Option *get_option_no_throw(std::string option_name) noexcept {
1567  for(Option_p &opt : options_) {
1568  if(opt->check_name(option_name)) {
1569  return opt.get();
1570  }
1571  }
1572  for(auto &subc : subcommands_) {
1573  // also check down into nameless subcommands
1574  if(subc->get_name().empty()) {
1575  auto opt = subc->get_option_no_throw(option_name);
1576  if(opt != nullptr) {
1577  return opt;
1578  }
1579  }
1580  }
1581  return nullptr;
1582  }
1583 
1585  const Option *get_option_no_throw(std::string option_name) const noexcept {
1586  for(const Option_p &opt : options_) {
1587  if(opt->check_name(option_name)) {
1588  return opt.get();
1589  }
1590  }
1591  for(const auto &subc : subcommands_) {
1592  // also check down into nameless subcommands
1593  if(subc->get_name().empty()) {
1594  auto opt = subc->get_option_no_throw(option_name);
1595  if(opt != nullptr) {
1596  return opt;
1597  }
1598  }
1599  }
1600  return nullptr;
1601  }
1602 
1604  const Option *get_option(std::string option_name) const {
1605  auto opt = get_option_no_throw(option_name);
1606  if(opt == nullptr) {
1607  throw OptionNotFound(option_name);
1608  }
1609  return opt;
1610  }
1611 
1613  Option *get_option(std::string option_name) {
1614  auto opt = get_option_no_throw(option_name);
1615  if(opt == nullptr) {
1616  throw OptionNotFound(option_name);
1617  }
1618  return opt;
1619  }
1620 
1622  const Option *operator[](const std::string &option_name) const { return get_option(option_name); }
1623 
1625  const Option *operator[](const char *option_name) const { return get_option(option_name); }
1626 
1628  bool get_ignore_case() const { return ignore_case_; }
1629 
1632 
1634  bool get_fallthrough() const { return fallthrough_; }
1635 
1638 
1641 
1643  bool get_configurable() const { return configurable_; }
1644 
1646  const std::string &get_group() const { return group_; }
1647 
1649  std::string get_footer() const { return (footer_callback_) ? footer_callback_() + '\n' + footer_ : footer_; }
1650 
1652  std::size_t get_require_subcommand_min() const { return require_subcommand_min_; }
1653 
1655  std::size_t get_require_subcommand_max() const { return require_subcommand_max_; }
1656 
1658  std::size_t get_require_option_min() const { return require_option_min_; }
1659 
1661  std::size_t get_require_option_max() const { return require_option_max_; }
1662 
1664  bool get_prefix_command() const { return prefix_command_; }
1665 
1667  bool get_allow_extras() const { return allow_extras_; }
1668 
1670  bool get_required() const { return required_; }
1671 
1673  bool get_disabled() const { return disabled_; }
1674 
1677 
1680 
1685 
1688 
1691 
1693  const Option *get_help_ptr() const { return help_ptr_; }
1694 
1696  const Option *get_help_all_ptr() const { return help_all_ptr_; }
1697 
1700 
1702  const Option *get_config_ptr() const { return config_ptr_; }
1703 
1705  App *get_parent() { return parent_; }
1706 
1708  const App *get_parent() const { return parent_; }
1709 
1711  const std::string &get_name() const { return name_; }
1712 
1714  const std::vector<std::string> &get_aliases() const { return aliases_; }
1715 
1718  aliases_.clear();
1719  return this;
1720  }
1721 
1723  std::string get_display_name() const { return (!name_.empty()) ? name_ : "[Option Group: " + get_group() + "]"; }
1724 
1726  bool check_name(std::string name_to_check) const {
1727  std::string local_name = name_;
1728  if(ignore_underscore_) {
1729  local_name = detail::remove_underscore(name_);
1730  name_to_check = detail::remove_underscore(name_to_check);
1731  }
1732  if(ignore_case_) {
1733  local_name = detail::to_lower(name_);
1734  name_to_check = detail::to_lower(name_to_check);
1735  }
1736 
1737  if(local_name == name_to_check) {
1738  return true;
1739  }
1740  for(auto les : aliases_) {
1741  if(ignore_underscore_) {
1742  les = detail::remove_underscore(les);
1743  }
1744  if(ignore_case_) {
1745  les = detail::to_lower(les);
1746  }
1747  if(les == name_to_check) {
1748  return true;
1749  }
1750  }
1751  return false;
1752  }
1753 
1755  std::vector<std::string> get_groups() const {
1756  std::vector<std::string> groups;
1757 
1758  for(const Option_p &opt : options_) {
1759  // Add group if it is not already in there
1760  if(std::find(groups.begin(), groups.end(), opt->get_group()) == groups.end()) {
1761  groups.push_back(opt->get_group());
1762  }
1763  }
1764 
1765  return groups;
1766  }
1767 
1769  const std::vector<Option *> &parse_order() const { return parse_order_; }
1770 
1772  std::vector<std::string> remaining(bool recurse = false) const {
1773  std::vector<std::string> miss_list;
1774  for(const std::pair<detail::Classifier, std::string> &miss : missing_) {
1775  miss_list.push_back(std::get<1>(miss));
1776  }
1777  // Get from a subcommand that may allow extras
1778  if(recurse) {
1779  if(!allow_extras_) {
1780  for(const auto &sub : subcommands_) {
1781  if(sub->name_.empty() && !sub->missing_.empty()) {
1782  for(const std::pair<detail::Classifier, std::string> &miss : sub->missing_) {
1783  miss_list.push_back(std::get<1>(miss));
1784  }
1785  }
1786  }
1787  }
1788  // Recurse into subcommands
1789 
1790  for(const App *sub : parsed_subcommands_) {
1791  std::vector<std::string> output = sub->remaining(recurse);
1792  std::copy(std::begin(output), std::end(output), std::back_inserter(miss_list));
1793  }
1794  }
1795  return miss_list;
1796  }
1797 
1799  std::vector<std::string> remaining_for_passthrough(bool recurse = false) const {
1800  std::vector<std::string> miss_list = remaining(recurse);
1801  std::reverse(std::begin(miss_list), std::end(miss_list));
1802  return miss_list;
1803  }
1804 
1806  std::size_t remaining_size(bool recurse = false) const {
1807  auto remaining_options = static_cast<std::size_t>(std::count_if(
1808  std::begin(missing_), std::end(missing_), [](const std::pair<detail::Classifier, std::string> &val) {
1809  return val.first != detail::Classifier::POSITIONAL_MARK;
1810  }));
1811 
1812  if(recurse) {
1813  for(const App_p &sub : subcommands_) {
1814  remaining_options += sub->remaining_size(recurse);
1815  }
1816  }
1817  return remaining_options;
1818  }
1819 
1821 
1822  protected:
1827  void _validate() const {
1828  // count the number of positional only args
1829  auto pcount = std::count_if(std::begin(options_), std::end(options_), [](const Option_p &opt) {
1830  return opt->get_items_expected_max() >= detail::expected_max_vector_size && !opt->nonpositional();
1831  });
1832  if(pcount > 1) {
1833  auto pcount_req = std::count_if(std::begin(options_), std::end(options_), [](const Option_p &opt) {
1834  return opt->get_items_expected_max() >= detail::expected_max_vector_size && !opt->nonpositional() &&
1835  opt->get_required();
1836  });
1837  if(pcount - pcount_req > 1) {
1838  throw InvalidError(name_);
1839  }
1840  }
1841 
1842  std::size_t nameless_subs{0};
1843  for(const App_p &app : subcommands_) {
1844  app->_validate();
1845  if(app->get_name().empty())
1846  ++nameless_subs;
1847  }
1848 
1849  if(require_option_min_ > 0) {
1850  if(require_option_max_ > 0) {
1852  throw(InvalidError("Required min options greater than required max options",
1854  }
1855  }
1856  if(require_option_min_ > (options_.size() + nameless_subs)) {
1857  throw(InvalidError("Required min options greater than number of available options",
1859  }
1860  }
1861  }
1862 
1866  void _configure() {
1868  disabled_ = false;
1869  } else if(default_startup == startup_mode::disabled) {
1870  disabled_ = true;
1871  }
1872  for(const App_p &app : subcommands_) {
1873  if(app->has_automatic_name_) {
1874  app->name_.clear();
1875  }
1876  if(app->name_.empty()) {
1877  app->fallthrough_ = false; // make sure fallthrough_ is false to prevent infinite loop
1878  app->prefix_command_ = false;
1879  }
1880  // make sure the parent is set to be this object in preparation for parse
1881  app->parent_ = this;
1882  app->_configure();
1883  }
1884  }
1886  void run_callback(bool final_mode = false) {
1887  pre_callback();
1888  // in the main app if immediate_callback_ is set it runs the main callback before the used subcommands
1889  if(!final_mode && parse_complete_callback_) {
1891  }
1892  // run the callbacks for the received subcommands
1893  for(App *subc : get_subcommands()) {
1894  subc->run_callback(true);
1895  }
1896  // now run callbacks for option_groups
1897  for(auto &subc : subcommands_) {
1898  if(subc->name_.empty() && subc->count_all() > 0) {
1899  subc->run_callback(true);
1900  }
1901  }
1902 
1903  // finally run the main callback
1904  if(final_callback_ && (parsed_ > 0)) {
1905  if(!name_.empty() || count_all() > 0) {
1906  final_callback_();
1907  }
1908  }
1909  }
1910 
1912  bool _valid_subcommand(const std::string &current, bool ignore_used = true) const {
1913  // Don't match if max has been reached - but still check parents
1915  return parent_ != nullptr && parent_->_valid_subcommand(current, ignore_used);
1916  }
1917  auto com = _find_subcommand(current, true, ignore_used);
1918  if(com != nullptr) {
1919  return true;
1920  }
1921  // Check parent if exists, else return false
1922  return parent_ != nullptr && parent_->_valid_subcommand(current, ignore_used);
1923  }
1924 
1926  detail::Classifier _recognize(const std::string &current, bool ignore_used_subcommands = true) const {
1927  std::string dummy1, dummy2;
1928 
1929  if(current == "--")
1931  if(_valid_subcommand(current, ignore_used_subcommands))
1933  if(detail::split_long(current, dummy1, dummy2))
1934  return detail::Classifier::LONG;
1935  if(detail::split_short(current, dummy1, dummy2)) {
1936  if(dummy1[0] >= '0' && dummy1[0] <= '9') {
1937  if(get_option_no_throw(std::string{'-', dummy1[0]}) == nullptr) {
1938  return detail::Classifier::NONE;
1939  }
1940  }
1942  }
1943  if((allow_windows_style_options_) && (detail::split_windows_style(current, dummy1, dummy2)))
1945  if((current == "++") && !name_.empty() && parent_ != nullptr)
1947  return detail::Classifier::NONE;
1948  }
1949 
1950  // The parse function is now broken into several parts, and part of process
1951 
1954  if(config_ptr_ != nullptr) {
1955  bool config_required = config_ptr_->get_required();
1956  bool file_given = config_ptr_->count() > 0;
1957  auto config_file = config_ptr_->as<std::string>();
1958  if(config_file.empty()) {
1959  if(config_required) {
1960  throw FileError::Missing("no specified config file");
1961  }
1962  return;
1963  }
1964 
1965  auto path_result = detail::check_path(config_file.c_str());
1966  if(path_result == detail::path_type::file) {
1967  try {
1968  std::vector<ConfigItem> values = config_formatter_->from_file(config_file);
1969  _parse_config(values);
1970  if(!file_given) {
1971  config_ptr_->add_result(config_file);
1972  }
1973  } catch(const FileError &) {
1974  if(config_required || file_given)
1975  throw;
1976  }
1977  } else if(config_required || file_given) {
1978  throw FileError::Missing(config_file);
1979  }
1980  }
1981  }
1982 
1984  void _process_env() {
1985  for(const Option_p &opt : options_) {
1986  if(opt->count() == 0 && !opt->envname_.empty()) {
1987  char *buffer = nullptr;
1988  std::string ename_string;
1989 
1990 #ifdef _MSC_VER
1991  // Windows version
1992  std::size_t sz = 0;
1993  if(_dupenv_s(&buffer, &sz, opt->envname_.c_str()) == 0 && buffer != nullptr) {
1994  ename_string = std::string(buffer);
1995  free(buffer);
1996  }
1997 #else
1998  // This also works on Windows, but gives a warning
1999  buffer = std::getenv(opt->envname_.c_str());
2000  if(buffer != nullptr)
2001  ename_string = std::string(buffer);
2002 #endif
2003 
2004  if(!ename_string.empty()) {
2005  opt->add_result(ename_string);
2006  }
2007  }
2008  }
2009 
2010  for(App_p &sub : subcommands_) {
2011  if(sub->get_name().empty() || !sub->parse_complete_callback_)
2012  sub->_process_env();
2013  }
2014  }
2015 
2018 
2019  for(App_p &sub : subcommands_) {
2020  // process the priority option_groups first
2021  if(sub->get_name().empty() && sub->parse_complete_callback_) {
2022  if(sub->count_all() > 0) {
2023  sub->_process_callbacks();
2024  sub->run_callback();
2025  }
2026  }
2027  }
2028 
2029  for(const Option_p &opt : options_) {
2030  if(opt->count() > 0 && !opt->get_callback_run()) {
2031  opt->run_callback();
2032  }
2033  }
2034  for(App_p &sub : subcommands_) {
2035  if(!sub->parse_complete_callback_) {
2036  sub->_process_callbacks();
2037  }
2038  }
2039  }
2040 
2044  void _process_help_flags(bool trigger_help = false, bool trigger_all_help = false) const {
2045  const Option *help_ptr = get_help_ptr();
2046  const Option *help_all_ptr = get_help_all_ptr();
2047 
2048  if(help_ptr != nullptr && help_ptr->count() > 0)
2049  trigger_help = true;
2050  if(help_all_ptr != nullptr && help_all_ptr->count() > 0)
2051  trigger_all_help = true;
2052 
2053  // If there were parsed subcommands, call those. First subcommand wins if there are multiple ones.
2054  if(!parsed_subcommands_.empty()) {
2055  for(const App *sub : parsed_subcommands_)
2056  sub->_process_help_flags(trigger_help, trigger_all_help);
2057 
2058  // Only the final subcommand should call for help. All help wins over help.
2059  } else if(trigger_all_help) {
2060  throw CallForAllHelp();
2061  } else if(trigger_help) {
2062  throw CallForHelp();
2063  }
2064  }
2065 
2068  // check excludes
2069  bool excluded{false};
2070  std::string excluder;
2071  for(auto &opt : exclude_options_) {
2072  if(opt->count() > 0) {
2073  excluded = true;
2074  excluder = opt->get_name();
2075  }
2076  }
2077  for(auto &subc : exclude_subcommands_) {
2078  if(subc->count_all() > 0) {
2079  excluded = true;
2080  excluder = subc->get_display_name();
2081  }
2082  }
2083  if(excluded) {
2084  if(count_all() > 0) {
2085  throw ExcludesError(get_display_name(), excluder);
2086  }
2087  // if we are excluded but didn't receive anything, just return
2088  return;
2089  }
2090 
2091  // check excludes
2092  bool missing_needed{false};
2093  std::string missing_need;
2094  for(auto &opt : need_options_) {
2095  if(opt->count() == 0) {
2096  missing_needed = true;
2097  missing_need = opt->get_name();
2098  }
2099  }
2100  for(auto &subc : need_subcommands_) {
2101  if(subc->count_all() == 0) {
2102  missing_needed = true;
2103  missing_need = subc->get_display_name();
2104  }
2105  }
2106  if(missing_needed) {
2107  if(count_all() > 0) {
2108  throw RequiresError(get_display_name(), missing_need);
2109  }
2110  // if we missing something but didn't have any options, just return
2111  return;
2112  }
2113 
2114  std::size_t used_options = 0;
2115  for(const Option_p &opt : options_) {
2116 
2117  if(opt->count() != 0) {
2118  ++used_options;
2119  }
2120  // Required but empty
2121  if(opt->get_required() && opt->count() == 0) {
2122  throw RequiredError(opt->get_name());
2123  }
2124  // Requires
2125  for(const Option *opt_req : opt->needs_)
2126  if(opt->count() > 0 && opt_req->count() == 0)
2127  throw RequiresError(opt->get_name(), opt_req->get_name());
2128  // Excludes
2129  for(const Option *opt_ex : opt->excludes_)
2130  if(opt->count() > 0 && opt_ex->count() != 0)
2131  throw ExcludesError(opt->get_name(), opt_ex->get_name());
2132  }
2133  // check for the required number of subcommands
2134  if(require_subcommand_min_ > 0) {
2135  auto selected_subcommands = get_subcommands();
2136  if(require_subcommand_min_ > selected_subcommands.size())
2137  throw RequiredError::Subcommand(require_subcommand_min_);
2138  }
2139 
2140  // Max error cannot occur, the extra subcommand will parse as an ExtrasError or a remaining item.
2141 
2142  // run this loop to check how many unnamed subcommands were actually used since they are considered options
2143  // from the perspective of an App
2144  for(App_p &sub : subcommands_) {
2145  if(sub->disabled_)
2146  continue;
2147  if(sub->name_.empty() && sub->count_all() > 0) {
2148  ++used_options;
2149  }
2150  }
2151 
2152  if(require_option_min_ > used_options || (require_option_max_ > 0 && require_option_max_ < used_options)) {
2153  auto option_list = detail::join(options_, [](const Option_p &ptr) { return ptr->get_name(false, true); });
2154  if(option_list.compare(0, 10, "-h,--help,") == 0) {
2155  option_list.erase(0, 10);
2156  }
2157  auto subc_list = get_subcommands([](App *app) { return ((app->get_name().empty()) && (!app->disabled_)); });
2158  if(!subc_list.empty()) {
2159  option_list += "," + detail::join(subc_list, [](const App *app) { return app->get_display_name(); });
2160  }
2161  throw RequiredError::Option(require_option_min_, require_option_max_, used_options, option_list);
2162  }
2163 
2164  // now process the requirements for subcommands if needed
2165  for(App_p &sub : subcommands_) {
2166  if(sub->disabled_)
2167  continue;
2168  if(sub->name_.empty() && sub->required_ == false) {
2169  if(sub->count_all() == 0) {
2170  if(require_option_min_ > 0 && require_option_min_ <= used_options) {
2171  continue;
2172  // if we have met the requirement and there is nothing in this option group skip checking
2173  // requirements
2174  }
2175  if(require_option_max_ > 0 && used_options >= require_option_min_) {
2176  continue;
2177  // if we have met the requirement and there is nothing in this option group skip checking
2178  // requirements
2179  }
2180  }
2181  }
2182  if(sub->count() > 0 || sub->name_.empty()) {
2183  sub->_process_requirements();
2184  }
2185 
2186  if(sub->required_ && sub->count_all() == 0) {
2187  throw(CLI::RequiredError(sub->get_display_name()));
2188  }
2189  }
2190  }
2191 
2193  void _process() {
2195  _process_env();
2199  }
2200 
2203  if(!(allow_extras_ || prefix_command_)) {
2204  std::size_t num_left_over = remaining_size();
2205  if(num_left_over > 0) {
2206  throw ExtrasError(name_, remaining(false));
2207  }
2208  }
2209 
2210  for(App_p &sub : subcommands_) {
2211  if(sub->count() > 0)
2212  sub->_process_extras();
2213  }
2214  }
2215 
2218  void _process_extras(std::vector<std::string> &args) {
2219  if(!(allow_extras_ || prefix_command_)) {
2220  std::size_t num_left_over = remaining_size();
2221  if(num_left_over > 0) {
2222  args = remaining(false);
2223  throw ExtrasError(name_, args);
2224  }
2225  }
2226 
2227  for(App_p &sub : subcommands_) {
2228  if(sub->count() > 0)
2229  sub->_process_extras(args);
2230  }
2231  }
2232 
2235  ++parsed_;
2236  for(App_p &sub : subcommands_) {
2237  if(sub->get_name().empty())
2238  sub->increment_parsed();
2239  }
2240  }
2242  void _parse(std::vector<std::string> &args) {
2243  increment_parsed();
2244  _trigger_pre_parse(args.size());
2245  bool positional_only = false;
2246 
2247  while(!args.empty()) {
2248  if(!_parse_single(args, positional_only)) {
2249  break;
2250  }
2251  }
2252 
2253  if(parent_ == nullptr) {
2254  _process();
2255 
2256  // Throw error if any items are left over (depending on settings)
2257  _process_extras(args);
2258 
2259  // Convert missing (pairs) to extras (string only) ready for processing in another app
2260  args = remaining_for_passthrough(false);
2261  } else if(parse_complete_callback_) {
2262  _process_env();
2266  run_callback();
2267  }
2268  }
2269 
2271  void _parse(std::vector<std::string> &&args) {
2272  // this can only be called by the top level in which case parent == nullptr by definition
2273  // operation is simplified
2274  increment_parsed();
2275  _trigger_pre_parse(args.size());
2276  bool positional_only = false;
2277 
2278  while(!args.empty()) {
2279  _parse_single(args, positional_only);
2280  }
2281  _process();
2282 
2283  // Throw error if any items are left over (depending on settings)
2284  _process_extras();
2285  }
2286 
2291  void _parse_config(std::vector<ConfigItem> &args) {
2292  for(ConfigItem item : args) {
2294  throw ConfigError::Extras(item.fullname());
2295  }
2296  }
2297 
2299  bool _parse_single_config(const ConfigItem &item, std::size_t level = 0) {
2300  if(level < item.parents.size()) {
2301  try {
2302  auto subcom = get_subcommand(item.parents.at(level));
2303  auto result = subcom->_parse_single_config(item, level + 1);
2304 
2305  return result;
2306  } catch(const OptionNotFound &) {
2307  return false;
2308  }
2309  }
2310  // check for section open
2311  if(item.name == "++") {
2312  if(configurable_) {
2313  increment_parsed();
2314  _trigger_pre_parse(2);
2315  if(parent_ != nullptr) {
2316  parent_->parsed_subcommands_.push_back(this);
2317  }
2318  }
2319  return true;
2320  }
2321  // check for section close
2322  if(item.name == "--") {
2323  if(configurable_) {
2326  run_callback();
2327  }
2328  return true;
2329  }
2330  Option *op = get_option_no_throw("--" + item.name);
2331  if(op == nullptr) {
2332  // If the option was not present
2334  // Should we worry about classifying the extras properly?
2335  missing_.emplace_back(detail::Classifier::NONE, item.fullname());
2336  return false;
2337  }
2338 
2339  if(!op->get_configurable())
2340  throw ConfigError::NotConfigurable(item.fullname());
2341 
2342  if(op->empty()) {
2343  // Flag parsing
2344  if(op->get_expected_min() == 0) {
2345  auto res = config_formatter_->to_flag(item);
2346  res = op->get_flag_value(item.name, res);
2347 
2348  op->add_result(res);
2349 
2350  } else {
2351  op->add_result(item.inputs);
2352  op->run_callback();
2353  }
2354  }
2355 
2356  return true;
2357  }
2358 
2361  bool _parse_single(std::vector<std::string> &args, bool &positional_only) {
2362  bool retval = true;
2363  detail::Classifier classifier = positional_only ? detail::Classifier::NONE : _recognize(args.back());
2364  switch(classifier) {
2366  args.pop_back();
2367  positional_only = true;
2368  if((!_has_remaining_positionals()) && (parent_ != nullptr)) {
2369  retval = false;
2370  } else {
2371  _move_to_missing(classifier, "--");
2372  }
2373  break;
2375  // treat this like a positional mark if in the parent app
2376  args.pop_back();
2377  retval = false;
2378  break;
2380  retval = _parse_subcommand(args);
2381  break;
2385  // If already parsed a subcommand, don't accept options_
2386  _parse_arg(args, classifier);
2387  break;
2389  // Probably a positional or something for a parent (sub)command
2390  retval = _parse_positional(args, false);
2391  if(retval && positionals_at_end_) {
2392  positional_only = true;
2393  }
2394  break;
2395  // LCOV_EXCL_START
2396  default:
2397  throw HorribleError("unrecognized classifier (you should not see this!)");
2398  // LCOV_EXCL_STOP
2399  }
2400  return retval;
2401  }
2402 
2404  std::size_t _count_remaining_positionals(bool required_only = false) const {
2405  std::size_t retval = 0;
2406  for(const Option_p &opt : options_) {
2407  if(opt->get_positional() && (!required_only || opt->get_required())) {
2408  if(opt->get_items_expected_min() > 0 &&
2409  static_cast<int>(opt->count()) < opt->get_items_expected_min()) {
2410  retval += static_cast<std::size_t>(opt->get_items_expected_min()) - opt->count();
2411  }
2412  }
2413  }
2414  return retval;
2415  }
2416 
2419  for(const Option_p &opt : options_) {
2420  if(opt->get_positional() && ((static_cast<int>(opt->count()) < opt->get_items_expected_min()))) {
2421  return true;
2422  }
2423  }
2424 
2425  return false;
2426  }
2427 
2431  bool _parse_positional(std::vector<std::string> &args, bool haltOnSubcommand) {
2432 
2433  const std::string &positional = args.back();
2434 
2435  if(positionals_at_end_) {
2436  // deal with the case of required arguments at the end which should take precedence over other arguments
2437  auto arg_rem = args.size();
2438  auto remreq = _count_remaining_positionals(true);
2439  if(arg_rem <= remreq) {
2440  for(const Option_p &opt : options_) {
2441  if(opt->get_positional() && opt->required_) {
2442  if(static_cast<int>(opt->count()) < opt->get_items_expected_min()) {
2443  if(validate_positionals_) {
2444  std::string pos = positional;
2445  pos = opt->_validate(pos, 0);
2446  if(!pos.empty()) {
2447  continue;
2448  }
2449  }
2450  opt->add_result(positional);
2451  parse_order_.push_back(opt.get());
2452  args.pop_back();
2453  return true;
2454  }
2455  }
2456  }
2457  }
2458  }
2459  for(const Option_p &opt : options_) {
2460  // Eat options, one by one, until done
2461  if(opt->get_positional() &&
2462  (static_cast<int>(opt->count()) < opt->get_items_expected_min() || opt->get_allow_extra_args())) {
2463  if(validate_positionals_) {
2464  std::string pos = positional;
2465  pos = opt->_validate(pos, 0);
2466  if(!pos.empty()) {
2467  continue;
2468  }
2469  }
2470  opt->add_result(positional);
2471  parse_order_.push_back(opt.get());
2472  args.pop_back();
2473  return true;
2474  }
2475  }
2476 
2477  for(auto &subc : subcommands_) {
2478  if((subc->name_.empty()) && (!subc->disabled_)) {
2479  if(subc->_parse_positional(args, false)) {
2480  if(!subc->pre_parse_called_) {
2481  subc->_trigger_pre_parse(args.size());
2482  }
2483  return true;
2484  }
2485  }
2486  }
2487  // let the parent deal with it if possible
2488  if(parent_ != nullptr && fallthrough_)
2489  return _get_fallthrough_parent()->_parse_positional(args, static_cast<bool>(parse_complete_callback_));
2490 
2492  auto com = _find_subcommand(args.back(), true, false);
2493  if(com != nullptr && (require_subcommand_max_ == 0 || require_subcommand_max_ > parsed_subcommands_.size())) {
2494  if(haltOnSubcommand) {
2495  return false;
2496  }
2497  args.pop_back();
2498  com->_parse(args);
2499  return true;
2500  }
2503  auto parent_app = (parent_ != nullptr) ? _get_fallthrough_parent() : this;
2504  com = parent_app->_find_subcommand(args.back(), true, false);
2505  if(com != nullptr && (com->parent_->require_subcommand_max_ == 0 ||
2506  com->parent_->require_subcommand_max_ > com->parent_->parsed_subcommands_.size())) {
2507  return false;
2508  }
2509 
2510  if(positionals_at_end_) {
2511  throw CLI::ExtrasError(name_, args);
2512  }
2514  if(parent_ != nullptr && name_.empty()) {
2515  return false;
2516  }
2519  args.pop_back();
2520  if(prefix_command_) {
2521  while(!args.empty()) {
2523  args.pop_back();
2524  }
2525  }
2526 
2527  return true;
2528  }
2529 
2532  App *_find_subcommand(const std::string &subc_name, bool ignore_disabled, bool ignore_used) const noexcept {
2533  for(const App_p &com : subcommands_) {
2534  if(com->disabled_ && ignore_disabled)
2535  continue;
2536  if(com->get_name().empty()) {
2537  auto subc = com->_find_subcommand(subc_name, ignore_disabled, ignore_used);
2538  if(subc != nullptr) {
2539  return subc;
2540  }
2541  }
2542  if(com->check_name(subc_name)) {
2543  if((!*com) || !ignore_used)
2544  return com.get();
2545  }
2546  }
2547  return nullptr;
2548  }
2549 
2554  bool _parse_subcommand(std::vector<std::string> &args) {
2555  if(_count_remaining_positionals(/* required */ true) > 0) {
2556  _parse_positional(args, false);
2557  return true;
2558  }
2559  auto com = _find_subcommand(args.back(), true, true);
2560  if(com != nullptr) {
2561  args.pop_back();
2562  parsed_subcommands_.push_back(com);
2563  com->_parse(args);
2564  auto parent_app = com->parent_;
2565  while(parent_app != this) {
2566  parent_app->_trigger_pre_parse(args.size());
2567  parent_app->parsed_subcommands_.push_back(com);
2568  parent_app = parent_app->parent_;
2569  }
2570  return true;
2571  }
2572 
2573  if(parent_ == nullptr)
2574  throw HorribleError("Subcommand " + args.back() + " missing");
2575  return false;
2576  }
2577 
2580  bool _parse_arg(std::vector<std::string> &args, detail::Classifier current_type) {
2581 
2582  std::string current = args.back();
2583 
2584  std::string arg_name;
2585  std::string value;
2586  std::string rest;
2587 
2588  switch(current_type) {
2590  if(!detail::split_long(current, arg_name, value))
2591  throw HorribleError("Long parsed but missing (you should not see this):" + args.back());
2592  break;
2594  if(!detail::split_short(current, arg_name, rest))
2595  throw HorribleError("Short parsed but missing! You should not see this");
2596  break;
2598  if(!detail::split_windows_style(current, arg_name, value))
2599  throw HorribleError("windows option parsed but missing! You should not see this");
2600  break;
2605  default:
2606  throw HorribleError("parsing got called with invalid option! You should not see this");
2607  }
2608 
2609  auto op_ptr =
2610  std::find_if(std::begin(options_), std::end(options_), [arg_name, current_type](const Option_p &opt) {
2611  if(current_type == detail::Classifier::LONG)
2612  return opt->check_lname(arg_name);
2613  if(current_type == detail::Classifier::SHORT)
2614  return opt->check_sname(arg_name);
2615  // this will only get called for detail::Classifier::WINDOWS
2616  return opt->check_lname(arg_name) || opt->check_sname(arg_name);
2617  });
2618 
2619  // Option not found
2620  if(op_ptr == std::end(options_)) {
2621  for(auto &subc : subcommands_) {
2622  if(subc->name_.empty() && !subc->disabled_) {
2623  if(subc->_parse_arg(args, current_type)) {
2624  if(!subc->pre_parse_called_) {
2625  subc->_trigger_pre_parse(args.size());
2626  }
2627  return true;
2628  }
2629  }
2630  }
2631  // If a subcommand, try the master command
2632  if(parent_ != nullptr && fallthrough_)
2633  return _get_fallthrough_parent()->_parse_arg(args, current_type);
2634  // don't capture missing if this is a nameless subcommand
2635  if(parent_ != nullptr && name_.empty()) {
2636  return false;
2637  }
2638  // Otherwise, add to missing
2639  args.pop_back();
2640  _move_to_missing(current_type, current);
2641  return true;
2642  }
2643 
2644  args.pop_back();
2645 
2646  // Get a reference to the pointer to make syntax bearable
2647  Option_p &op = *op_ptr;
2648 
2649  int min_num = (std::min)(op->get_type_size_min(), op->get_items_expected_min());
2650  int max_num = op->get_items_expected_max();
2651 
2652  // Make sure we always eat the minimum for unlimited vectors
2653  int collected = 0; // total number of arguments collected
2654  int result_count = 0; // local variable for number of results in a single arg string
2655  // deal with purely flag like things
2656  if(max_num == 0) {
2657  auto res = op->get_flag_value(arg_name, value);
2658  op->add_result(res);
2659  parse_order_.push_back(op.get());
2660  } else if(!value.empty()) { // --this=value
2661  op->add_result(value, result_count);
2662  parse_order_.push_back(op.get());
2663  collected += result_count;
2664  // -Trest
2665  } else if(!rest.empty()) {
2666  op->add_result(rest, result_count);
2667  parse_order_.push_back(op.get());
2668  rest = "";
2669  collected += result_count;
2670  }
2671 
2672  // gather the minimum number of arguments
2673  while(min_num > collected && !args.empty()) {
2674  std::string current_ = args.back();
2675  args.pop_back();
2676  op->add_result(current_, result_count);
2677  parse_order_.push_back(op.get());
2678  collected += result_count;
2679  }
2680 
2681  if(min_num > collected) { // if we have run out of arguments and the minimum was not met
2682  throw ArgumentMismatch::TypedAtLeast(op->get_name(), min_num, op->get_type_name());
2683  }
2684 
2685  if(max_num > collected || op->get_allow_extra_args()) { // we allow optional arguments
2686  auto remreqpos = _count_remaining_positionals(true);
2687  // we have met the minimum now optionally check up to the maximum
2688  while((collected < max_num || op->get_allow_extra_args()) && !args.empty() &&
2689  _recognize(args.back(), false) == detail::Classifier::NONE) {
2690  // If any required positionals remain, don't keep eating
2691  if(remreqpos >= args.size()) {
2692  break;
2693  }
2694 
2695  op->add_result(args.back(), result_count);
2696  parse_order_.push_back(op.get());
2697  args.pop_back();
2698  collected += result_count;
2699  }
2700 
2701  // Allow -- to end an unlimited list and "eat" it
2702  if(!args.empty() && _recognize(args.back()) == detail::Classifier::POSITIONAL_MARK)
2703  args.pop_back();
2704  // optional flag that didn't receive anything now get the default value
2705  if(min_num == 0 && max_num > 0 && collected == 0) {
2706  auto res = op->get_flag_value(arg_name, std::string{});
2707  op->add_result(res);
2708  parse_order_.push_back(op.get());
2709  }
2710  }
2711 
2712  // if we only partially completed a type then add an empty string for later processing
2713  if(min_num > 0 && op->get_type_size_max() != min_num && collected % op->get_type_size_max() != 0) {
2714  op->add_result(std::string{});
2715  }
2716 
2717  if(!rest.empty()) {
2718  rest = "-" + rest;
2719  args.push_back(rest);
2720  }
2721  return true;
2722  }
2723 
2725  void _trigger_pre_parse(std::size_t remaining_args) {
2726  if(!pre_parse_called_) {
2727  pre_parse_called_ = true;
2728  if(pre_parse_callback_) {
2729  pre_parse_callback_(remaining_args);
2730  }
2731  } else if(immediate_callback_) {
2732  if(!name_.empty()) {
2733  auto pcnt = parsed_;
2734  auto extras = std::move(missing_);
2735  clear();
2736  parsed_ = pcnt;
2737  pre_parse_called_ = true;
2738  missing_ = std::move(extras);
2739  }
2740  }
2741  }
2742 
2745  if(parent_ == nullptr) {
2746  throw(HorribleError("No Valid parent"));
2747  }
2748  auto fallthrough_parent = parent_;
2749  while((fallthrough_parent->parent_ != nullptr) && (fallthrough_parent->get_name().empty())) {
2750  fallthrough_parent = fallthrough_parent->parent_;
2751  }
2752  return fallthrough_parent;
2753  }
2754 
2756  const std::string &_compare_subcommand_names(const App &subcom, const App &base) const {
2757  static const std::string estring;
2758  if(subcom.disabled_) {
2759  return estring;
2760  }
2761  for(auto &subc : base.subcommands_) {
2762  if(subc.get() != &subcom) {
2763  if(subc->disabled_) {
2764  continue;
2765  }
2766  if(!subcom.get_name().empty()) {
2767  if(subc->check_name(subcom.get_name())) {
2768  return subcom.get_name();
2769  }
2770  }
2771  if(!subc->get_name().empty()) {
2772  if(subcom.check_name(subc->get_name())) {
2773  return subc->get_name();
2774  }
2775  }
2776  for(const auto &les : subcom.aliases_) {
2777  if(subc->check_name(les)) {
2778  return les;
2779  }
2780  }
2781  // this loop is needed in case of ignore_underscore or ignore_case on one but not the other
2782  for(const auto &les : subc->aliases_) {
2783  if(subcom.check_name(les)) {
2784  return les;
2785  }
2786  }
2787  // if the subcommand is an option group we need to check deeper
2788  if(subc->get_name().empty()) {
2789  auto &cmpres = _compare_subcommand_names(subcom, *subc);
2790  if(!cmpres.empty()) {
2791  return cmpres;
2792  }
2793  }
2794  // if the test subcommand is an option group we need to check deeper
2795  if(subcom.get_name().empty()) {
2796  auto &cmpres = _compare_subcommand_names(*subc, subcom);
2797  if(!cmpres.empty()) {
2798  return cmpres;
2799  }
2800  }
2801  }
2802  }
2803  return estring;
2804  }
2806  void _move_to_missing(detail::Classifier val_type, const std::string &val) {
2807  if(allow_extras_ || subcommands_.empty()) {
2808  missing_.emplace_back(val_type, val);
2809  return;
2810  }
2811  // allow extra arguments to be places in an option group if it is allowed there
2812  for(auto &subc : subcommands_) {
2813  if(subc->name_.empty() && subc->allow_extras_) {
2814  subc->missing_.emplace_back(val_type, val);
2815  return;
2816  }
2817  }
2818  // if we haven't found any place to put them yet put them in missing
2819  missing_.emplace_back(val_type, val);
2820  }
2821 
2822  public:
2824  void _move_option(Option *opt, App *app) {
2825  if(opt == nullptr) {
2826  throw OptionNotFound("the option is NULL");
2827  }
2828  // verify that the give app is actually a subcommand
2829  bool found = false;
2830  for(auto &subc : subcommands_) {
2831  if(app == subc.get()) {
2832  found = true;
2833  }
2834  }
2835  if(!found) {
2836  throw OptionNotFound("The Given app is not a subcommand");
2837  }
2838 
2839  if((help_ptr_ == opt) || (help_all_ptr_ == opt))
2840  throw OptionAlreadyAdded("cannot move help options");
2841 
2842  if(config_ptr_ == opt)
2843  throw OptionAlreadyAdded("cannot move config file options");
2844 
2845  auto iterator =
2846  std::find_if(std::begin(options_), std::end(options_), [opt](const Option_p &v) { return v.get() == opt; });
2847  if(iterator != std::end(options_)) {
2848  const auto &opt_p = *iterator;
2849  if(std::find_if(std::begin(app->options_), std::end(app->options_), [&opt_p](const Option_p &v) {
2850  return (*v == *opt_p);
2851  }) == std::end(app->options_)) {
2852  // only erase after the insertion was successful
2853  app->options_.push_back(std::move(*iterator));
2854  options_.erase(iterator);
2855  } else {
2856  throw OptionAlreadyAdded("option was not located: " + opt->get_name());
2857  }
2858  } else {
2859  throw OptionNotFound("could not locate the given Option");
2860  }
2861  }
2862 }; // namespace CLI
2863 
2865 class Option_group : public App {
2866  public:
2867  Option_group(std::string group_description, std::string group_name, App *parent)
2868  : App(std::move(group_description), "", parent) {
2869  group(group_name);
2870  // option groups should have automatic fallthrough
2871  }
2872  using App::add_option;
2875  if(get_parent() == nullptr) {
2876  throw OptionNotFound("Unable to locate the specified option");
2877  }
2878  get_parent()->_move_option(opt, this);
2879  return opt;
2880  }
2882  void add_options(Option *opt) { add_option(opt); }
2884  template <typename... Args> void add_options(Option *opt, Args... args) {
2885  add_option(opt);
2886  add_options(args...);
2887  }
2888  using App::add_subcommand;
2890  App *add_subcommand(App *subcom) {
2891  App_p subc = subcom->get_parent()->get_subcommand_ptr(subcom);
2892  subc->get_parent()->remove_subcommand(subcom);
2893  add_subcommand(std::move(subc));
2894  return subcom;
2895  }
2896 };
2898 inline void TriggerOn(App *trigger_app, App *app_to_enable) {
2899  app_to_enable->enabled_by_default(false);
2900  app_to_enable->disabled_by_default();
2901  trigger_app->preparse_callback([app_to_enable](std::size_t) { app_to_enable->disabled(false); });
2902 }
2903 
2905 inline void TriggerOn(App *trigger_app, std::vector<App *> apps_to_enable) {
2906  for(auto &app : apps_to_enable) {
2907  app->enabled_by_default(false);
2908  app->disabled_by_default();
2909  }
2910 
2911  trigger_app->preparse_callback([apps_to_enable](std::size_t) {
2912  for(auto &app : apps_to_enable) {
2913  app->disabled(false);
2914  }
2915  });
2916 }
2917 
2919 inline void TriggerOff(App *trigger_app, App *app_to_enable) {
2920  app_to_enable->disabled_by_default(false);
2921  app_to_enable->enabled_by_default();
2922  trigger_app->preparse_callback([app_to_enable](std::size_t) { app_to_enable->disabled(); });
2923 }
2924 
2926 inline void TriggerOff(App *trigger_app, std::vector<App *> apps_to_enable) {
2927  for(auto &app : apps_to_enable) {
2928  app->disabled_by_default(false);
2929  app->enabled_by_default();
2930  }
2931 
2932  trigger_app->preparse_callback([apps_to_enable](std::size_t) {
2933  for(auto &app : apps_to_enable) {
2934  app->disabled();
2935  }
2936  });
2937 }
2938 
2940 inline void deprecate_option(Option *opt, const std::string &replacement = "") {
2941  Validator deprecate_warning{[opt, replacement](std::string &) {
2942  std::cout << opt->get_name() << " is deprecated please use '" << replacement
2943  << "' instead\n";
2944  return std::string();
2945  },
2946  "DEPRECATED"};
2947  deprecate_warning.application_index(0);
2948  opt->check(deprecate_warning);
2949  if(!replacement.empty()) {
2950  opt->description(opt->get_description() + " DEPRECATED: please use '" + replacement + "' instead");
2951  }
2952 }
2953 
2955 inline void deprecate_option(App *app, const std::string &option_name, const std::string &replacement = "") {
2956  auto opt = app->get_option(option_name);
2957  deprecate_option(opt, replacement);
2958 }
2959 
2961 inline void deprecate_option(App &app, const std::string &option_name, const std::string &replacement = "") {
2962  auto opt = app.get_option(option_name);
2963  deprecate_option(opt, replacement);
2964 }
2965 
2967 inline void retire_option(App *app, Option *opt) {
2968  App temp;
2969  auto option_copy = temp.add_option(opt->get_name(false, true))
2971  ->expected(opt->get_expected_min(), opt->get_expected_max())
2973 
2974  app->remove_option(opt);
2975  auto opt2 = app->add_option(option_copy->get_name(false, true), "option has been retired and has no effect")
2976  ->type_name("RETIRED")
2977  ->default_str("RETIRED")
2978  ->type_size(option_copy->get_type_size_min(), option_copy->get_type_size_max())
2979  ->expected(option_copy->get_expected_min(), option_copy->get_expected_max())
2980  ->allow_extra_args(option_copy->get_allow_extra_args());
2981 
2982  Validator retired_warning{[opt2](std::string &) {
2983  std::cout << "WARNING " << opt2->get_name() << " is retired and has no effect\n";
2984  return std::string();
2985  },
2986  ""};
2987  retired_warning.application_index(0);
2988  opt2->check(retired_warning);
2989 }
2990 
2992 inline void retire_option(App &app, Option *opt) { retire_option(&app, opt); }
2993 
2995 inline void retire_option(App *app, const std::string &option_name) {
2996 
2997  auto opt = app->get_option_no_throw(option_name);
2998  if(opt != nullptr) {
2999  retire_option(app, opt);
3000  return;
3001  }
3002  auto opt2 = app->add_option(option_name, "option has been retired and has no effect")
3003  ->type_name("RETIRED")
3004  ->expected(0, 1)
3005  ->default_str("RETIRED");
3006  Validator retired_warning{[opt2](std::string &) {
3007  std::cout << "WARNING " << opt2->get_name() << " is retired and has no effect\n";
3008  return std::string();
3009  },
3010  ""};
3011  retired_warning.application_index(0);
3012  opt2->check(retired_warning);
3013 }
3014 
3016 inline void retire_option(App &app, const std::string &option_name) { retire_option(&app, option_name); }
3017 
3018 namespace FailureMessage {
3019 
3021 inline std::string simple(const App *app, const Error &e) {
3022  std::string header = std::string(e.what()) + "\n";
3023  std::vector<std::string> names;
3024 
3025  // Collect names
3026  if(app->get_help_ptr() != nullptr)
3027  names.push_back(app->get_help_ptr()->get_name());
3028 
3029  if(app->get_help_all_ptr() != nullptr)
3030  names.push_back(app->get_help_all_ptr()->get_name());
3031 
3032  // If any names found, suggest those
3033  if(!names.empty())
3034  header += "Run with " + detail::join(names, " or ") + " for more information.\n";
3035 
3036  return header;
3037 }
3038 
3040 inline std::string help(const App *app, const Error &e) {
3041  std::string header = std::string("ERROR: ") + e.get_name() + ": " + e.what() + "\n";
3042  header += app->help();
3043  return header;
3044 }
3045 
3046 } // namespace FailureMessage
3047 
3048 namespace detail {
3050 struct AppFriend {
3051 
3053  template <typename... Args>
3054  static auto parse_arg(App *app, Args &&... args) ->
3055  typename std::result_of<decltype (&App::_parse_arg)(App, Args...)>::type {
3056  return app->_parse_arg(std::forward<Args>(args)...);
3057  }
3058 
3060  template <typename... Args>
3061  static auto parse_subcommand(App *app, Args &&... args) ->
3062  typename std::result_of<decltype (&App::_parse_subcommand)(App, Args...)>::type {
3063  return app->_parse_subcommand(std::forward<Args>(args)...);
3064  }
3066  static App *get_fallthrough_parent(App *app) { return app->_get_fallthrough_parent(); }
3067 };
3068 } // namespace detail
3069 
3070 } // namespace CLI
CLI::App::_compare_subcommand_names
const std::string & _compare_subcommand_names(const App &subcom, const App &base) const
Helper function to run through all possible comparisons of subcommand names to check there is no over...
Definition: App.hpp:2756
CLI::App::allow_windows_style_options
App * allow_windows_style_options(bool value=true)
Definition: App.hpp:472
CLI::App_p
std::shared_ptr< App > App_p
Definition: App.hpp:54
CLI::Option_group::add_subcommand
App * add_subcommand(App *subcom)
Add an existing subcommand to be a member of an option_group.
Definition: App.hpp:2890
CLI::config_extras_mode::error
@ error
CLI::App::get_disabled
bool get_disabled() const
Get the status of disabled.
Definition: App.hpp:1673
CLI::App::fallthrough_
bool fallthrough_
Allow subcommand fallthrough, so that parent commands can collect commands after subcommand....
Definition: App.hpp:189
CLI::App::_process_config_file
void _process_config_file()
Read and process a configuration file (main app only)
Definition: App.hpp:1953
CLI::App::allow_windows_style_options_
bool allow_windows_style_options_
Allow '/' for options for Windows like options. Defaults to true on Windows, false otherwise....
Definition: App.hpp:192
CLI::Option::check_name
bool check_name(std::string name) const
Check a name. Requires "-" or "--" for short / long, supports positional name.
Definition: Option.hpp:836
CLI::App::required
App * required(bool require=true)
Remove the error when extras are left over on the command line.
Definition: App.hpp:380
FormatterFwd.hpp
CLI::App::config_formatter_
std::shared_ptr< Config > config_formatter_
This is the formatter for help printing. Default provided. INHERITABLE (same pointer)
Definition: App.hpp:245
CLI::FailureMessage::help
std::string help(const App *app, const Error &e)
Printout the full help string on error (if this fn is set, the old default for CLI11)
Definition: App.hpp:3040
CLI::ConfigItem::name
std::string name
This is the name.
Definition: ConfigFwd.hpp:24
CLI::App::alias
App * alias(std::string app_name)
Set an alias for the app.
Definition: App.hpp:354
CLI::FileError
Thrown when parsing an INI file and it is missing.
Definition: Error.hpp:175
CLI::App::get_option_no_throw
const Option * get_option_no_throw(std::string option_name) const noexcept
Get an option by name (noexcept const version)
Definition: App.hpp:1585
CLI::Option_group::add_options
void add_options(Option *opt)
Add an existing option to the Option_group.
Definition: App.hpp:2882
CLI::App::name_
std::string name_
Subcommand name or program name (from parser if name is empty)
Definition: App.hpp:72
CLI::App::option_defaults_
OptionDefaults option_defaults_
The default values for options, customizable and changeable INHERITABLE.
Definition: App.hpp:116
CLI::detail::Classifier::SUBCOMMAND
@ SUBCOMMAND
CLI::OptionBase::get_required
bool get_required() const
True if this is a required option.
Definition: Option.hpp:115
CLI::App::operator=
App & operator=(const App &)=delete
CLI::detail::Classifier::WINDOWS
@ WINDOWS
CLI::App::remove_excludes
bool remove_excludes(App *app)
Removes a subcommand from the excludes list of this subcommand.
Definition: App.hpp:1441
CLI::detail::AppFriend
This class is simply to allow tests access to App's protected functions.
Definition: App.hpp:3050
CLI::detail::enabler
enabler
Simple empty scoped class.
Definition: TypeTools.hpp:22
CLI::App::prefix_command_
bool prefix_command_
If true, return immediately on an unrecognized option (implies allow_extras) INHERITABLE.
Definition: App.hpp:85
CLI::detail::expected_max_vector_size
constexpr int expected_max_vector_size
Definition: StringTools.hpp:36
CLI::App::get_help_ptr
Option * get_help_ptr()
Get a pointer to the help flag.
Definition: App.hpp:1690
CLI::App::missing_
missing_t missing_
Definition: App.hpp:152
CLI::App::_configure
void _configure()
Definition: App.hpp:1866
CLI::App::allow_config_extras
App * allow_config_extras(bool allow=true)
ignore extras in config files
Definition: App.hpp:433
CLI::App::get_options
std::vector< const Option * > get_options(const std::function< bool(const Option *)> filter={}) const
Get the list of options (user facing function, so returns raw pointers), has optional filter function...
Definition: App.hpp:1533
CLI::App::need_subcommands_
std::set< App * > need_subcommands_
Definition: App.hpp:169
CLI::ExcludesError
Thrown when an excludes option is present.
Definition: Error.hpp:276
CLI::App::remaining_for_passthrough
std::vector< std::string > remaining_for_passthrough(bool recurse=false) const
This returns the missing options in a form ready for processing by another command line program.
Definition: App.hpp:1799
CLI::App::add_subcommand
App * add_subcommand(CLI::App_p subcom)
Add a previously created app as a subcommand.
Definition: App.hpp:994
CLI::Validator
Some validators that are provided.
Definition: Validators.hpp:61
CLI::App::ignore_underscore_
bool ignore_underscore_
If true, the program should ignore underscores INHERITABLE.
Definition: App.hpp:186
Error.hpp
CLI::App::get_subcommand
App * get_subcommand(std::string subcom) const
Check to see if a subcommand is part of this command (text version)
Definition: App.hpp:1035
CLI::AppFormatMode::Normal
@ Normal
CLI::App::add_subcommand
App * add_subcommand(std::string subcommand_name="", std::string subcommand_description="")
Add a subcommand. Inherits INHERITABLE and OptionDefaults, and help flag.
Definition: App.hpp:985
CLI::CallForHelp
-h or –help on command line
Definition: Error.hpp:156
CLI::App::formatter_fn
App * formatter_fn(std::function< std::string(const App *, std::string, AppFormatMode)> fmt)
Set the help formatter.
Definition: App.hpp:511
CLI::Option::default_flag_values_
std::vector< std::pair< std::string, std::string > > default_flag_values_
Definition: Option.hpp:243
CLI::App::get_immediate_callback
bool get_immediate_callback() const
Get the status of disabled.
Definition: App.hpp:1676
CLI::App::get_option
const Option * get_option(std::string option_name) const
Get an option by name.
Definition: App.hpp:1604
CLI::App::remove_needs
bool remove_needs(App *app)
Removes a subcommand from the needs list of this subcommand.
Definition: App.hpp:1463
CLI::App::set_config
Option * set_config(std::string option_name="", std::string default_filename="", const std::string &help_message="Read an ini file", bool config_required=false)
Set a configuration ini file option, or clear it if no name passed.
Definition: App.hpp:921
CLI::App::add_option
Option * add_option(std::string option_name, callback_t option_callback, std::string option_description="", bool defaulted=false, std::function< std::string()> func={})
Definition: App.hpp:546
CLI::App::_recognize
detail::Classifier _recognize(const std::string &current, bool ignore_used_subcommands=true) const
Selects a Classifier enum based on the type of the current argument.
Definition: App.hpp:1926
CLI::App::immediate_callback
App * immediate_callback(bool immediate=true)
Set the subcommand callback to be executed immediately on subcommand completion.
Definition: App.hpp:414
CLI::App::require_subcommand_max_
std::size_t require_subcommand_max_
Max number of subcommands allowed (parsing stops after this number). 0 is unlimited INHERITABLE.
Definition: App.hpp:223
CLI::Option_group::add_options
void add_options(Option *opt, Args... args)
Add a bunch of options to the group.
Definition: App.hpp:2884
CLI::App::exit
int exit(const Error &e, std::ostream &out=std::cout, std::ostream &err=std::cerr) const
Print a nice error message and return the exit code.
Definition: App.hpp:1307
CLI::ExitCodes::Success
@ Success
CLI::App::get_allow_config_extras
config_extras_mode get_allow_config_extras() const
Get the status of allow extras.
Definition: App.hpp:1687
CLI::App::footer
App * footer(std::string footer_string)
Set footer.
Definition: App.hpp:1477
CLI::Option::description
Option * description(std::string option_description)
Set the description.
Definition: Option.hpp:714
CLI::App::require_subcommand
App * require_subcommand(int value)
Definition: App.hpp:1126
CLI::App::add_option_function
Option * add_option_function(std::string option_name, const std::function< void(const T &)> &func, std::string option_description="")
Add option for a callback of a specific type.
Definition: App.hpp:616
CLI::App::config_ptr_
Option * config_ptr_
Pointer to the config option.
Definition: App.hpp:242
CLI::retire_option
void retire_option(App *app, Option *opt)
Helper function to mark an option as retired.
Definition: App.hpp:2967
CLI::App::excludes
App * excludes(App *app)
Sets excluded subcommands for the subcommand.
Definition: App.hpp:1396
CLI::App::validate_positionals
App * validate_positionals(bool validate=true)
Set the subcommand to validate positional arguments before assigning.
Definition: App.hpp:427
CLI::App::got_subcommand
bool got_subcommand(const App *subcom) const
Check to see if given subcommand was selected.
Definition: App.hpp:1378
CLI::App::parse
void parse(int argc, const char *const *argv)
Definition: App.hpp:1216
CLI::App::count
std::size_t count() const
Definition: App.hpp:1092
CLI::App::get_aliases
const std::vector< std::string > & get_aliases() const
Get the aliases of the current app.
Definition: App.hpp:1714
CLI::Option::fnames_
std::vector< std::string > fnames_
a list of flag names with specified default values;
Definition: Option.hpp:246
CLI::App::get_enabled_by_default
bool get_enabled_by_default() const
Get the status of disabled by default.
Definition: App.hpp:1682
CLI::App::get_ignore_underscore
bool get_ignore_underscore() const
Check the status of ignore_underscore.
Definition: App.hpp:1631
CLI::App::get_name
const std::string & get_name() const
Get the name of the current app.
Definition: App.hpp:1711
CLI::App::add_set
Option * add_set(std::string option_name, T &member, std::set< T > options, std::string option_description="")
Add set of options (No default, temp reference, such as an inline set) DEPRECATED.
Definition: App.hpp:822
CLI::App::ignore_underscore
App * ignore_underscore(bool value=true)
Ignore underscore. Subcommands inherit value.
Definition: App.hpp:490
CLI::config_extras_mode
config_extras_mode
enumeration of modes of how to deal with extras in config files
Definition: App.hpp:50
CLI::App::remove_option
bool remove_option(Option *opt)
Removes an option from the App. Takes an option pointer. Returns true if found and removed.
Definition: App.hpp:948
CLI::Option::get_type_size_max
int get_type_size_max() const
The maximum number of arguments the option expects.
Definition: Option.hpp:656
CLI::App::positionals_at_end
App * positionals_at_end(bool value=true)
Specify that the positional arguments are only at the end of the sequence.
Definition: App.hpp:478
CLI::App::get_display_name
std::string get_display_name() const
Get a display name for an app.
Definition: App.hpp:1723
CLI::App::final_callback
App * final_callback(std::function< void()> app_callback)
Definition: App.hpp:316
CLI::App::increment_parsed
void increment_parsed()
Internal function to recursively increment the parsed counter on the current app as well unnamed subc...
Definition: App.hpp:2234
TypeTools.hpp
CLI::Option::get_type_size_min
int get_type_size_min() const
The minimum number of arguments the option expects.
Definition: Option.hpp:654
CLI::App::get_config_ptr
const Option * get_config_ptr() const
Get a pointer to the config option. (const)
Definition: App.hpp:1702
CLI::detail::AppFriend::parse_arg
static auto parse_arg(App *app, Args &&... args) -> typename std::result_of< decltype(&App::_parse_arg)(App, Args...)>::type
Wrap _parse_short, perfectly forward arguments and return.
Definition: App.hpp:3054
CLI::App::needs
App * needs(Option *opt)
Definition: App.hpp:1411
CLI::App::get_group
const std::string & get_group() const
Get the group of this subcommand.
Definition: App.hpp:1646
CLI::ExtrasError
Thrown when too many positionals or options are found.
Definition: Error.hpp:283
CLI::App::startup_mode::disabled
@ disabled
CLI::App::name
App * name(std::string app_name="")
Set a name for the app (empty will use parser to set the name)
Definition: App.hpp:336
CLI::Option::get_positional
bool get_positional() const
True if the argument can be given directly.
Definition: Option.hpp:702
CLI::App::require_option
App * require_option(int value)
Definition: App.hpp:1155
CLI::OptionBase::get_configurable
bool get_configurable() const
The status of configurable.
Definition: Option.hpp:124
CLI::App::_process_requirements
void _process_requirements()
Verify required options and cross requirements. Subcommands too (only if selected).
Definition: App.hpp:2067
CLI::App::get_subcommand
App * get_subcommand(int index=0) const
Get a pointer to subcommand by index.
Definition: App.hpp:1042
CLI::App::parsed_
std::size_t parsed_
Counts the number of times this command/subcommand was parsed.
Definition: App.hpp:217
CLI::App::_parse_config
void _parse_config(std::vector< ConfigItem > &args)
Definition: App.hpp:2291
CLI::App::pre_parse_callback_
std::function< void(std::size_t)> pre_parse_callback_
This is a function that runs prior to the start of parsing.
Definition: App.hpp:104
CLI::MultiOptionPolicy::TakeLast
@ TakeLast
take only the last Expected number of arguments
CLI::App::missing_t
std::vector< std::pair< detail::Classifier, std::string > > missing_t
Definition: App.hpp:147
CLI::Option::count
std::size_t count() const
Count the total number of times an option was passed.
Definition: Option.hpp:345
CLI::App::startup_mode
startup_mode
Definition: App.hpp:202
CLI::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: TypeTools.hpp:33
CLI::App::add_option
Option * add_option(std::string option_name, AssignTo &variable, std::string option_description="", bool defaulted=false)
Add option for assigning to a variable.
Definition: App.hpp:591
CLI::App::get_subcommand_ptr
CLI::App_p get_subcommand_ptr(std::string subcom) const
Check to see if a subcommand is part of this command (text version)
Definition: App.hpp:1062
CLI::App::get_disabled_by_default
bool get_disabled_by_default() const
Get the status of disabled by default.
Definition: App.hpp:1679
CLI::detail::get_default_flag_values
std::vector< std::pair< std::string, std::string > > get_default_flag_values(const std::string &str)
extract default flag values either {def} or starting with a !
Definition: Split.hpp:71
CLI::Option::needs_
std::set< Option * > needs_
A list of options that are required with this option.
Definition: Option.hpp:291
CLI::TriggerOff
void TriggerOff(App *trigger_app, App *app_to_enable)
Helper function to disable one option group/subcommand when another is used.
Definition: App.hpp:2919
CLI::detail::Classifier::POSITIONAL_MARK
@ POSITIONAL_MARK
CLI::App::_validate
void _validate() const
Definition: App.hpp:1827
CLI::Option::type_size
Option * type_size(int option_type_size)
Set a custom option size.
Definition: Option.hpp:1022
CLI::App::excludes
App * excludes(Option *opt)
Sets excluded options for the subcommand.
Definition: App.hpp:1387
CLI::Option_group
Extension of App to better manage groups of options.
Definition: App.hpp:2865
CLI::App::required_
bool required_
If set to true the subcommand is required to be processed and used, ignored for main app.
Definition: App.hpp:91
CLI::App::parse
void parse(std::vector< std::string > &&args)
The real work is done here. Expects a reversed vector.
Definition: App.hpp:1282
CLI::App::footer
App * footer(std::function< std::string()> footer_function)
Set footer.
Definition: App.hpp:1482
CLI::App::add_flag
Option * add_flag(std::string flag_name, T &flag_result, std::string flag_description="")
Definition: App.hpp:751
CLI::App::get_option_no_throw
Option * get_option_no_throw(std::string option_name) noexcept
Get an option by name (noexcept non-const version)
Definition: App.hpp:1566
CLI::Option::get_name
std::string get_name(bool positional=false, bool all_options=false) const
Gets a comma separated list of names. Will include / prefer the positional name if positional is true...
Definition: Option.hpp:727
CLI::Option::expected
Option * expected(int value)
Set the number of expected arguments.
Definition: Option.hpp:364
CLI::App::check_name
bool check_name(std::string name_to_check) const
Check the name, case insensitive and underscore insensitive if set.
Definition: App.hpp:1726
CLI::App::add_mutable_set
Option * add_mutable_set(std::string option_name, T &member, const std::set< T > &options, std::string option_description, bool defaulted)
Add set of options (with default, set can be changed afterwards - do not destroy the set) DEPRECATED.
Definition: App.hpp:859
CLI::App::~App
virtual ~App()=default
virtual destructor
CLI::App::add_flag
Option * add_flag(std::string flag_name, std::vector< T > &flag_results, std::string flag_description="")
Vector version to capture multiple flags.
Definition: App.hpp:764
CLI::App::get_subcommands
std::vector< App * > get_subcommands(const std::function< bool(App *)> &filter)
Definition: App.hpp:1362
CLI::App::require_subcommand
App * require_subcommand(std::size_t min, std::size_t max)
Definition: App.hpp:1139
CLI::App::set_help_flag
Option * set_help_flag(std::string flag_name="", const std::string &help_description="")
Set a help flag, replace the existing one if present.
Definition: App.hpp:650
CLI::Option::get_expected_max
int get_expected_max() const
The max number of times the option expects to be included.
Definition: Option.hpp:688
CLI::detail::AppFriend::get_fallthrough_parent
static App * get_fallthrough_parent(App *app)
Wrap the fallthrough parent function to make sure that is working correctly.
Definition: App.hpp:3066
CLI::config_extras_mode::ignore
@ ignore
CLI::ExitCodes::OptionAlreadyAdded
@ OptionAlreadyAdded
CLI::detail::join
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
Definition: StringTools.hpp:56
CLI::App::count
std::size_t count(std::string option_name) const
Counts the number of times the given option was passed.
Definition: App.hpp:1336
CLI::App::_valid_subcommand
bool _valid_subcommand(const std::string &current, bool ignore_used=true) const
Check to see if a subcommand is valid. Give up immediately if subcommand max has been reached.
Definition: App.hpp:1912
CLI::App::allow_config_extras_
config_extras_mode allow_config_extras_
Definition: App.hpp:82
CLI::Validator::get_name
const std::string & get_name() const
Get the name of the Validator.
Definition: Validators.hpp:143
CLI::App::get_allow_windows_style_options
bool get_allow_windows_style_options() const
Check the status of the allow windows style options.
Definition: App.hpp:1637
CLI::Option::excludes_
std::set< Option * > excludes_
A list of options that are excluded with this option.
Definition: Option.hpp:294
CLI::App::run_callback
void run_callback(bool final_mode=false)
Internal function to run (App) callback, bottom up.
Definition: App.hpp:1886
CLI::ConfigItem::fullname
std::string fullname() const
The list of parents and name joined by ".".
Definition: ConfigFwd.hpp:30
CLI::App::parsed_subcommands_
std::vector< App * > parsed_subcommands_
This is a list of the subcommands collected, in order.
Definition: App.hpp:158
CLI::detail::check_path
path_type check_path(const char *file) noexcept
get the type of the path from a file name
Definition: Validators.hpp:308
CLI::App::get_formatter
std::shared_ptr< FormatterBase > get_formatter() const
Access the formatter.
Definition: App.hpp:1513
CLI::App::parse_complete_callback
App * parse_complete_callback(std::function< void()> pc_callback)
Definition: App.hpp:323
CLI::App::_get_fallthrough_parent
App * _get_fallthrough_parent()
Get the appropriate parent to fallthrough to which is the first one that has a name or the main app.
Definition: App.hpp:2744
CLI::App::formatter_
std::shared_ptr< FormatterBase > formatter_
This is the formatter for help printing. Default provided. INHERITABLE (same pointer)
Definition: App.hpp:138
CLI::App::startup_mode::enabled
@ enabled
CLI::detail::to_string
auto to_string(T &&value) -> decltype(std::forward< T >(value))
Convert an object to a string (directly forward if this can become a string)
Definition: TypeTools.hpp:222
CLI::Error::get_exit_code
int get_exit_code() const
Definition: Error.hpp:68
CLI::Option::envname_
std::string envname_
If given, check the environment for this option.
Definition: Option.hpp:252
CLI::App::ignore_case_
bool ignore_case_
If true, the program name is not case sensitive INHERITABLE.
Definition: App.hpp:183
CLI::RuntimeError
Does not output a diagnostic in CLI11_PARSE, but allows to return from main() with a specific error c...
Definition: Error.hpp:169
CLI::detail::lexical_cast
bool lexical_cast(const std::string &input, T &output)
Signed integers.
Definition: TypeTools.hpp:596
CLI::MultiOptionPolicy::TakeAll
@ TakeAll
just get all the passed argument regardless
CLI::App::parse
void parse(std::string commandline, bool program_name_included=false)
Definition: App.hpp:1234
CLI::App::disabled_by_default
App * disabled_by_default(bool disable=true)
Set the subcommand to be disabled by default, so on clear(), at the start of each parse it is disable...
Definition: App.hpp:392
CLI::App::get_configurable
bool get_configurable() const
Check the status of the allow windows style options.
Definition: App.hpp:1643
CLI::App::get_required
bool get_required() const
Get the status of required.
Definition: App.hpp:1670
CLI::App::failure_message_
std::function< std::string(const App *, const Error &e)> failure_message_
The error message printing function INHERITABLE.
Definition: App.hpp:141
CLI::App::group
App * group(std::string group_name)
Changes the group membership.
Definition: App.hpp:1111
CLI
Definition: App.hpp:27
CLI::App::configurable_
bool configurable_
if set to true the subcommand can be triggered via configuration files INHERITABLE
Definition: App.hpp:208
CLI::detail::valid_name_string
bool valid_name_string(const std::string &str)
Verify an option name.
Definition: StringTools.hpp:181
CLI::App::get_help_all_ptr
const Option * get_help_all_ptr() const
Get a pointer to the help all flag. (const)
Definition: App.hpp:1696
CLI::App::_process
void _process()
Process callbacks and such.
Definition: App.hpp:2193
CLI::App::require_option_max_
std::size_t require_option_max_
Max number of options allowed. 0 is unlimited (not inheritable)
Definition: App.hpp:229
CLI::App::got_subcommand
bool got_subcommand(std::string subcommand_name) const
Check with name instead of pointer to see if subcommand was selected.
Definition: App.hpp:1384
CLI::App::get_require_subcommand_min
std::size_t get_require_subcommand_min() const
Get the required min subcommand value.
Definition: App.hpp:1652
CLI::detail::split_up
std::vector< std::string > split_up(std::string str, char delimiter='\0')
Definition: StringTools.hpp:282
CLI::App::clear_aliases
App * clear_aliases()
clear all the aliases of the current App
Definition: App.hpp:1717
CLI::App::_process_help_flags
void _process_help_flags(bool trigger_help=false, bool trigger_all_help=false) const
Definition: App.hpp:2044
CLI::App::get_allow_extras
bool get_allow_extras() const
Get the status of allow extras.
Definition: App.hpp:1667
CLI::detail::split_program_name
std::pair< std::string, std::string > split_program_name(std::string commandline)
Definition: Validators.hpp:1100
CLI::App::final_callback_
std::function< void()> final_callback_
This is a function that runs when all processing has completed.
Definition: App.hpp:109
CLI::App::immediate_callback_
bool immediate_callback_
Definition: App.hpp:101
CLI::App::get_option_group
App * get_option_group(std::string group_name) const
Check to see if an option group is part of this App.
Definition: App.hpp:1080
CLI::App::_move_option
void _move_option(Option *opt, App *app)
function that could be used by subclasses of App to shift options around into subcommands
Definition: App.hpp:2824
CLI::OptionBase::copy_to
void copy_to(T *other) const
Copy the contents to another similar class (one based on OptionBase)
Definition: Option.hpp:74
CLI::detail::dummy
constexpr enabler dummy
An instance to use in EnableIf.
Definition: TypeTools.hpp:25
CLI::FailureMessage::simple
std::string simple(const App *app, const Error &e)
Printout a clean, simple message on error (the default in CLI11 1.5+)
Definition: App.hpp:3021
CLI::App::exclude_subcommands_
std::set< App * > exclude_subcommands_
this is a list of subcommands that are exclusionary to this one
Definition: App.hpp:161
CLI::App::prefix_command
App * prefix_command(bool allow=true)
Do not parse anything after the first unrecognized option and return.
Definition: App.hpp:450
CLI::App::get_prefix_command
bool get_prefix_command() const
Get the prefix command status.
Definition: App.hpp:1664
CLI::Error::get_name
std::string get_name() const
Definition: Error.hpp:70
CLI::App::require_subcommand_min_
std::size_t require_subcommand_min_
Minimum required subcommands (not inheritable!)
Definition: App.hpp:220
CLI::App::_find_subcommand
App * _find_subcommand(const std::string &subc_name, bool ignore_disabled, bool ignore_used) const noexcept
Definition: App.hpp:2532
CLI::App::positionals_at_end_
bool positionals_at_end_
specify that positional arguments come at the end of the argument sequence not inheritable
Definition: App.hpp:200
CLI::ConfigItem::inputs
std::vector< std::string > inputs
Listing of inputs.
Definition: ConfigFwd.hpp:27
CLI::OptionBase::delimiter
CRTP * delimiter(char value='\0')
Allow in a configuration file.
Definition: Option.hpp:183
CLI::detail::split_short
bool split_short(const std::string &current, std::string &name, std::string &rest)
Definition: Split.hpp:17
CLI::App::has_automatic_name_
bool has_automatic_name_
If set to true the name was automatically generated from the command line vs a user set name.
Definition: App.hpp:88
CLI::Option::check
Option * check(Validator validator, const std::string &validator_name="")
Adds a Validator with a built in type name.
Definition: Option.hpp:423
CLI::App::get_subcommand
App * get_subcommand(const App *subcom) const
Definition: App.hpp:1025
CLI::App::get_groups
std::vector< std::string > get_groups() const
Get the groups available directly from this option (in order)
Definition: App.hpp:1755
CLI::App::config_formatter
App * config_formatter(std::shared_ptr< Config > fmt)
Set the config formatter.
Definition: App.hpp:517
CLI::App::startup_mode::stable
@ stable
CLI::App::get_config_formatter_base
std::shared_ptr< ConfigBase > get_config_formatter_base() const
Access the config formatter as a configBase pointer.
Definition: App.hpp:1519
CLI::App::fallthrough
App * fallthrough(bool value=true)
Definition: App.hpp:1176
CLI::App::require_option
App * require_option()
The argumentless form of require option requires 1 or more options be used.
Definition: App.hpp:1146
CLI::App::require_option
App * require_option(std::size_t min, std::size_t max)
Definition: App.hpp:1168
CLI::App::set_help_all_flag
Option * set_help_all_flag(std::string help_name="", const std::string &help_description="")
Set a help all flag, replaced the existing one if present.
Definition: App.hpp:667
CLI::detail::find_and_modify
std::string find_and_modify(std::string str, std::string trigger, Callable modify)
Definition: StringTools.hpp:272
CLI::App::pre_callback
virtual void pre_callback()
Definition: App.hpp:1192
CLI::detail::path_type::file
@ file
CLI::App::failure_message
void failure_message(std::function< std::string(const App *, const Error &e)> function)
Provide a function to print a help message. The function gets access to the App pointer and error.
Definition: App.hpp:1302
CLI::App::get_config_formatter
std::shared_ptr< Config > get_config_formatter() const
Access the config formatter.
Definition: App.hpp:1516
CLI::App::get_require_subcommand_max
std::size_t get_require_subcommand_max() const
Get the required max subcommand value.
Definition: App.hpp:1655
CLI::App::remaining
std::vector< std::string > remaining(bool recurse=false) const
This returns the missing options from the current subcommand.
Definition: App.hpp:1772
CLI::Error
All errors derive from this one.
Definition: Error.hpp:63
CLI::OptionAlreadyAdded
Thrown when an option already exists.
Definition: Error.hpp:128
CLI::App::aliases_
std::vector< std::string > aliases_
Alias names for the subcommand.
Definition: App.hpp:235
CLI::detail::remove_default_flag_values
void remove_default_flag_values(std::string &flags)
Definition: StringTools.hpp:227
CLI::App::add_option
Option * add_option(std::string option_name, T &option_description)
Add option with description but with no variable assignment or callback.
Definition: App.hpp:645
CLI::App::clear
void clear()
Reset the parsed data.
Definition: App.hpp:1199
ConfigFwd.hpp
CLI::Option::get_flag_value
std::string get_flag_value(const std::string &name, std::string input_value) const
Definition: Option.hpp:875
CLI::App::get_description
std::string get_description() const
Get the app or subcommand description.
Definition: App.hpp:1524
CLI::App::get_require_option_min
std::size_t get_require_option_min() const
Get the required min option value.
Definition: App.hpp:1658
CLI::App::subcommands_
std::vector< App_p > subcommands_
Storage for subcommand list.
Definition: App.hpp:180
CLI::callback_t
std::function< bool(const results_t &)> callback_t
callback function definition
Definition: Option.hpp:25
CLI::App::remove_excludes
bool remove_excludes(Option *opt)
Removes an option from the excludes list of this subcommand.
Definition: App.hpp:1431
CLI::App::_count_remaining_positionals
std::size_t _count_remaining_positionals(bool required_only=false) const
Count the required remaining positional arguments.
Definition: App.hpp:2404
CLI::App::disabled_
bool disabled_
If set to true the subcommand is disabled and cannot be used, ignored for main app.
Definition: App.hpp:94
CLI::App::_parse_subcommand
bool _parse_subcommand(std::vector< std::string > &args)
Definition: App.hpp:2554
CLI::Option
Definition: Option.hpp:228
CLI::App::allow_extras
App * allow_extras(bool allow=true)
Remove the error when extras are left over on the command line.
Definition: App.hpp:374
CLI::App::get_footer
std::string get_footer() const
Generate and return the footer.
Definition: App.hpp:1649
CLI::App::get_require_option_max
std::size_t get_require_option_max() const
Get the required max option value.
Definition: App.hpp:1661
CLI::detail::to_lower
std::string to_lower(std::string str)
Return a lower case version of a string.
Definition: StringTools.hpp:196
CLI::App::App
App(std::string app_description="", std::string app_name="")
Create a new program. Pass in the same arguments as main(), along with a help string.
Definition: App.hpp:288
CLI::App::add_flag_function
Option * add_flag_function(std::string flag_name, std::function< void(int64_t)> function, std::string flag_description="")
Add option for callback with an integer value.
Definition: App.hpp:797
CLI::App::config_to_str
std::string config_to_str(bool default_also=false, bool write_description=false) const
Definition: App.hpp:1488
CLI::Formatter
Definition: FormatterFwd.hpp:109
CLI::ExitCodes::InvalidError
@ InvalidError
CLI::Option::type_name
Option * type_name(std::string typeval)
Set a custom option typestring.
Definition: Option.hpp:1016
CLI::App::operator[]
const Option * operator[](const char *option_name) const
Shortcut bracket operator for getting a pointer to an option.
Definition: App.hpp:1625
CLI::detail::split_windows_style
bool split_windows_style(const std::string &current, std::string &name, std::string &value)
Definition: Split.hpp:43
CLI::App::get_parent
const App * get_parent() const
Get the parent of this subcommand (or nullptr if master app) (const version)
Definition: App.hpp:1708
CLI::App::add_option
Option * add_option(std::string option_name)
Add option with no description or variable assignment.
Definition: App.hpp:637
CLI::App::add_flag
Option * add_flag(std::string flag_name, T &flag_count, std::string flag_description="")
Definition: App.hpp:728
CLI::App::default_startup
startup_mode default_startup
Definition: App.hpp:205
CLI::App::needs
App * needs(App *app)
Definition: App.hpp:1419
CLI::Option::multi_option_policy
Option * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times (or another policy)
Definition: Option.hpp:628
CLI::is_bool
Check to see if something is bool (fail check by default)
Definition: TypeTools.hpp:54
CLI::ConfigINI
ConfigBase ConfigINI
the default Config is the INI file format
Definition: ConfigFwd.hpp:113
CLI::detail::remove_underscore
std::string remove_underscore(std::string str)
remove underscores from a string
Definition: StringTools.hpp:204
CLI::IsMember
Verify items are in a set.
Definition: Validators.hpp:684
CLI::App::get_ignore_case
bool get_ignore_case() const
Check the status of ignore_case.
Definition: App.hpp:1628
CLI::App::parse
void parse(std::vector< std::string > &args)
Definition: App.hpp:1262
CLI::App::require_option_min_
std::size_t require_option_min_
Minimum required options (not inheritable!)
Definition: App.hpp:226
CLI::App::preparse_callback
App * preparse_callback(std::function< void(std::size_t)> pp_callback)
Definition: App.hpp:330
CLI::Option::run_callback_for_default
Option * run_callback_for_default(bool value=true)
Definition: Option.hpp:415
CLI::App::remove_needs
bool remove_needs(Option *opt)
Removes an option from the needs list of this subcommand.
Definition: App.hpp:1453
Option.hpp
CLI::App::parent_
App * parent_
A pointer to the parent if this is a subcommand.
Definition: App.hpp:214
CLI::AppFormatMode
AppFormatMode
Definition: FormatterFwd.hpp:22
CLI::Option::get_description
const std::string & get_description() const
Get the description.
Definition: Option.hpp:711
StringTools.hpp
CLI::App::parse_order_
std::vector< Option * > parse_order_
This is a list of pointers to options with the original parse order.
Definition: App.hpp:155
CLI::Option::get_callback_run
bool get_callback_run() const
See if the callback has been run already.
Definition: Option.hpp:1003
CLI::App::get_subcommands
std::vector< App * > get_subcommands() const
Definition: App.hpp:1340
CLI::Option_group::add_option
Option * add_option(Option *opt)
Add an existing option to the Option_group.
Definition: App.hpp:2874
CLI::detail::trim
std::string & trim(std::string &str)
Trim whitespace from string.
Definition: StringTools.hpp:127
CLI::config_extras_mode::capture
@ capture
CLI::App::footer_
std::string footer_
Footer to put after all options in the help output INHERITABLE.
Definition: App.hpp:126
CLI::App::description_
std::string description_
Description of the current program/subcommand.
Definition: App.hpp:75
CLI::App::options_
std::vector< Option_p > options_
The list of options, stored locally.
Definition: App.hpp:119
Macros.hpp
CLI::App::need_options_
std::set< Option * > need_options_
Definition: App.hpp:173
CLI::results_t
std::vector< std::string > results_t
Definition: Option.hpp:23
CLI::App::get_config_ptr
Option * get_config_ptr()
Get a pointer to the config option.
Definition: App.hpp:1699
CLI::App
Creates a command line program, with very few defaults.
Definition: App.hpp:61
CLI::App::exclude_options_
std::set< Option * > exclude_options_
Definition: App.hpp:165
CLI::App::_parse
void _parse(std::vector< std::string > &&args)
Internal parse function.
Definition: App.hpp:2271
CLI::AppFormatMode::All
@ All
CLI::InvalidError
Thrown when validation fails before parsing.
Definition: Error.hpp:309
CLI::App::_parse_single_config
bool _parse_single_config(const ConfigItem &item, std::size_t level=0)
Fill in a single config option.
Definition: App.hpp:2299
CLI::App::formatter
App * formatter(std::shared_ptr< FormatterBase > fmt)
Set the help formatter.
Definition: App.hpp:505
CLI::OptionBase::required_
bool required_
True if this is a required option.
Definition: Option.hpp:50
CLI::App::_trigger_pre_parse
void _trigger_pre_parse(std::size_t remaining_args)
Trigger the pre_parse callback if needed.
Definition: App.hpp:2725
CLI::Option::as
T as() const
Return the results as the specified type.
Definition: Option.hpp:996
CLI::App::parsed
bool parsed() const
Check to see if this subcommand was parsed, true only if received on command line.
Definition: App.hpp:523
CLI::App::_parse_single
bool _parse_single(std::vector< std::string > &args, bool &positional_only)
Definition: App.hpp:2361
CLI::OptionDefaults
Definition: Option.hpp:191
Split.hpp
CLI::App::operator[]
const Option * operator[](const std::string &option_name) const
Shortcut bracket operator for getting a pointer to an option.
Definition: App.hpp:1622
CLI::OptionBase::get_group
const std::string & get_group() const
Get the group of this option.
Definition: Option.hpp:112
CLI::detail::Classifier::SHORT
@ SHORT
CLI::deprecate_option
void deprecate_option(Option *opt, const std::string &replacement="")
Helper function to mark an option as deprecated.
Definition: App.hpp:2940
CLI::App::parse_order
const std::vector< Option * > & parse_order() const
This gets a vector of pointers with the original parse order.
Definition: App.hpp:1769
CLI::OptionBase::configurable
CRTP * configurable(bool value=true)
Allow in a configuration file.
Definition: Option.hpp:177
CLI::App::_process_extras
void _process_extras()
Throw an error if anything is left over and should not be.
Definition: App.hpp:2202
CLI::Option::default_str
Option * default_str(std::string val)
Set the default value string representation (does not change the contained value)
Definition: Option.hpp:1075
CLI::Option_p
std::unique_ptr< Option > Option_p
Definition: Option.hpp:30
CLI::App::add_option_group
T * add_option_group(std::string group_name, std::string group_description="")
creates an option group as part of the given app
Definition: App.hpp:971
CLI::App::_process_callbacks
void _process_callbacks()
Process callbacks. Runs on all subcommands.
Definition: App.hpp:2017
CLI::App::_parse_positional
bool _parse_positional(std::vector< std::string > &args, bool haltOnSubcommand)
Definition: App.hpp:2431
CLI::App::_parse_arg
bool _parse_arg(std::vector< std::string > &args, detail::Classifier current_type)
Definition: App.hpp:2580
CLI::App::get_validate_positionals
bool get_validate_positionals() const
Get the status of validating positionals.
Definition: App.hpp:1684
CLI::App::remove_subcommand
bool remove_subcommand(App *subcom)
Removes a subcommand from the App. Takes a subcommand pointer. Returns true if found and removed.
Definition: App.hpp:1008
CLI::App::ignore_case
App * ignore_case(bool value=true)
Ignore case. Subcommands inherit value.
Definition: App.hpp:456
CLI::App::add_complex
Option * add_complex(std::string option_name, T &variable, std::string option_description="", bool defaulted=false, std::string label="COMPLEX")
Add a complex number.
Definition: App.hpp:872
CLI::Option::empty
bool empty() const
True if the option was not passed.
Definition: Option.hpp:348
CLI::Option::get_items_expected_min
int get_items_expected_min() const
The total min number of expected string values to be used.
Definition: Option.hpp:691
CLI::detail::expected_count
This will only trigger for actual void type.
Definition: TypeTools.hpp:318
CLI::App::get_subcommands
std::vector< const App * > get_subcommands(const std::function< bool(const App *)> &filter) const
Definition: App.hpp:1344
CLI::App::_move_to_missing
void _move_to_missing(detail::Classifier val_type, const std::string &val)
Helper function to place extra values in the most appropriate position.
Definition: App.hpp:2806
CLI::App::add_flag
Option * add_flag(std::string flag_name, T &flag_description)
Definition: App.hpp:720
CLI::App::add_flag_callback
Option * add_flag_callback(std::string flag_name, std::function< void(void)> function, std::string flag_description="")
Add option for callback that is triggered with a true flag and takes no arguments.
Definition: App.hpp:781
CLI::CallForAllHelp
Usually something like –help-all on command line.
Definition: Error.hpp:162
CLI::App::get_help_ptr
const Option * get_help_ptr() const
Get a pointer to the help flag. (const)
Definition: App.hpp:1693
CLI::TriggerOn
void TriggerOn(App *trigger_app, App *app_to_enable)
Helper function to enable one option group/subcommand when another is used.
Definition: App.hpp:2898
CLI::App::_process_env
void _process_env()
Get envname options if not yet passed. Runs on all subcommands.
Definition: App.hpp:1984
CLI::App::App
App(std::string app_description, std::string app_name, App *parent)
Special private constructor for subcommand.
Definition: App.hpp:250
CLI::HorribleError
Definition: Error.hpp:318
CLI::App::allow_extras_
bool allow_extras_
If true, allow extra arguments (ie, don't throw an error). INHERITABLE.
Definition: App.hpp:78
CLI::RequiredError
Thrown when a required option is missing.
Definition: Error.hpp:205
CLI::detail::escape_detect
std::size_t escape_detect(std::string &str, std::size_t offset)
Definition: StringTools.hpp:349
CLI::Option_group::Option_group
Option_group(std::string group_description, std::string group_name, App *parent)
Definition: App.hpp:2867
CLI::Option::get_allow_extra_args
bool get_allow_extra_args() const
Get the current value of allow extra args.
Definition: Option.hpp:411
CLI::detail::type_count
This will only trigger for actual void type.
Definition: TypeTools.hpp:297
CLI::App::get_fallthrough
bool get_fallthrough() const
Check the status of fallthrough.
Definition: App.hpp:1634
CLI::App::callback
App * callback(std::function< void()> app_callback)
Definition: App.hpp:305
CLI::App::pre_parse_called_
bool pre_parse_called_
Flag indicating that the pre_parse_callback has been triggered.
Definition: App.hpp:97
CLI::App::get_positionals_at_end
bool get_positionals_at_end() const
Check the status of the allow windows style options.
Definition: App.hpp:1640
CLI::OptionNotFound
Thrown when counting a non-existent option.
Definition: Error.hpp:326
CLI::App::count_all
std::size_t count_all() const
Definition: App.hpp:1096
CLI::detail::AppFriend::parse_subcommand
static auto parse_subcommand(App *app, Args &&... args) -> typename std::result_of< decltype(&App::_parse_subcommand)(App, Args...)>::type
Wrap _parse_subcommand, perfectly forward arguments and return.
Definition: App.hpp:3061
CLI::App::disabled
App * disabled(bool disable=true)
Disable the subcommand or option group.
Definition: App.hpp:386
CLI::detail::Classifier::SUBCOMMAND_TERMINATOR
@ SUBCOMMAND_TERMINATOR
CLI::App::parse_complete_callback_
std::function< void()> parse_complete_callback_
This is a function that runs when parsing has finished.
Definition: App.hpp:107
CLI::App::add_flag
Option * add_flag(std::string flag_name)
Add a flag with no description or variable assignment.
Definition: App.hpp:712
CLI::Option::get_expected_min
int get_expected_min() const
The number of times the option expects to be included.
Definition: Option.hpp:686
CLI::OptionBase::required
CRTP * required(bool value=true)
Set the option as required.
Definition: Option.hpp:96
CLI::App::add_mutable_set
Option * add_mutable_set(std::string option_name, T &member, const std::set< T > &options, std::string option_description="")
Add set of options (No default, set can be changed afterwards - do not destroy the set) DEPRECATED.
Definition: App.hpp:834
CLI::Option::clear
void clear()
Clear the parsed results (mostly for testing)
Definition: Option.hpp:354
CLI::App::allow_config_extras
App * allow_config_extras(config_extras_mode mode)
ignore extras in config files
Definition: App.hpp:444
CLI::App::_process_extras
void _process_extras(std::vector< std::string > &args)
Definition: App.hpp:2218
CLI::App::help_all_ptr_
Option * help_all_ptr_
A pointer to the help all flag if there is one INHERITABLE.
Definition: App.hpp:135
CLI::App::_parse
void _parse(std::vector< std::string > &args)
Internal parse function.
Definition: App.hpp:2242
CLI::detail::split_long
bool split_long(const std::string &current, std::string &name, std::string &value)
Definition: Split.hpp:27
CLI::App::get_parent
App * get_parent()
Get the parent of this subcommand (or nullptr if master app)
Definition: App.hpp:1705
CLI::detail::Classifier::NONE
@ NONE
CLI::Option::add_result
Option * add_result(std::string s)
Puts a result at the end.
Definition: Option.hpp:919
CLI::App::help_ptr_
Option * help_ptr_
A pointer to the help flag if there is one INHERITABLE.
Definition: App.hpp:132
CLI::App::configurable
App * configurable(bool value=true)
Specify that the subcommand can be triggered by a config file.
Definition: App.hpp:484
CLI::ConfigItem
Holds values to load into Options.
Definition: ConfigFwd.hpp:19
CLI::detail::Classifier
Classifier
Definition: App.hpp:39
CLI::App::description
App * description(std::string app_description)
Set the description of the app.
Definition: App.hpp:1527
CLI::detail::Classifier::LONG
@ LONG
CLI::App::group_
std::string group_
The group membership INHERITABLE.
Definition: App.hpp:232
CLI::App::footer_callback_
std::function< std::string()> footer_callback_
This is a function that generates a footer to put after all other options in help output.
Definition: App.hpp:129
CLI::App::get_option
Option * get_option(std::string option_name)
Get an option by name (non-const version)
Definition: App.hpp:1613
CLI::App::help
std::string help(std::string prev="", AppFormatMode mode=AppFormatMode::Normal) const
Definition: App.hpp:1494
CLI::App::get_options
std::vector< Option * > get_options(const std::function< bool(Option *)> filter={})
Non-const version of the above.
Definition: App.hpp:1550
CLI::ConfigItem::parents
std::vector< std::string > parents
This is the list of parents.
Definition: ConfigFwd.hpp:21
CLI::Option::run_callback
void run_callback()
Process the callback.
Definition: Option.hpp:787
CLI::App::enabled_by_default
App * enabled_by_default(bool enable=true)
Definition: App.hpp:403
CLI::App::require_subcommand
App * require_subcommand()
The argumentless form of require subcommand requires 1 or more subcommands.
Definition: App.hpp:1117
CLI::App::get_subcommand_ptr
CLI::App_p get_subcommand_ptr(int index=0) const
Get an owning pointer to subcommand by index.
Definition: App.hpp:1070
CLI::App::get_subcommand_ptr
CLI::App_p get_subcommand_ptr(App *subcom) const
Check to see if a subcommand is part of this command and get a shared_ptr to it.
Definition: App.hpp:1052
CLI::IncorrectConstruction
Thrown when an option is set to conflicting values (non-vector and multi args, for example)
Definition: Error.hpp:86
CLI::App::validate_positionals_
bool validate_positionals_
If set to true positional options are validated before assigning INHERITABLE.
Definition: App.hpp:211
CLI::App::option_defaults
OptionDefaults * option_defaults()
Get the OptionDefault object, to set option defaults.
Definition: App.hpp:526
CLI::RequiresError
Thrown when a requires option is missing.
Definition: Error.hpp:269
CLI::detail::has_default_flag_values
bool has_default_flag_values(const std::string &flags)
check if the flag definitions has possible false flags
Definition: StringTools.hpp:223
CLI::Option::allow_extra_args
Option * allow_extra_args(bool value=true)
Definition: Option.hpp:406
CLI::App::remaining_size
std::size_t remaining_size(bool recurse=false) const
This returns the number of remaining options, minus the – separator.
Definition: App.hpp:1806
CLI::App::_has_remaining_positionals
bool _has_remaining_positionals() const
Count the required remaining positional arguments.
Definition: App.hpp:2418
CLI::App::add_set
Option * add_set(std::string option_name, T &member, std::set< T > options, std::string option_description, bool defaulted)
Add set of options (with default, static set, such as an inline set) DEPRECATED.
Definition: App.hpp:846