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