Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand All @@ -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.
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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

Expand Down
22 changes: 16 additions & 6 deletions include/CLI/App.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <memory>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <iterator>

// 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 {

Expand Down Expand Up @@ -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_; }

Expand Down Expand Up @@ -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();
}
}
Expand Down
13 changes: 11 additions & 2 deletions include/CLI/Option.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,11 @@ class Option : public OptionBase<Option> {
/// Count the total number of times an option was passed
size_t count() const { return results_.size(); }

/// True if the option was not passed
size_t empty() const { return results_.empty(); }

/// This class is true if option is passed.
operator bool() const { return count() > 0; }
operator bool() const { return !empty(); }

/// Clear the parsed results (mostly for testing)
void clear() { results_.clear(); }
Expand Down Expand Up @@ -593,12 +596,18 @@ class Option : public OptionBase<Option> {
return std::find(std::begin(lnames_), std::end(lnames_), name) != std::end(lnames_);
}

/// Puts a result at the end, unless last_ is set, in which case it just keeps the last one
/// Puts a result at the end
void add_result(std::string s) {
results_.push_back(s);
callback_run_ = false;
}

/// Set the results vector all at once
void set_results(std::vector<std::string> results) {
results_ = results;
callback_run_ = false;
}

/// Get a copy of the results
std::vector<std::string> results() const { return results_; }

Expand Down