mirror of
https://github.com/CLIUtils/CLI11.git
synced 2026-01-19 04:52:08 +00:00
Subcommand plurality (#1169)
Partially address #1168 fix subcommand plurality when subcommand_max count is 0 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -29,6 +29,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
try {
|
||||
if(pstring_start > 0) {
|
||||
app->parse(parseString.substr(pstring_start));
|
||||
// test to make sure no seg fault or other errors occur
|
||||
std::ignore = app->help("", CLI::AppFormatMode::All);
|
||||
} else {
|
||||
app->parse(parseString);
|
||||
}
|
||||
@@ -39,7 +41,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
// this just indicates we caught an error known by CLI
|
||||
return 0; // Non-zero return values are reserved for future use.
|
||||
}
|
||||
if(fuzzdata.support_config_file_only()) {
|
||||
if(fuzzdata.supports_config_file()) {
|
||||
CLI::FuzzApp fuzzdata2;
|
||||
auto app2 = fuzzdata2.generateApp();
|
||||
// should be able to write the config to a file and read from it again
|
||||
|
||||
@@ -555,6 +555,16 @@ std::size_t FuzzApp::add_custom_options(CLI::App *app, const std::string &descri
|
||||
}
|
||||
}
|
||||
current_index = end_option + 9;
|
||||
} else if(description_string.compare(current_index, 11, "<subcommand") == 0) {
|
||||
auto end_sub_label = description_string.find_first_of('>', current_index + 12);
|
||||
if(end_sub_label == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
auto end_sub = description_string.find("</subcommand>", end_sub_label + 1);
|
||||
if(end_sub == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
if(isspace(description_string[current_index]) != 0) {
|
||||
++current_index;
|
||||
|
||||
@@ -63,7 +63,7 @@ class FuzzApp {
|
||||
/** modify an option based on string*/
|
||||
static void modify_option(CLI::Option *opt, const std::string &modifier);
|
||||
|
||||
CLI11_NODISCARD bool support_config_file_only() const { return !non_config_required; }
|
||||
CLI11_NODISCARD bool supports_config_file() const { return !non_config_required; }
|
||||
int32_t val32{0};
|
||||
int16_t val16{0};
|
||||
int8_t val8{0};
|
||||
|
||||
@@ -133,8 +133,7 @@ CLI11_INLINE std::string Formatter::make_usage(const App *app, std::string name)
|
||||
[](const CLI::App *subc) { return ((!subc->get_disabled()) && (!subc->get_name().empty())); })
|
||||
.empty()) {
|
||||
out << ' ' << (app->get_require_subcommand_min() == 0 ? "[" : "")
|
||||
<< get_label(app->get_require_subcommand_max() < 2 || app->get_require_subcommand_min() > 1 ? "SUBCOMMAND"
|
||||
: "SUBCOMMANDS")
|
||||
<< get_label(app->get_require_subcommand_max() == 1 ? "SUBCOMMAND" : "SUBCOMMANDS")
|
||||
<< (app->get_require_subcommand_min() == 0 ? "]" : "");
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ TEST_CASE("Formatter: AppCustomize", "[formatter]") {
|
||||
app.add_subcommand("subcom2", "That");
|
||||
|
||||
std::string help = app.help();
|
||||
CHECK_THAT(help, Contains("Run: [OPTIONS] [SUBCOMMAND]\n\n"));
|
||||
CHECK_THAT(help, Contains("Run: [OPTIONS] [SUBCOMMANDS]\n\n"));
|
||||
CHECK_THAT(help, Contains("\nSUBCOMMANDS:\n"));
|
||||
CHECK_THAT(help, Contains(" subcom1 This \n"));
|
||||
CHECK_THAT(help, Contains(" subcom2 That \n"));
|
||||
@@ -142,7 +142,7 @@ TEST_CASE("Formatter: AppCustomizeSimple", "[formatter]") {
|
||||
app.add_subcommand("subcom2", "That");
|
||||
|
||||
std::string help = app.help();
|
||||
CHECK_THAT(help, Contains("Run: [OPTIONS] [SUBCOMMAND]\n\n"));
|
||||
CHECK_THAT(help, Contains("Run: [OPTIONS] [SUBCOMMANDS]\n\n"));
|
||||
CHECK_THAT(help, Contains("\nSUBCOMMANDS:\n"));
|
||||
CHECK_THAT(help, Contains(" subcom1 This \n"));
|
||||
CHECK_THAT(help, Contains(" subcom2 That \n"));
|
||||
|
||||
@@ -322,10 +322,11 @@ TEST_CASE("app_roundtrip_custom") {
|
||||
|
||||
if(pstring_start > 0) {
|
||||
app->parse(parseData.substr(pstring_start));
|
||||
CHECK_NOTHROW(app->help("", CLI::AppFormatMode::All));
|
||||
} else {
|
||||
app->parse(parseData);
|
||||
}
|
||||
if(fuzzdata.support_config_file_only()) {
|
||||
if(fuzzdata.supports_config_file()) {
|
||||
// should be able to write the config to a file and read from it again
|
||||
std::string configOut = app->config_to_str();
|
||||
std::stringstream out(configOut);
|
||||
|
||||
@@ -516,10 +516,14 @@ TEST_CASE("THelp: Subcom", "[help]") {
|
||||
app.add_subcommand("sub2");
|
||||
|
||||
std::string help = app.help();
|
||||
CHECK_THAT(help, Contains("Usage: [OPTIONS] [SUBCOMMAND]"));
|
||||
CHECK_THAT(help, Contains("Usage: [OPTIONS] [SUBCOMMANDS]"));
|
||||
|
||||
app.require_subcommand();
|
||||
|
||||
help = app.help();
|
||||
CHECK_THAT(help, Contains("Usage: [OPTIONS] SUBCOMMANDS"));
|
||||
app.require_subcommand(1);
|
||||
|
||||
help = app.help();
|
||||
CHECK_THAT(help, Contains("Usage: [OPTIONS] SUBCOMMAND"));
|
||||
|
||||
@@ -546,7 +550,7 @@ TEST_CASE("THelp: Subcom_alias", "[help]") {
|
||||
app.add_subcommand("sub2", "Subcommand2 description test");
|
||||
|
||||
std::string help = app.help();
|
||||
CHECK_THAT(help, Contains("Usage: [OPTIONS] [SUBCOMMAND]"));
|
||||
CHECK_THAT(help, Contains("Usage: [OPTIONS] [SUBCOMMANDS]"));
|
||||
CHECK_THAT(help, Contains("sub_alias1"));
|
||||
CHECK_THAT(help, Contains("sub_alias2"));
|
||||
}
|
||||
@@ -561,7 +565,7 @@ TEST_CASE("THelp: Subcom_alias_group", "[help]") {
|
||||
app.add_subcommand("sub2", "Subcommand2 description test");
|
||||
|
||||
std::string help = app.help();
|
||||
CHECK_THAT(help, Contains("Usage: [OPTIONS] [SUBCOMMAND]"));
|
||||
CHECK_THAT(help, Contains("Usage: [OPTIONS] [SUBCOMMANDS]"));
|
||||
CHECK_THAT(help, Contains("sub_alias1"));
|
||||
CHECK_THAT(help, Contains("sub_alias2"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user