File indexing completed on 2025-01-18 09:54:43
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009
0010 #include <algorithm>
0011 #include <cstdint>
0012 #include <functional>
0013 #include <iostream>
0014 #include <iterator>
0015 #include <memory>
0016 #include <numeric>
0017 #include <set>
0018 #include <sstream>
0019 #include <string>
0020 #include <utility>
0021 #include <vector>
0022
0023
0024
0025 #include "ConfigFwd.hpp"
0026 #include "Error.hpp"
0027 #include "FormatterFwd.hpp"
0028 #include "Macros.hpp"
0029 #include "Option.hpp"
0030 #include "Split.hpp"
0031 #include "StringTools.hpp"
0032 #include "TypeTools.hpp"
0033
0034 namespace CLI {
0035
0036
0037 #ifndef CLI11_PARSE
0038 #define CLI11_PARSE(app, argc, argv) \
0039 try { \
0040 (app).parse((argc), (argv)); \
0041 } catch(const CLI::ParseError &e) { \
0042 return (app).exit(e); \
0043 }
0044 #endif
0045
0046 namespace detail {
0047 enum class Classifier { NONE, POSITIONAL_MARK, SHORT, LONG, WINDOWS_STYLE, SUBCOMMAND, SUBCOMMAND_TERMINATOR };
0048 struct AppFriend;
0049 }
0050
0051 namespace FailureMessage {
0052
0053 CLI11_INLINE std::string simple(const App *app, const Error &e);
0054
0055
0056 CLI11_INLINE std::string help(const App *app, const Error &e);
0057 }
0058
0059
0060
0061 enum class config_extras_mode : char { error = 0, ignore, ignore_all, capture };
0062
0063 class App;
0064
0065 using App_p = std::shared_ptr<App>;
0066
0067 namespace detail {
0068
0069
0070 template <typename T, enable_if_t<!std::is_integral<T>::value || (sizeof(T) <= 1U), detail::enabler> = detail::dummy>
0071 Option *default_flag_modifiers(Option *opt) {
0072 return opt->always_capture_default();
0073 }
0074
0075
0076 template <typename T, enable_if_t<std::is_integral<T>::value && (sizeof(T) > 1U), detail::enabler> = detail::dummy>
0077 Option *default_flag_modifiers(Option *opt) {
0078 return opt->multi_option_policy(MultiOptionPolicy::Sum)->default_str("0")->force_callback();
0079 }
0080
0081 }
0082
0083 class Option_group;
0084
0085
0086
0087
0088 class App {
0089 friend Option;
0090 friend detail::AppFriend;
0091
0092 protected:
0093
0094
0095
0096
0097
0098
0099 std::string name_{};
0100
0101
0102 std::string description_{};
0103
0104
0105 bool allow_extras_{false};
0106
0107
0108
0109 config_extras_mode allow_config_extras_{config_extras_mode::ignore};
0110
0111
0112 bool prefix_command_{false};
0113
0114
0115 bool has_automatic_name_{false};
0116
0117
0118 bool required_{false};
0119
0120
0121 bool disabled_{false};
0122
0123
0124 bool pre_parse_called_{false};
0125
0126
0127
0128 bool immediate_callback_{false};
0129
0130
0131 std::function<void(std::size_t)> pre_parse_callback_{};
0132
0133
0134 std::function<void()> parse_complete_callback_{};
0135
0136
0137 std::function<void()> final_callback_{};
0138
0139
0140
0141
0142
0143
0144 OptionDefaults option_defaults_{};
0145
0146
0147 std::vector<Option_p> options_{};
0148
0149
0150
0151
0152
0153
0154 std::string footer_{};
0155
0156
0157 std::function<std::string()> footer_callback_{};
0158
0159
0160 Option *help_ptr_{nullptr};
0161
0162
0163 Option *help_all_ptr_{nullptr};
0164
0165
0166 Option *version_ptr_{nullptr};
0167
0168
0169 std::shared_ptr<FormatterBase> formatter_{new Formatter()};
0170
0171
0172 std::function<std::string(const App *, const Error &e)> failure_message_{FailureMessage::simple};
0173
0174
0175
0176
0177
0178 using missing_t = std::vector<std::pair<detail::Classifier, std::string>>;
0179
0180
0181
0182
0183 missing_t missing_{};
0184
0185
0186 std::vector<Option *> parse_order_{};
0187
0188
0189 std::vector<App *> parsed_subcommands_{};
0190
0191
0192 std::set<App *> exclude_subcommands_{};
0193
0194
0195
0196 std::set<Option *> exclude_options_{};
0197
0198
0199
0200 std::set<App *> need_subcommands_{};
0201
0202
0203
0204 std::set<Option *> need_options_{};
0205
0206
0207
0208
0209
0210
0211 std::vector<App_p> subcommands_{};
0212
0213
0214 bool ignore_case_{false};
0215
0216
0217 bool ignore_underscore_{false};
0218
0219
0220 bool fallthrough_{false};
0221
0222
0223 bool allow_windows_style_options_{
0224 #ifdef _WIN32
0225 true
0226 #else
0227 false
0228 #endif
0229 };
0230
0231 bool positionals_at_end_{false};
0232
0233 enum class startup_mode : char { stable, enabled, disabled };
0234
0235
0236 startup_mode default_startup{startup_mode::stable};
0237
0238
0239 bool configurable_{false};
0240
0241
0242 bool validate_positionals_{false};
0243
0244
0245 bool validate_optional_arguments_{false};
0246
0247
0248
0249 bool silent_{false};
0250
0251
0252 std::uint32_t parsed_{0U};
0253
0254
0255 std::size_t require_subcommand_min_{0};
0256
0257
0258 std::size_t require_subcommand_max_{0};
0259
0260
0261 std::size_t require_option_min_{0};
0262
0263
0264 std::size_t require_option_max_{0};
0265
0266
0267 App *parent_{nullptr};
0268
0269
0270 std::string group_{"Subcommands"};
0271
0272
0273 std::vector<std::string> aliases_{};
0274
0275
0276
0277
0278
0279
0280 Option *config_ptr_{nullptr};
0281
0282
0283 std::shared_ptr<Config> config_formatter_{new ConfigTOML()};
0284
0285
0286
0287
0288 App(std::string app_description, std::string app_name, App *parent);
0289
0290 public:
0291
0292
0293
0294
0295 explicit App(std::string app_description = "", std::string app_name = "")
0296 : App(app_description, app_name, nullptr) {
0297 set_help_flag("-h,--help", "Print this help message and exit");
0298 }
0299
0300 App(const App &) = delete;
0301 App &operator=(const App &) = delete;
0302
0303
0304 virtual ~App() = default;
0305
0306
0307
0308
0309
0310
0311
0312 App *callback(std::function<void()> app_callback) {
0313 if(immediate_callback_) {
0314 parse_complete_callback_ = std::move(app_callback);
0315 } else {
0316 final_callback_ = std::move(app_callback);
0317 }
0318 return this;
0319 }
0320
0321
0322
0323 App *final_callback(std::function<void()> app_callback) {
0324 final_callback_ = std::move(app_callback);
0325 return this;
0326 }
0327
0328
0329
0330 App *parse_complete_callback(std::function<void()> pc_callback) {
0331 parse_complete_callback_ = std::move(pc_callback);
0332 return this;
0333 }
0334
0335
0336
0337 App *preparse_callback(std::function<void(std::size_t)> pp_callback) {
0338 pre_parse_callback_ = std::move(pp_callback);
0339 return this;
0340 }
0341
0342
0343 App *name(std::string app_name = "");
0344
0345
0346 App *alias(std::string app_name);
0347
0348
0349 App *allow_extras(bool allow = true) {
0350 allow_extras_ = allow;
0351 return this;
0352 }
0353
0354
0355 App *required(bool require = true) {
0356 required_ = require;
0357 return this;
0358 }
0359
0360
0361 App *disabled(bool disable = true) {
0362 disabled_ = disable;
0363 return this;
0364 }
0365
0366
0367 App *silent(bool silence = true) {
0368 silent_ = silence;
0369 return this;
0370 }
0371
0372
0373 App *disabled_by_default(bool disable = true) {
0374 if(disable) {
0375 default_startup = startup_mode::disabled;
0376 } else {
0377 default_startup = (default_startup == startup_mode::enabled) ? startup_mode::enabled : startup_mode::stable;
0378 }
0379 return this;
0380 }
0381
0382
0383
0384 App *enabled_by_default(bool enable = true) {
0385 if(enable) {
0386 default_startup = startup_mode::enabled;
0387 } else {
0388 default_startup =
0389 (default_startup == startup_mode::disabled) ? startup_mode::disabled : startup_mode::stable;
0390 }
0391 return this;
0392 }
0393
0394
0395 App *immediate_callback(bool immediate = true);
0396
0397
0398 App *validate_positionals(bool validate = true) {
0399 validate_positionals_ = validate;
0400 return this;
0401 }
0402
0403
0404 App *validate_optional_arguments(bool validate = true) {
0405 validate_optional_arguments_ = validate;
0406 return this;
0407 }
0408
0409
0410 App *allow_config_extras(bool allow = true) {
0411 if(allow) {
0412 allow_config_extras_ = config_extras_mode::capture;
0413 allow_extras_ = true;
0414 } else {
0415 allow_config_extras_ = config_extras_mode::error;
0416 }
0417 return this;
0418 }
0419
0420
0421 App *allow_config_extras(config_extras_mode mode) {
0422 allow_config_extras_ = mode;
0423 return this;
0424 }
0425
0426
0427 App *prefix_command(bool allow = true) {
0428 prefix_command_ = allow;
0429 return this;
0430 }
0431
0432
0433 App *ignore_case(bool value = true);
0434
0435
0436
0437 App *allow_windows_style_options(bool value = true) {
0438 allow_windows_style_options_ = value;
0439 return this;
0440 }
0441
0442
0443 App *positionals_at_end(bool value = true) {
0444 positionals_at_end_ = value;
0445 return this;
0446 }
0447
0448
0449 App *configurable(bool value = true) {
0450 configurable_ = value;
0451 return this;
0452 }
0453
0454
0455 App *ignore_underscore(bool value = true);
0456
0457
0458 App *formatter(std::shared_ptr<FormatterBase> fmt) {
0459 formatter_ = fmt;
0460 return this;
0461 }
0462
0463
0464 App *formatter_fn(std::function<std::string(const App *, std::string, AppFormatMode)> fmt) {
0465 formatter_ = std::make_shared<FormatterLambda>(fmt);
0466 return this;
0467 }
0468
0469
0470 App *config_formatter(std::shared_ptr<Config> fmt) {
0471 config_formatter_ = fmt;
0472 return this;
0473 }
0474
0475
0476 CLI11_NODISCARD bool parsed() const { return parsed_ > 0; }
0477
0478
0479 OptionDefaults *option_defaults() { return &option_defaults_; }
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499 Option *add_option(std::string option_name,
0500 callback_t option_callback,
0501 std::string option_description = "",
0502 bool defaulted = false,
0503 std::function<std::string()> func = {});
0504
0505
0506 template <typename AssignTo,
0507 typename ConvertTo = AssignTo,
0508 enable_if_t<!std::is_const<ConvertTo>::value, detail::enabler> = detail::dummy>
0509 Option *add_option(std::string option_name,
0510 AssignTo &variable,
0511 std::string option_description = "") {
0512
0513 auto fun = [&variable](const CLI::results_t &res) {
0514 return detail::lexical_conversion<AssignTo, ConvertTo>(res, variable);
0515 };
0516
0517 Option *opt = add_option(option_name, fun, option_description, false, [&variable]() {
0518 return CLI::detail::checked_to_string<AssignTo, ConvertTo>(variable);
0519 });
0520 opt->type_name(detail::type_name<ConvertTo>());
0521
0522
0523 auto Tcount = detail::type_count<AssignTo>::value;
0524 auto XCcount = detail::type_count<ConvertTo>::value;
0525 opt->type_size(detail::type_count_min<ConvertTo>::value, (std::max)(Tcount, XCcount));
0526 opt->expected(detail::expected_count<ConvertTo>::value);
0527 opt->run_callback_for_default();
0528 return opt;
0529 }
0530
0531
0532 template <typename AssignTo, enable_if_t<!std::is_const<AssignTo>::value, detail::enabler> = detail::dummy>
0533 Option *add_option_no_stream(std::string option_name,
0534 AssignTo &variable,
0535 std::string option_description = "") {
0536
0537 auto fun = [&variable](const CLI::results_t &res) {
0538 return detail::lexical_conversion<AssignTo, AssignTo>(res, variable);
0539 };
0540
0541 Option *opt = add_option(option_name, fun, option_description, false, []() { return std::string{}; });
0542 opt->type_name(detail::type_name<AssignTo>());
0543 opt->type_size(detail::type_count_min<AssignTo>::value, detail::type_count<AssignTo>::value);
0544 opt->expected(detail::expected_count<AssignTo>::value);
0545 opt->run_callback_for_default();
0546 return opt;
0547 }
0548
0549
0550 template <typename ArgType>
0551 Option *add_option_function(std::string option_name,
0552 const std::function<void(const ArgType &)> &func,
0553 std::string option_description = "") {
0554
0555 auto fun = [func](const CLI::results_t &res) {
0556 ArgType variable;
0557 bool result = detail::lexical_conversion<ArgType, ArgType>(res, variable);
0558 if(result) {
0559 func(variable);
0560 }
0561 return result;
0562 };
0563
0564 Option *opt = add_option(option_name, std::move(fun), option_description, false);
0565 opt->type_name(detail::type_name<ArgType>());
0566 opt->type_size(detail::type_count_min<ArgType>::value, detail::type_count<ArgType>::value);
0567 opt->expected(detail::expected_count<ArgType>::value);
0568 return opt;
0569 }
0570
0571
0572 Option *add_option(std::string option_name) {
0573 return add_option(option_name, CLI::callback_t{}, std::string{}, false);
0574 }
0575
0576
0577 template <typename T,
0578 enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
0579 detail::dummy>
0580 Option *add_option(std::string option_name, T &option_description) {
0581 return add_option(option_name, CLI::callback_t(), option_description, false);
0582 }
0583
0584
0585 Option *set_help_flag(std::string flag_name = "", const std::string &help_description = "");
0586
0587
0588 Option *set_help_all_flag(std::string help_name = "", const std::string &help_description = "");
0589
0590
0591 Option *set_version_flag(std::string flag_name = "",
0592 const std::string &versionString = "",
0593 const std::string &version_help = "Display program version information and exit");
0594
0595
0596 Option *set_version_flag(std::string flag_name,
0597 std::function<std::string()> vfunc,
0598 const std::string &version_help = "Display program version information and exit");
0599
0600 private:
0601
0602 Option *_add_flag_internal(std::string flag_name, CLI::callback_t fun, std::string flag_description);
0603
0604 public:
0605
0606 Option *add_flag(std::string flag_name) { return _add_flag_internal(flag_name, CLI::callback_t(), std::string{}); }
0607
0608
0609
0610
0611 template <typename T,
0612 enable_if_t<std::is_const<T>::value && std::is_constructible<std::string, T>::value, detail::enabler> =
0613 detail::dummy>
0614 Option *add_flag(std::string flag_name, T &flag_description) {
0615 return _add_flag_internal(flag_name, CLI::callback_t(), flag_description);
0616 }
0617
0618
0619
0620 template <typename T,
0621 enable_if_t<!detail::is_mutable_container<T>::value && !std::is_const<T>::value &&
0622 !std::is_constructible<std::function<void(int)>, T>::value,
0623 detail::enabler> = detail::dummy>
0624 Option *add_flag(std::string flag_name,
0625 T &flag_result,
0626 std::string flag_description = "") {
0627
0628 CLI::callback_t fun = [&flag_result](const CLI::results_t &res) {
0629 using CLI::detail::lexical_cast;
0630 return lexical_cast(res[0], flag_result);
0631 };
0632 auto *opt = _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
0633 return detail::default_flag_modifiers<T>(opt);
0634 }
0635
0636
0637 template <typename T,
0638 enable_if_t<!std::is_assignable<std::function<void(std::int64_t)> &, T>::value, detail::enabler> =
0639 detail::dummy>
0640 Option *add_flag(std::string flag_name,
0641 std::vector<T> &flag_results,
0642 std::string flag_description = "") {
0643 CLI::callback_t fun = [&flag_results](const CLI::results_t &res) {
0644 bool retval = true;
0645 for(const auto &elem : res) {
0646 using CLI::detail::lexical_cast;
0647 flag_results.emplace_back();
0648 retval &= lexical_cast(elem, flag_results.back());
0649 }
0650 return retval;
0651 };
0652 return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description))
0653 ->multi_option_policy(MultiOptionPolicy::TakeAll)
0654 ->run_callback_for_default();
0655 }
0656
0657
0658 Option *add_flag_callback(std::string flag_name,
0659 std::function<void(void)> function,
0660 std::string flag_description = "");
0661
0662
0663 Option *add_flag_function(std::string flag_name,
0664 std::function<void(std::int64_t)> function,
0665 std::string flag_description = "");
0666
0667 #ifdef CLI11_CPP14
0668
0669 Option *add_flag(std::string flag_name,
0670 std::function<void(std::int64_t)> function,
0671 std::string flag_description = "") {
0672 return add_flag_function(std::move(flag_name), std::move(function), std::move(flag_description));
0673 }
0674 #endif
0675
0676
0677 Option *set_config(std::string option_name = "",
0678 std::string default_filename = "",
0679 const std::string &help_message = "Read an ini file",
0680 bool config_required = false);
0681
0682
0683 bool remove_option(Option *opt);
0684
0685
0686 template <typename T = Option_group>
0687 T *add_option_group(std::string group_name, std::string group_description = "") {
0688 if(!detail::valid_alias_name_string(group_name)) {
0689 throw IncorrectConstruction("option group names may not contain newlines or null characters");
0690 }
0691 auto option_group = std::make_shared<T>(std::move(group_description), group_name, this);
0692 auto *ptr = option_group.get();
0693
0694 App_p app_ptr = std::dynamic_pointer_cast<App>(option_group);
0695 add_subcommand(std::move(app_ptr));
0696 return ptr;
0697 }
0698
0699
0700
0701
0702
0703
0704 App *add_subcommand(std::string subcommand_name = "", std::string subcommand_description = "");
0705
0706
0707 App *add_subcommand(CLI::App_p subcom);
0708
0709
0710 bool remove_subcommand(App *subcom);
0711
0712
0713
0714 App *get_subcommand(const App *subcom) const;
0715
0716
0717 CLI11_NODISCARD App *get_subcommand(std::string subcom) const;
0718
0719
0720 CLI11_NODISCARD App *get_subcommand(int index = 0) const;
0721
0722
0723 CLI::App_p get_subcommand_ptr(App *subcom) const;
0724
0725
0726 CLI11_NODISCARD CLI::App_p get_subcommand_ptr(std::string subcom) const;
0727
0728
0729 CLI11_NODISCARD CLI::App_p get_subcommand_ptr(int index = 0) const;
0730
0731
0732 CLI11_NODISCARD App *get_option_group(std::string group_name) const;
0733
0734
0735
0736
0737 CLI11_NODISCARD std::size_t count() const { return parsed_; }
0738
0739
0740
0741 CLI11_NODISCARD std::size_t count_all() const;
0742
0743
0744 App *group(std::string group_name) {
0745 group_ = group_name;
0746 return this;
0747 }
0748
0749
0750 App *require_subcommand() {
0751 require_subcommand_min_ = 1;
0752 require_subcommand_max_ = 0;
0753 return this;
0754 }
0755
0756
0757
0758
0759 App *require_subcommand(int value) {
0760 if(value < 0) {
0761 require_subcommand_min_ = 0;
0762 require_subcommand_max_ = static_cast<std::size_t>(-value);
0763 } else {
0764 require_subcommand_min_ = static_cast<std::size_t>(value);
0765 require_subcommand_max_ = static_cast<std::size_t>(value);
0766 }
0767 return this;
0768 }
0769
0770
0771
0772 App *require_subcommand(std::size_t min, std::size_t max) {
0773 require_subcommand_min_ = min;
0774 require_subcommand_max_ = max;
0775 return this;
0776 }
0777
0778
0779 App *require_option() {
0780 require_option_min_ = 1;
0781 require_option_max_ = 0;
0782 return this;
0783 }
0784
0785
0786
0787
0788 App *require_option(int value) {
0789 if(value < 0) {
0790 require_option_min_ = 0;
0791 require_option_max_ = static_cast<std::size_t>(-value);
0792 } else {
0793 require_option_min_ = static_cast<std::size_t>(value);
0794 require_option_max_ = static_cast<std::size_t>(value);
0795 }
0796 return this;
0797 }
0798
0799
0800
0801 App *require_option(std::size_t min, std::size_t max) {
0802 require_option_min_ = min;
0803 require_option_max_ = max;
0804 return this;
0805 }
0806
0807
0808
0809 App *fallthrough(bool value = true) {
0810 fallthrough_ = value;
0811 return this;
0812 }
0813
0814
0815
0816 explicit operator bool() const { return parsed_ > 0; }
0817
0818
0819
0820
0821
0822
0823
0824
0825 virtual void pre_callback() {}
0826
0827
0828
0829
0830
0831
0832 void clear();
0833
0834
0835
0836 void parse(int argc, const char *const *argv);
0837
0838
0839
0840
0841
0842 void parse(std::string commandline, bool program_name_included = false);
0843
0844
0845
0846 void parse(std::vector<std::string> &args);
0847
0848
0849 void parse(std::vector<std::string> &&args);
0850
0851 void parse_from_stream(std::istream &input);
0852
0853
0854 void failure_message(std::function<std::string(const App *, const Error &e)> function) {
0855 failure_message_ = function;
0856 }
0857
0858
0859 int exit(const Error &e, std::ostream &out = std::cout, std::ostream &err = std::cerr) const;
0860
0861
0862
0863
0864
0865
0866 CLI11_NODISCARD std::size_t count(std::string option_name) const { return get_option(option_name)->count(); }
0867
0868
0869
0870 CLI11_NODISCARD std::vector<App *> get_subcommands() const { return parsed_subcommands_; }
0871
0872
0873
0874 std::vector<const App *> get_subcommands(const std::function<bool(const App *)> &filter) const;
0875
0876
0877
0878 std::vector<App *> get_subcommands(const std::function<bool(App *)> &filter);
0879
0880
0881 bool got_subcommand(const App *subcom) const {
0882
0883 return get_subcommand(subcom)->parsed_ > 0;
0884 }
0885
0886
0887 CLI11_NODISCARD bool got_subcommand(std::string subcommand_name) const {
0888 return get_subcommand(subcommand_name)->parsed_ > 0;
0889 }
0890
0891
0892 App *excludes(Option *opt) {
0893 if(opt == nullptr) {
0894 throw OptionNotFound("nullptr passed");
0895 }
0896 exclude_options_.insert(opt);
0897 return this;
0898 }
0899
0900
0901 App *excludes(App *app) {
0902 if(app == nullptr) {
0903 throw OptionNotFound("nullptr passed");
0904 }
0905 if(app == this) {
0906 throw OptionNotFound("cannot self reference in needs");
0907 }
0908 auto res = exclude_subcommands_.insert(app);
0909
0910 if(res.second) {
0911 app->exclude_subcommands_.insert(this);
0912 }
0913 return this;
0914 }
0915
0916 App *needs(Option *opt) {
0917 if(opt == nullptr) {
0918 throw OptionNotFound("nullptr passed");
0919 }
0920 need_options_.insert(opt);
0921 return this;
0922 }
0923
0924 App *needs(App *app) {
0925 if(app == nullptr) {
0926 throw OptionNotFound("nullptr passed");
0927 }
0928 if(app == this) {
0929 throw OptionNotFound("cannot self reference in needs");
0930 }
0931 need_subcommands_.insert(app);
0932 return this;
0933 }
0934
0935
0936 bool remove_excludes(Option *opt);
0937
0938
0939 bool remove_excludes(App *app);
0940
0941
0942 bool remove_needs(Option *opt);
0943
0944
0945 bool remove_needs(App *app);
0946
0947
0948
0949
0950
0951 App *footer(std::string footer_string) {
0952 footer_ = std::move(footer_string);
0953 return this;
0954 }
0955
0956 App *footer(std::function<std::string()> footer_function) {
0957 footer_callback_ = std::move(footer_function);
0958 return this;
0959 }
0960
0961
0962 CLI11_NODISCARD std::string config_to_str(bool default_also = false, bool write_description = false) const {
0963 return config_formatter_->to_config(this, default_also, write_description, "");
0964 }
0965
0966
0967
0968 CLI11_NODISCARD std::string help(std::string prev = "", AppFormatMode mode = AppFormatMode::Normal) const;
0969
0970
0971 CLI11_NODISCARD std::string version() const;
0972
0973
0974
0975
0976
0977 CLI11_NODISCARD std::shared_ptr<FormatterBase> get_formatter() const { return formatter_; }
0978
0979
0980 CLI11_NODISCARD std::shared_ptr<Config> get_config_formatter() const { return config_formatter_; }
0981
0982
0983 CLI11_NODISCARD std::shared_ptr<ConfigBase> get_config_formatter_base() const {
0984
0985 #if CLI11_USE_STATIC_RTTI == 0
0986 return std::dynamic_pointer_cast<ConfigBase>(config_formatter_);
0987 #else
0988 return std::static_pointer_cast<ConfigBase>(config_formatter_);
0989 #endif
0990 }
0991
0992
0993 CLI11_NODISCARD std::string get_description() const { return description_; }
0994
0995
0996 App *description(std::string app_description) {
0997 description_ = std::move(app_description);
0998 return this;
0999 }
1000
1001
1002 std::vector<const Option *> get_options(const std::function<bool(const Option *)> filter = {}) const;
1003
1004
1005 std::vector<Option *> get_options(const std::function<bool(Option *)> filter = {});
1006
1007
1008 Option *get_option_no_throw(std::string option_name) noexcept;
1009
1010
1011 CLI11_NODISCARD const Option *get_option_no_throw(std::string option_name) const noexcept;
1012
1013
1014 CLI11_NODISCARD const Option *get_option(std::string option_name) const {
1015 const auto *opt = get_option_no_throw(option_name);
1016 if(opt == nullptr) {
1017 throw OptionNotFound(option_name);
1018 }
1019 return opt;
1020 }
1021
1022
1023 Option *get_option(std::string option_name) {
1024 auto *opt = get_option_no_throw(option_name);
1025 if(opt == nullptr) {
1026 throw OptionNotFound(option_name);
1027 }
1028 return opt;
1029 }
1030
1031
1032 const Option *operator[](const std::string &option_name) const { return get_option(option_name); }
1033
1034
1035 const Option *operator[](const char *option_name) const { return get_option(option_name); }
1036
1037
1038 CLI11_NODISCARD bool get_ignore_case() const { return ignore_case_; }
1039
1040
1041 CLI11_NODISCARD bool get_ignore_underscore() const { return ignore_underscore_; }
1042
1043
1044 CLI11_NODISCARD bool get_fallthrough() const { return fallthrough_; }
1045
1046
1047 CLI11_NODISCARD bool get_allow_windows_style_options() const { return allow_windows_style_options_; }
1048
1049
1050 CLI11_NODISCARD bool get_positionals_at_end() const { return positionals_at_end_; }
1051
1052
1053 CLI11_NODISCARD bool get_configurable() const { return configurable_; }
1054
1055
1056 CLI11_NODISCARD const std::string &get_group() const { return group_; }
1057
1058
1059 CLI11_NODISCARD std::string get_footer() const {
1060 return (footer_callback_) ? footer_callback_() + '\n' + footer_ : footer_;
1061 }
1062
1063
1064 CLI11_NODISCARD std::size_t get_require_subcommand_min() const { return require_subcommand_min_; }
1065
1066
1067 CLI11_NODISCARD std::size_t get_require_subcommand_max() const { return require_subcommand_max_; }
1068
1069
1070 CLI11_NODISCARD std::size_t get_require_option_min() const { return require_option_min_; }
1071
1072
1073 CLI11_NODISCARD std::size_t get_require_option_max() const { return require_option_max_; }
1074
1075
1076 CLI11_NODISCARD bool get_prefix_command() const { return prefix_command_; }
1077
1078
1079 CLI11_NODISCARD bool get_allow_extras() const { return allow_extras_; }
1080
1081
1082 CLI11_NODISCARD bool get_required() const { return required_; }
1083
1084
1085 CLI11_NODISCARD bool get_disabled() const { return disabled_; }
1086
1087
1088 CLI11_NODISCARD bool get_silent() const { return silent_; }
1089
1090
1091 CLI11_NODISCARD bool get_immediate_callback() const { return immediate_callback_; }
1092
1093
1094 CLI11_NODISCARD bool get_disabled_by_default() const { return (default_startup == startup_mode::disabled); }
1095
1096
1097 CLI11_NODISCARD bool get_enabled_by_default() const { return (default_startup == startup_mode::enabled); }
1098
1099 CLI11_NODISCARD bool get_validate_positionals() const { return validate_positionals_; }
1100
1101 CLI11_NODISCARD bool get_validate_optional_arguments() const { return validate_optional_arguments_; }
1102
1103
1104 CLI11_NODISCARD config_extras_mode get_allow_config_extras() const { return allow_config_extras_; }
1105
1106
1107 Option *get_help_ptr() { return help_ptr_; }
1108
1109
1110 CLI11_NODISCARD const Option *get_help_ptr() const { return help_ptr_; }
1111
1112
1113 CLI11_NODISCARD const Option *get_help_all_ptr() const { return help_all_ptr_; }
1114
1115
1116 Option *get_config_ptr() { return config_ptr_; }
1117
1118
1119 CLI11_NODISCARD const Option *get_config_ptr() const { return config_ptr_; }
1120
1121
1122 Option *get_version_ptr() { return version_ptr_; }
1123
1124
1125 CLI11_NODISCARD const Option *get_version_ptr() const { return version_ptr_; }
1126
1127
1128 App *get_parent() { return parent_; }
1129
1130
1131 CLI11_NODISCARD const App *get_parent() const { return parent_; }
1132
1133
1134 CLI11_NODISCARD const std::string &get_name() const { return name_; }
1135
1136
1137 CLI11_NODISCARD const std::vector<std::string> &get_aliases() const { return aliases_; }
1138
1139
1140 App *clear_aliases() {
1141 aliases_.clear();
1142 return this;
1143 }
1144
1145
1146 CLI11_NODISCARD std::string get_display_name(bool with_aliases = false) const;
1147
1148
1149 CLI11_NODISCARD bool check_name(std::string name_to_check) const;
1150
1151
1152 CLI11_NODISCARD std::vector<std::string> get_groups() const;
1153
1154
1155 CLI11_NODISCARD const std::vector<Option *> &parse_order() const { return parse_order_; }
1156
1157
1158 CLI11_NODISCARD std::vector<std::string> remaining(bool recurse = false) const;
1159
1160
1161 CLI11_NODISCARD std::vector<std::string> remaining_for_passthrough(bool recurse = false) const;
1162
1163
1164 CLI11_NODISCARD std::size_t remaining_size(bool recurse = false) const;
1165
1166
1167
1168 protected:
1169
1170
1171
1172
1173 void _validate() const;
1174
1175
1176
1177
1178 void _configure();
1179
1180
1181 void run_callback(bool final_mode = false, bool suppress_final_callback = false);
1182
1183
1184 CLI11_NODISCARD bool _valid_subcommand(const std::string ¤t, bool ignore_used = true) const;
1185
1186
1187 CLI11_NODISCARD detail::Classifier _recognize(const std::string ¤t,
1188 bool ignore_used_subcommands = true) const;
1189
1190
1191
1192
1193 void _process_config_file();
1194
1195
1196 void _process_env();
1197
1198
1199 void _process_callbacks();
1200
1201
1202
1203
1204 void _process_help_flags(bool trigger_help = false, bool trigger_all_help = false) const;
1205
1206
1207 void _process_requirements();
1208
1209
1210 void _process();
1211
1212
1213 void _process_extras();
1214
1215
1216
1217 void _process_extras(std::vector<std::string> &args);
1218
1219
1220 void increment_parsed();
1221
1222
1223 void _parse(std::vector<std::string> &args);
1224
1225
1226 void _parse(std::vector<std::string> &&args);
1227
1228
1229 void _parse_stream(std::istream &input);
1230
1231
1232
1233
1234
1235 void _parse_config(const std::vector<ConfigItem> &args);
1236
1237
1238 bool _parse_single_config(const ConfigItem &item, std::size_t level = 0);
1239
1240
1241
1242 bool _parse_single(std::vector<std::string> &args, bool &positional_only);
1243
1244
1245 CLI11_NODISCARD std::size_t _count_remaining_positionals(bool required_only = false) const;
1246
1247
1248 CLI11_NODISCARD bool _has_remaining_positionals() const;
1249
1250
1251
1252
1253 bool _parse_positional(std::vector<std::string> &args, bool haltOnSubcommand);
1254
1255
1256
1257 CLI11_NODISCARD App *
1258 _find_subcommand(const std::string &subc_name, bool ignore_disabled, bool ignore_used) const noexcept;
1259
1260
1261
1262
1263
1264 bool _parse_subcommand(std::vector<std::string> &args);
1265
1266
1267
1268 bool _parse_arg(std::vector<std::string> &args, detail::Classifier current_type);
1269
1270
1271 void _trigger_pre_parse(std::size_t remaining_args);
1272
1273
1274 App *_get_fallthrough_parent();
1275
1276
1277 CLI11_NODISCARD const std::string &_compare_subcommand_names(const App &subcom, const App &base) const;
1278
1279
1280 void _move_to_missing(detail::Classifier val_type, const std::string &val);
1281
1282 public:
1283
1284 void _move_option(Option *opt, App *app);
1285 };
1286
1287
1288 class Option_group : public App {
1289 public:
1290 Option_group(std::string group_description, std::string group_name, App *parent)
1291 : App(std::move(group_description), "", parent) {
1292 group(group_name);
1293
1294 }
1295 using App::add_option;
1296
1297 Option *add_option(Option *opt) {
1298 if(get_parent() == nullptr) {
1299 throw OptionNotFound("Unable to locate the specified option");
1300 }
1301 get_parent()->_move_option(opt, this);
1302 return opt;
1303 }
1304
1305 void add_options(Option *opt) { add_option(opt); }
1306
1307 template <typename... Args> void add_options(Option *opt, Args... args) {
1308 add_option(opt);
1309 add_options(args...);
1310 }
1311 using App::add_subcommand;
1312
1313 App *add_subcommand(App *subcom) {
1314 App_p subc = subcom->get_parent()->get_subcommand_ptr(subcom);
1315 subc->get_parent()->remove_subcommand(subcom);
1316 add_subcommand(std::move(subc));
1317 return subcom;
1318 }
1319 };
1320
1321
1322 CLI11_INLINE void TriggerOn(App *trigger_app, App *app_to_enable);
1323
1324
1325 CLI11_INLINE void TriggerOn(App *trigger_app, std::vector<App *> apps_to_enable);
1326
1327
1328 CLI11_INLINE void TriggerOff(App *trigger_app, App *app_to_enable);
1329
1330
1331 CLI11_INLINE void TriggerOff(App *trigger_app, std::vector<App *> apps_to_enable);
1332
1333
1334 CLI11_INLINE void deprecate_option(Option *opt, const std::string &replacement = "");
1335
1336
1337 inline void deprecate_option(App *app, const std::string &option_name, const std::string &replacement = "") {
1338 auto *opt = app->get_option(option_name);
1339 deprecate_option(opt, replacement);
1340 }
1341
1342
1343 inline void deprecate_option(App &app, const std::string &option_name, const std::string &replacement = "") {
1344 auto *opt = app.get_option(option_name);
1345 deprecate_option(opt, replacement);
1346 }
1347
1348
1349 CLI11_INLINE void retire_option(App *app, Option *opt);
1350
1351
1352 CLI11_INLINE void retire_option(App &app, Option *opt);
1353
1354
1355 CLI11_INLINE void retire_option(App *app, const std::string &option_name);
1356
1357
1358 CLI11_INLINE void retire_option(App &app, const std::string &option_name);
1359
1360 namespace detail {
1361
1362 struct AppFriend {
1363 #ifdef CLI11_CPP14
1364
1365
1366 template <typename... Args> static decltype(auto) parse_arg(App *app, Args &&...args) {
1367 return app->_parse_arg(std::forward<Args>(args)...);
1368 }
1369
1370
1371 template <typename... Args> static decltype(auto) parse_subcommand(App *app, Args &&...args) {
1372 return app->_parse_subcommand(std::forward<Args>(args)...);
1373 }
1374 #else
1375
1376 template <typename... Args>
1377 static auto parse_arg(App *app, Args &&...args) ->
1378 typename std::result_of<decltype (&App::_parse_arg)(App, Args...)>::type {
1379 return app->_parse_arg(std::forward<Args>(args)...);
1380 }
1381
1382
1383 template <typename... Args>
1384 static auto parse_subcommand(App *app, Args &&...args) ->
1385 typename std::result_of<decltype (&App::_parse_subcommand)(App, Args...)>::type {
1386 return app->_parse_subcommand(std::forward<Args>(args)...);
1387 }
1388 #endif
1389
1390 static App *get_fallthrough_parent(App *app) { return app->_get_fallthrough_parent(); }
1391 };
1392 }
1393
1394
1395 }
1396
1397 #ifndef CLI11_COMPILE
1398 #include "impl/App_inl.hpp"
1399 #endif