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");