diff --git a/CHANGELOG.md b/CHANGELOG.md index 99c33d41..2b9b3578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Validators are now much more powerful [#118], all built in validators upgraded t Other changes: +* Better support for manual options with `get_option`, `set_results`, and `empty` [#119] * Using `add_set` will now capture L-values for sets, allowing further modification [#113] * Internally, `type_name` is now a lambda function; for sets, this reads the set live [#116] * Dropped duplicate way to run `get_type_name` (`get_typeval`) @@ -40,6 +41,7 @@ Other changes: [#113]: https://github.com/CLIUtils/CLI11/issues/113 [#116]: https://github.com/CLIUtils/CLI11/pull/116 [#118]: https://github.com/CLIUtils/CLI11/pull/118 +[#118]: https://github.com/CLIUtils/CLI11/pull/119 ### Version 1.5.3: Compiler compatibility This version fixes older AppleClang compilers by removing the optimization for casting. The minimum version of Boost Optional supported has been clarified to be 1.58. CUDA 7.0 NVCC is now supported. diff --git a/README.md b/README.md index dae4b1e2..e397bb8e 100644 --- a/README.md +++ b/README.md @@ -243,9 +243,10 @@ There are several options that are supported on the main app and subcommands. Th * `.require_subcommand(min, max)`: Explicitly set min and max allowed subcommands. Setting `max` to 0 is unlimited. * `.add_subcommand(name, description="")` Add a subcommand, returns a pointer to the internally stored subcommand. * `.got_subcommand(App_or_name)`: Check to see if a subcommand was received on the command line. -* `.get_subcommands()`: The list of subcommands given on the command line. +* `.get_subcommands(filter)`: The list of subcommands given on the command line. * `.get_parent()`: Get the parent App or nullptr if called on master App. -* `.get_options()`: Get the list of all defined option pointers (useful for processing the app for custom output formats). +* `.get_option(name)`: Get an option pointer by option name +* `.get_options(filter)`: Get the list of all defined option pointers (useful for processing the app for custom output formats). * `.parse_order()`: Get the list of option pointers in the order they were parsed (including duplicates). * `.formatter(fmt)`: Set a formatter, with signature `std::string(const App*, std::string, AppFormatMode)`. See Formatting for more details. * `.get_description()`: Access the description. @@ -260,7 +261,7 @@ There are several options that are supported on the main app and subcommands. Th * `.set_failure_message(func)`: Set the failure message function. Two provided: `CLI::FailureMessage::help` and `CLI::FailureMessage::simple` (the default). * `.group(name)`: Set a group name, defaults to `"Subcommands"`. Setting `""` will be hide the subcommand. -> Note: if you have a fixed number of required positional options, that will match before subcommand names. +> Note: if you have a fixed number of required positional options, that will match before subcommand names. `{}` is an empty filter function. ## Configuration file diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index 5de6ac72..2ecc5263 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -14,17 +15,16 @@ #include #include #include -#include // CLI Library includes #include "CLI/Error.hpp" +#include "CLI/FormatterFwd.hpp" #include "CLI/Ini.hpp" #include "CLI/Macros.hpp" #include "CLI/Option.hpp" #include "CLI/Split.hpp" #include "CLI/StringTools.hpp" #include "CLI/TypeTools.hpp" -#include "CLI/FormatterFwd.hpp" namespace CLI { @@ -1096,6 +1096,16 @@ class App { return options; } + /// Get an option by name + const Option *get_option(std::string name) const { + for(const Option_p &opt : options_) { + if(opt->check_name(name)) { + return opt.get(); + } + } + throw OptionNotFound(name); + } + /// Check the status of ignore_case bool get_ignore_case() const { return ignore_case_; } @@ -1404,28 +1414,28 @@ class App { if(!op->get_configurable()) throw INIError::NotConfigurable(current.fullname); - if(op->results_.empty()) { + if(op->empty()) { // Flag parsing if(op->get_type_size() == 0) { if(current.inputs.size() == 1) { std::string val = current.inputs.at(0); val = detail::to_lower(val); if(val == "true" || val == "on" || val == "yes") - op->results_ = {""}; + op->set_results({""}); else if(val == "false" || val == "off" || val == "no") ; else try { size_t ui = std::stoul(val); for(size_t i = 0; i < ui; i++) - op->results_.emplace_back(""); + op->add_result(""); } catch(const std::invalid_argument &) { throw ConversionError::TrueFalse(current.fullname); } } else throw ConversionError::TooManyInputsFlag(current.fullname); } else { - op->results_ = current.inputs; + op->set_results(current.inputs); op->run_callback(); } } diff --git a/include/CLI/Option.hpp b/include/CLI/Option.hpp index 5bc1bd84..4b64d9a8 100644 --- a/include/CLI/Option.hpp +++ b/include/CLI/Option.hpp @@ -238,8 +238,11 @@ class Option : public OptionBase