mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-01-15 06:38:02 +00:00
Compare commits
3 Commits
15bb724e06
...
25cca2dcb9
Author | SHA1 | Date | |
---|---|---|---|
|
25cca2dcb9 | ||
|
a8ef5b8d2f | ||
|
2fa8cae9e8 |
@ -599,6 +599,7 @@ There are several options that are supported on the main app and subcommands and
|
||||
- `.footer(message)`: Set text to appear at the bottom of the help string.
|
||||
- `.footer(std::string())`: 🆕 Set a callback to generate a string that will appear at the end of the help string.
|
||||
- `.set_help_flag(name, message)`: Set the help flag name and message, returns a pointer to the created option.
|
||||
- `.set_version_flag(name, versionString or callback, help_message)`: 🆕 Set the version flag name and version string or callback and optional help message, returns a pointer to the created option.
|
||||
- `.set_help_all_flag(name, message)`: Set the help all flag name and message, returns a pointer to the created option. Expands subcommands.
|
||||
- `.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.
|
||||
@ -798,7 +799,7 @@ Every `add_` option you have seen so far depends on one method that takes a lamb
|
||||
|
||||
Other values can be added as long as they support `operator>>` (and defaults can be printed if they support `operator<<`). To add a new type, for example, provide a custom `operator>>` with an `istream` (inside the CLI namespace is fine if you don't want to interfere with an existing `operator>>`).
|
||||
|
||||
If you wanted to extend this to support a completely new type, use a lambda or add a specialization of the `lexical_cast` function template in the namespace `CLI::detail` with the type you need to convert to. Some examples of some new parsers for `complex<double>` that support all of the features of a standard `add_options` call are in [one of the tests](./tests/NewParseTest.cpp). A simpler example is shown below:
|
||||
If you wanted to extend this to support a completely new type, use a lambda or add a specialization of the `lexical_cast` function template in the namespace of the type you need to convert to. Some examples of some new parsers for `complex<double>` that support all of the features of a standard `add_options` call are in [one of the tests](./tests/NewParseTest.cpp). A simpler example is shown below:
|
||||
|
||||
#### Example
|
||||
|
||||
@ -870,6 +871,7 @@ The API is [documented here][api-docs]. Also see the [CLI11 tutorial GitBook][gi
|
||||
Several short examples of different features are included in the repository. A brief description of each is included here
|
||||
|
||||
- [callback_passthrough](https://github.com/CLIUtils/CLI11/blob/master/examples/callback_passthrough.cpp): Example of directly passing remaining arguments through to a callback function which generates a CLI11 application based on existing arguments.
|
||||
- [custom_parse](https://github.com/CLIUtils/CLI11/blob/master/examples/custom_parse.cpp): Based on [Issue #566](https://github.com/CLIUtils/CLI11/issues/566), example of custom parser
|
||||
- [digit_args](https://github.com/CLIUtils/CLI11/blob/master/examples/digit_args.cpp): Based on [Issue #123](https://github.com/CLIUtils/CLI11/issues/123), uses digit flags to pass a value
|
||||
- [enum](https://github.com/CLIUtils/CLI11/blob/master/examples/enum.cpp): Using enumerations in an option, and the use of [CheckedTransformer](#transforming-validators)
|
||||
- [enum_ostream](https://github.com/CLIUtils/CLI11/blob/master/examples/enum_ostream.cpp): In addition to the contents of example enum.cpp, this example shows how a custom ostream operator overrides CLI11's enum streaming.
|
||||
|
@ -242,3 +242,8 @@ set_property(TEST retired_retired_test2 PROPERTY PASS_REGULAR_EXPRESSION "WARNIN
|
||||
set_property(TEST retired_retired_test3 PROPERTY PASS_REGULAR_EXPRESSION "WARNING.*retired")
|
||||
|
||||
set_property(TEST retired_deprecated PROPERTY PASS_REGULAR_EXPRESSION "deprecated.*not_deprecated")
|
||||
|
||||
#--------------------------------------------
|
||||
add_cli_exe(custom_parse custom_parse.cpp)
|
||||
add_test(NAME cp_test COMMAND custom_parse --dv 1.7)
|
||||
set_property(TEST cp_test PROPERTY PASS_REGULAR_EXPRESSION "called correct")
|
||||
|
39
examples/custom_parse.cpp
Normal file
39
examples/custom_parse.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2017-2020, University of Cincinnati, developed by Henry Schreiner
|
||||
// under NSF AWARD 1414736 and by the respective contributors.
|
||||
// All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// from Issue #566 on github https://github.com/CLIUtils/CLI11/issues/566
|
||||
|
||||
#include <CLI/CLI.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
// example file to demonstrate a custom lexical cast function
|
||||
|
||||
template <class T = int> struct Values {
|
||||
T a;
|
||||
T b;
|
||||
T c;
|
||||
};
|
||||
|
||||
// in C++20 this is constructible from a double due to the new aggregate initialization in C++20.
|
||||
using DoubleValues = Values<double>;
|
||||
|
||||
// the lexical cast operator should be in the same namespace as the type for ADL to work properly
|
||||
bool lexical_cast(const std::string &input, Values<double> &v) {
|
||||
std::cout << "called correct lexical_cast function ! val: " << input << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
DoubleValues doubles;
|
||||
void argparse(CLI::Option_group *group) { group->add_option("--dv", doubles)->default_str("0"); }
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
CLI::App app;
|
||||
|
||||
argparse(app.add_option_group("param"));
|
||||
CLI11_PARSE(app, argc, argv);
|
||||
return 0;
|
||||
}
|
@ -732,7 +732,9 @@ class App {
|
||||
}
|
||||
|
||||
/// Set a version flag and version display string, replace the existing one if present
|
||||
Option *set_version_flag(std::string flag_name = "", const std::string &versionString = "") {
|
||||
Option *set_version_flag(std::string flag_name = "",
|
||||
const std::string &versionString = "",
|
||||
const std::string &version_help = "Display program version information and exit") {
|
||||
// take flag_description by const reference otherwise add_flag tries to assign to version_description
|
||||
if(version_ptr_ != nullptr) {
|
||||
remove_option(version_ptr_);
|
||||
@ -742,17 +744,16 @@ class App {
|
||||
// Empty name will simply remove the version flag
|
||||
if(!flag_name.empty()) {
|
||||
version_ptr_ = add_flag_callback(
|
||||
flag_name,
|
||||
[versionString]() { throw(CLI::CallForVersion(versionString, 0)); },
|
||||
"Display program version information and exit");
|
||||
flag_name, [versionString]() { throw(CLI::CallForVersion(versionString, 0)); }, version_help);
|
||||
version_ptr_->configurable(false);
|
||||
}
|
||||
|
||||
return version_ptr_;
|
||||
}
|
||||
/// Generate the version string through a callback function
|
||||
Option *set_version_flag(std::string flag_name, std::function<std::string()> vfunc) {
|
||||
// take flag_description by const reference otherwise add_flag tries to assign to version_description
|
||||
Option *set_version_flag(std::string flag_name,
|
||||
std::function<std::string()> vfunc,
|
||||
const std::string &version_help = "Display program version information and exit") {
|
||||
if(version_ptr_ != nullptr) {
|
||||
remove_option(version_ptr_);
|
||||
version_ptr_ = nullptr;
|
||||
@ -761,9 +762,7 @@ class App {
|
||||
// Empty name will simply remove the version flag
|
||||
if(!flag_name.empty()) {
|
||||
version_ptr_ = add_flag_callback(
|
||||
flag_name,
|
||||
[vfunc]() { throw(CLI::CallForVersion(vfunc(), 0)); },
|
||||
"Display program version information and exit");
|
||||
flag_name, [vfunc]() { throw(CLI::CallForVersion(vfunc(), 0)); }, version_help);
|
||||
version_ptr_->configurable(false);
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ ConfigBase::to_config(const App *app, bool default_also, bool write_description,
|
||||
std::vector<std::string> groups = app->get_groups();
|
||||
bool defaultUsed = false;
|
||||
groups.insert(groups.begin(), std::string("Options"));
|
||||
if(write_description) {
|
||||
if(write_description && (app->get_configurable() || app->get_parent() == nullptr || app->get_name().empty())) {
|
||||
out << commentLead << app->get_description() << '\n';
|
||||
}
|
||||
for(auto &group : groups) {
|
||||
|
@ -1888,6 +1888,27 @@ TEST_CASE_METHOD(TApp, "TomlOutputSubsubcomConfigurable", "[config]") {
|
||||
CHECK(std::string::npos == str.find("sub2.newest=true"));
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "TomlOutputSubcomNonConfigurable", "[config]") {
|
||||
|
||||
app.add_flag("--simple");
|
||||
auto subcom = app.add_subcommand("other", "other_descriptor")->configurable();
|
||||
subcom->add_flag("--newer");
|
||||
|
||||
auto subcom2 = app.add_subcommand("sub2", "descriptor2");
|
||||
subcom2->add_flag("--newest")->configurable(false);
|
||||
|
||||
args = {"--simple", "other", "--newer", "sub2", "--newest"};
|
||||
run();
|
||||
|
||||
std::string str = app.config_to_str(true, true);
|
||||
CHECK_THAT(str, Contains("other_descriptor"));
|
||||
CHECK_THAT(str, Contains("simple=true"));
|
||||
CHECK_THAT(str, Contains("[other]"));
|
||||
CHECK_THAT(str, Contains("newer=true"));
|
||||
CHECK_THAT(str, !Contains("newest"));
|
||||
CHECK_THAT(str, !Contains("descriptor2"));
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "TomlOutputSubsubcomConfigurableDeep", "[config]") {
|
||||
|
||||
app.add_flag("--simple");
|
||||
|
@ -1220,6 +1220,21 @@ TEST_CASE("TVersion: callback_flag", "[help]") {
|
||||
CHECK_THAT(vers, Contains("VERSION"));
|
||||
}
|
||||
|
||||
TEST_CASE("TVersion: help", "[help]") {
|
||||
|
||||
CLI::App app;
|
||||
|
||||
app.set_version_flag("-v,--version", "version_string", "help_for_version");
|
||||
|
||||
auto hvers = app.help();
|
||||
CHECK_THAT(hvers, Contains("help_for_version"));
|
||||
|
||||
app.set_version_flag(
|
||||
"-v", []() { return std::string("VERSION2 " CLI11_VERSION); }, "help_for_version2");
|
||||
hvers = app.help();
|
||||
CHECK_THAT(hvers, Contains("help_for_version2"));
|
||||
}
|
||||
|
||||
TEST_CASE("TVersion: parse_throw", "[help]") {
|
||||
|
||||
CLI::App app;
|
||||
|
Loading…
Reference in New Issue
Block a user