From 985a19f3860be0cba87354336f6588494b20111c Mon Sep 17 00:00:00 2001 From: Philip Top Date: Thu, 29 Jun 2023 08:29:32 -0700 Subject: [PATCH] fix some doc and error strings (#899) Update some doc strings and error output for clarity --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- README.md | 105 +++++++++++++++++++-------------- book/chapters/options.md | 2 +- include/CLI/Error.hpp | 3 + include/CLI/impl/Split_inl.hpp | 2 + tests/AppTest.cpp | 22 +++++++ 5 files changed, 88 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 74182c7d6..37cb707db 100644 --- a/README.md +++ b/README.md @@ -24,39 +24,43 @@ set with a simple and intuitive interface. ## Table of Contents -- [Background](#background) - - [Introduction](#introduction) - - [Why write another CLI parser?](#why-write-another-cli-parser) - - [Other parsers](#other-parsers) - - [Features not supported by this library](#features-not-supported-by-this-library) -- [Install](#install) -- [Usage](#usage) - - [Adding options](#adding-options) - - [Option types](#option-types) - - [Example](#example) - - [Option options](#option-options) - - [Validators](#validators) - - [Transforming Validators](#transforming-validators) - - [Validator operations](#validator-operations) - - [Custom Validators](#custom-validators) - - [Querying Validators](#querying-validators) - - [Getting Results](#getting-results) - - [Subcommands](#subcommands) - - [Subcommand options](#subcommand-options) - - [Option groups](#option-groups) - - [Callbacks](#callbacks) - - [Configuration file](#configuration-file) - - [Inheriting defaults](#inheriting-defaults) - - [Formatting](#formatting) - - [Subclassing](#subclassing) - - [How it works](#how-it-works) - - [Unicode support](#unicode-support) - - [Utilities](#utilities) - - [Other libraries](#other-libraries) -- [API](#api) -- [Examples](#Examples) -- [Contribute](#contribute) -- [License](#license) +- [CLI11: Command line parser for C++11](#cli11-command-line-parser-for-c11) + - [Table of Contents](#table-of-contents) + - [Background](#background) + - [Introduction](#introduction) + - [Why write another CLI parser?](#why-write-another-cli-parser) + - [Other parsers](#other-parsers) + - [Features not supported by this library](#features-not-supported-by-this-library) + - [Install](#install) + - [Usage](#usage) + - [Adding options](#adding-options) + - [Option types](#option-types) + - [Example](#example) + - [Option options](#option-options) + - [Validators](#validators) + - [Transforming Validators](#transforming-validators) + - [Validator operations](#validator-operations) + - [Custom Validators](#custom-validators) + - [Querying Validators](#querying-validators) + - [Getting results](#getting-results) + - [Subcommands](#subcommands) + - [Subcommand options](#subcommand-options) + - [Callbacks](#callbacks) + - [Option groups](#option-groups) + - [Configuration file](#configuration-file) + - [Inheriting defaults](#inheriting-defaults) + - [Formatting](#formatting) + - [Subclassing](#subclassing) + - [How it works](#how-it-works) + - [Example](#example-1) + - [Unicode support](#unicode-support) + - [Note on using Unicode paths](#note-on-using-unicode-paths) + - [Utilities](#utilities) + - [Other libraries](#other-libraries) + - [API](#api) + - [Examples](#examples) + - [Contribute](#contribute) + - [License](#license) Features that were added in the last released minor version are marked with "🆕". Features only available in main are marked with "🚧". @@ -224,7 +228,7 @@ include(FetchContent) FetchContent_Declare( cli11 GIT_REPOSITORY https://github.com/CLIUtils/CLI11 - GIT_TAG v2.2.0 + GIT_TAG v2.3.2 ) FetchContent_MakeAvailable(cli11) @@ -265,6 +269,10 @@ In some cases certain clang compilations may require linking against `libc++fs`. These situations have not been encountered so the specific situations requiring them are unknown yet. +If building with WASI it is necessary to add the flag +`-lc-printscan-long-double` to the build to allow long double support. See #841 +for more details. +


@@ -287,6 +295,9 @@ int main() { } ``` +The 🚧 `CLI11_PARSE(app)` is only available in main currently and not in a +release. +
Note: If you don't like macros, this is what that macro expands to: (click to expand)

```cpp @@ -309,7 +320,8 @@ interfere.

Note: Why are argc and argv not used? (click to expand)

`argc` and `argv` may contain incorrect information on Windows when unicode text -is passed in. Check out a section on [unicode support](#unicode-support) below. +is passed in. Check out a section on [unicode support](#unicode-support)🚧 +below. If this is not a concern, you can explicitly pass `argc` and `argv` from main or from an external preprocessor of CLI arguments to `parse`: @@ -514,8 +526,8 @@ Before parsing, you can set the following options: - `->envname(name)`: Gets the value from the environment if present and not passed on the command line. - `->group(name)`: The help group to put the option in. No effect for positional - options. Defaults to `"Options"`. `""` will not show up in the help print - (hidden). + options. Defaults to `"Options"`. Options given an empty string will not show + up in the help print (hidden). - `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments). - `->ignore_underscore()`: Ignore any underscores in the options names (also @@ -901,12 +913,15 @@ not used in performance critical code: ### Subcommands -Subcommands are supported, and can be nested infinitely. To add a subcommand, -call the `add_subcommand` method with a name and an optional description. This -gives a pointer to an `App` that behaves just like the main app, and can take -options or further subcommands. Add `->ignore_case()` to a subcommand to allow -any variation of caps to also be accepted. `->ignore_underscore()` is similar, -but for underscores. Children inherit the current setting from the parent. You +Subcommands are keywords that invoke a new set of options and features. For +example, the `git` command has a long series of subcommands, like `add` and +`commit`. Each can have its own options and implementations. Subcommands are +supported in CLI11, and can be nested infinitely. To add a subcommand, call the +`add_subcommand` method with a name and an optional description. This gives a +pointer to an `App` that behaves just like the main app, and can take options or +further subcommands. Add `->ignore_case()` to a subcommand to allow any +variation of caps to also be accepted. `->ignore_underscore()` is similar, but +for underscores. Children inherit the current setting from the parent. You cannot add multiple matching subcommand names at the same level (including `ignore_case` and `ignore_underscore`). @@ -1109,8 +1124,8 @@ option_groups. These are: 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. +- `.group(name)`: Set a group name, defaults to `"Subcommands"`. Setting an + empty string for the name will be hide the subcommand. - `[option_name]`: retrieve a const pointer to an option given by `option_name` for Example `app["--flag1"]` will get a pointer to the option for the "--flag1" value, `app["--flag1"]->as()` will get the results of the diff --git a/book/chapters/options.md b/book/chapters/options.md index 39447113b..3afe6d88d 100644 --- a/book/chapters/options.md +++ b/book/chapters/options.md @@ -215,7 +215,7 @@ that to add option modifiers. A full listing of the option modifiers: | `->needs(opt)` | This option requires another option to also be present, opt is an `Option` pointer or a string with the name of the option. Can be removed with `->remove_needs(opt)` | | `->excludes(opt)` | This option cannot be given with `opt` present, opt is an `Option` pointer or a string with the name of the option. Can be removed with `->remove_excludes(opt)` | | `->envname(name)` | Gets the value from the environment if present and not passed on the command line. | -| `->group(name)` | The help group to put the option in. No effect for positional options. Defaults to `"Options"`. `"Hidden"` will not show up in the help print. | +| `->group(name)` | The help group to put the option in. No effect for positional options. Defaults to `"Options"`. Options given an empty string for the group name will not show up in the help print. | | `->description(string)` | Set/change the description | | `->ignore_case()` | Ignore the case on the command line (also works on subcommands, does not affect arguments). | | `->ignore_underscore()` | Ignore any underscores on the command line (also works on subcommands, does not affect arguments). | diff --git a/include/CLI/Error.hpp b/include/CLI/Error.hpp index 0900da53c..93f8469ee 100644 --- a/include/CLI/Error.hpp +++ b/include/CLI/Error.hpp @@ -123,6 +123,9 @@ class BadNameString : public ConstructionError { CLI11_ERROR_DEF(ConstructionError, BadNameString) CLI11_ERROR_SIMPLE(BadNameString) static BadNameString OneCharName(std::string name) { return BadNameString("Invalid one char name: " + name); } + static BadNameString MissingDash(std::string name) { + return BadNameString("Long names strings require 2 dashes " + name); + } static BadNameString BadLongName(std::string name) { return BadNameString("Bad long name: " + name); } static BadNameString DashesOnly(std::string name) { return BadNameString("Must have a name, not just dashes: " + name); diff --git a/include/CLI/impl/Split_inl.hpp b/include/CLI/impl/Split_inl.hpp index d974f80a6..785bb79bf 100644 --- a/include/CLI/impl/Split_inl.hpp +++ b/include/CLI/impl/Split_inl.hpp @@ -114,6 +114,8 @@ get_names(const std::vector &input) { if(name.length() > 1 && name[0] == '-' && name[1] != '-') { if(name.length() == 2 && valid_first_char(name[1])) short_names.emplace_back(1, name[1]); + else if(name.length() > 2) + throw BadNameString::MissingDash(name); else throw BadNameString::OneCharName(name); } else if(name.length() > 2 && name.substr(0, 2) == "--") { diff --git a/tests/AppTest.cpp b/tests/AppTest.cpp index d0a8769e7..a0863d143 100644 --- a/tests/AppTest.cpp +++ b/tests/AppTest.cpp @@ -641,6 +641,28 @@ TEST_CASE_METHOD(TApp, "StrangeOptionNames", "[app]") { CHECK(app["--{}"]->as() == 5); } +TEST_CASE_METHOD(TApp, "singledash", "[app]") { + app.add_option("-t"); + try { + app.add_option("-test"); + } catch(const CLI::BadNameString &e) { + std::string str = e.what(); + CHECK_THAT(str, Contains("2 dashes")); + CHECK_THAT(str, Contains("-test")); + } catch(...) { + CHECK(false); + } + try { + app.add_option("-!"); + } catch(const CLI::BadNameString &e) { + std::string str = e.what(); + CHECK_THAT(str, Contains("one char")); + CHECK_THAT(str, Contains("-!")); + } catch(...) { + CHECK(false); + } +} + TEST_CASE_METHOD(TApp, "FlagLikeOption", "[app]") { bool val{false}; auto *opt = app.add_option("--flag", val)->type_size(0)->default_str("true");