diff --git a/contrib/CLI11/README.contrib b/contrib/CLI11/README.contrib index c0e274270..04e057e2d 100644 --- a/contrib/CLI11/README.contrib +++ b/contrib/CLI11/README.contrib @@ -1,2 +1,2 @@ Source: https://github.com/CLIUtils/CLI11 -Revision: v2.3.2 +Revision: v2.4.1 diff --git a/contrib/CLI11/README.md b/contrib/CLI11/README.md index 3127be8a3..7a26fb251 100644 --- a/contrib/CLI11/README.md +++ b/contrib/CLI11/README.md @@ -4,7 +4,6 @@ [![Build Status Azure][azure-badge]][azure] [![Actions Status][actions-badge]][actions-link] -[![Build Status AppVeyor][appveyor-badge]][appveyor] [![Code Coverage][codecov-badge]][codecov] [![Codacy Badge][codacy-badge]][codacy-link] [![License: BSD][license-badge]](./LICENSE) [![DOI][doi-badge]][doi-link] @@ -14,7 +13,7 @@ [![Latest release][repology-badge]][repology] [![Conan.io][conan-badge]][conan-link] [![Conda Version][conda-badge]][conda-link] -[![Try CLI11 2.1 online][wandbox-badge]][wandbox-link] +[![Try CLI11 2.4 online][wandbox-badge]][wandbox-link] [What's new](./CHANGELOG.md) β€’ [Documentation][gitbook] β€’ [API Reference][api-docs] @@ -52,7 +51,6 @@ set with a simple and intuitive interface. - [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) @@ -207,8 +205,8 @@ int main(int argc, char** argv) { } ``` -For more information about 🚧`ensure_utf8` the section on -[Unicode support](#unicode-support) below. The 🚧`ensure_utf8` function is only +For more information about πŸ†•`ensure_utf8` the section on +[Unicode support](#unicode-support) below. The πŸ†•`ensure_utf8` function 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)

@@ -417,7 +415,7 @@ Before parsing, you can set the following options: option. Options can be removed from the excludes list with `->remove_excludes(opt)` - `->envname(name)`: Gets the value from the environment if present and not - passed on the command line. 🚧 The value must also pass any validators to be + passed on the command line. πŸ†• The value must also pass any validators to be used. - `->group(name)`: The help group to put the option in. No effect for positional options. Defaults to `"Options"`. Options given an empty string will not show @@ -452,8 +450,8 @@ Before parsing, you can set the following options: This equivalent to calling `->delimiter(delim)` and `->join()`. Valid values are `CLI::MultiOptionPolicy::Throw`, `CLI::MultiOptionPolicy::Throw`, `CLI::MultiOptionPolicy::TakeLast`, `CLI::MultiOptionPolicy::TakeFirst`, - `CLI::MultiOptionPolicy::Join`, `CLI::MultiOptionPolicy::TakeAll`, and - `CLI::MultiOptionPolicy::Sum` πŸ†•. + `CLI::MultiOptionPolicy::Join`, `CLI::MultiOptionPolicy::TakeAll`, + `CLI::MultiOptionPolicy::Sum`, and `CLI::MultiOptionPolicy::Reverse` πŸ†•. - `->check(std::string(const std::string &), validator_name="",validator_description="")`: Define a check function. The function should return a non empty string with the error message if the check fails @@ -695,7 +693,7 @@ NOTES: If the container used in `IsMember`, `Transformer`, or fast search is performed first, and if that fails a linear search with the filters on the key values is performed. -- `CLI::FileOnDefaultPath(default_path)`: πŸ†• can be used to check for files in a +- `CLI::FileOnDefaultPath(default_path)`: can be used to check for files in a default path. If used as a transform it will first check that a file exists, if it does nothing further is done, if it does not it tries to add a default Path to the file and search there again. If the file does not exist an error @@ -703,6 +701,17 @@ filters on the key values is performed. `CLI::FileOnDefaultPath(default_path, false)`. This allows multiple paths to be chained using multiple transform calls. +- `CLI::EscapedString`: πŸ†• can be used to process an escaped string. The + processing is equivalent to that used for TOML config files, see + [TOML strings](https://toml.io/en/v1.0.0#string). With 2 notable exceptions. + \` can also be used as a literal string notation, and it also allows binary + string notation see + [binary strings](https://cliutils.github.io/CLI11/book/chapters/config.html). + The escaped string processing will remove outer quotes if present, `"` will + indicate a string with potential escape sequences, `'` and \` will indicate a + literal string and the quotes removed but no escape sequences will be + processed. This is the same escape processing as used in config files. + ##### Validator operations Validators are copyable and have a few operations that can be performed on them @@ -864,7 +873,7 @@ nameless subcommands are allowed. Callbacks for nameless subcommands are only triggered if any options from the subcommand were parsed. Subcommand names given through the `add_subcommand` method have the same restrictions as option names. -🚧 Options or flags in a subcommand may be directly specified using dot notation +πŸ†• Options or flags in a subcommand may be directly specified using dot notation - `--subcommand.long=val` (long subcommand option) - `--subcommand.long val` (long subcommand option) @@ -874,9 +883,11 @@ through the `add_subcommand` method have the same restrictions as option names. - `--subcommand1.subsub.f val` (short form nested subcommand option) The use of dot notation in this form is equivalent `--subcommand.long ` => -`subcommand --long ++`. Nested subcommands also work `"sub1.subsub"` -would trigger the subsub subcommand in `sub1`. This is equivalent to "sub1 -subsub" +`subcommand --long ++`. Nested subcommands also work `sub1.subsub` would +trigger the subsub subcommand in `sub1`. This is equivalent to "sub1 subsub". +Quotes around the subcommand names are permitted πŸ†• following the TOML standard +for such specification. This includes allowing escape sequences. For example +`"subcommand".'f'` or `"subcommand.with.dots".arg1 = value`. #### Subcommand options @@ -914,9 +925,9 @@ option_groups. These are: before matching. Validation is specified through `transform`, `check`, and `each` for an option. If an argument fails validation it is not an error and matching proceeds to the next available positional or extra arguments. -- `.validate_optional_arguments()`:πŸ†• Specify that optional arguments should - pass validation before being assigned to an option. Validation is specified - through `transform`, `check`, and `each` for an option. If an argument fails +- `.validate_optional_arguments()`: Specify that optional arguments should pass + validation before being assigned to an option. Validation is specified through + `transform`, `check`, and `each` for an option. If an argument fails validation it is not an error and matching proceeds to the next available positional subcommand or extra arguments. - `.excludes(option_or_subcommand)`: If given an option pointer or pointer to @@ -1002,10 +1013,10 @@ option_groups. These are: - `.prefix_command()`: Like `allow_extras`, but stop immediately on the first unrecognized item. It is ideal for allowing your app or subcommand to be a "prefix" to calling another app. -- `.usage(message)`: Replace text to appear at the start of the help string +- `.usage(message)`: πŸ†• Replace text to appear at the start of the help string after description. -- `.usage(std::string())`: Set a callback to generate a string that will appear - at the start of the help string after description. +- `.usage(std::string())`: πŸ†• Set a callback to generate a string that will + appear at the start of the help string after description. - `.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. @@ -1026,9 +1037,11 @@ option_groups. These are: command line for a flag. The operation will throw an exception if the option name is not valid. -> Note: if you have a fixed number of required positional options, that will -> match before subcommand names. `{}` is an empty filter function, and any -> positional argument will match before repeated subcommand names. +> [!NOTE] +> +> If you have a fixed number of required positional options, that will match +> before subcommand names. `{}` is an empty filter function, and any positional +> argument will match before repeated subcommand names. #### Callbacks @@ -1208,18 +1221,22 @@ option (like `set_help_flag`). Setting a configuration option is special. If it is present, it will be read along with the normal command line arguments. The file will be read if it exists, and does not throw an error unless `required` is `true`. Configuration files are in [TOML][] format by default, though the -default reader can also accept files in INI format as well. It should be noted -that CLI11 does not contain a full TOML parser but can read strings from most -TOML file and run them through the CLI11 parser. Other formats can be added by -an adept user, some variations are available through customization points in the -default formatter. An example of a TOML file: +default reader can also accept files in INI format as well. The config reader +can read most aspects of TOML files including strings both literal πŸ†• and with +potential escape sequences πŸ†•, digit separators πŸ†•, and multi-line strings πŸ†•, +and run them through the CLI11 parser. Other formats can be added by an adept +user, some variations are available through customization points in the default +formatter. An example of a TOML file: ```toml # Comments are supported, using a # # The default section is [default], case insensitive value = 1 +value2 = 123_456 # a string with separators str = "A string" +str2 = "A string\nwith new lines" +str3 = 'A literal "string"' vector = [1,2,3] str_vector = ["one","two","and three"] @@ -1227,6 +1244,7 @@ str_vector = ["one","two","and three"] [subcommand] in_subcommand = Wow sub.subcommand = true +"sub"."subcommand2" = "string_value" ``` or equivalently in INI format @@ -1278,9 +1296,9 @@ boolean values are not quoted. For options or flags which allow 0 arguments to be passed using an empty string in the config file, `{}`, or `[]` will convert the result to the default value -specified via `default_str` or `default_val` on the option πŸ†•. If no user -specified default is given the result is an empty string or the converted value -of an empty string. +specified via `default_str` or `default_val` on the option. If no user specified +default is given the result is an empty string or the converted value of an +empty string. NOTE: Transforms and checks can be used with the option pointer returned from set_config like any other option to validate the input if needed. It can also be @@ -1408,71 +1426,46 @@ CLI11 supports Unicode and wide strings as defined in the When using the command line on Windows with unicode arguments, your `main` function may already receive broken Unicode. Parsing `argv` at that point will -not give you a correct string. To fix this, you have three good options and two -bad ones: - -1. Replace `argv` with `app.ensure_utf8(argv)` before any arguments are parsed. - `ensure_utf8` will do nothing on systems where `argv` is already in UTF-8 - (Such as Linux or macOS) and return `argv` unmodified. On Windows, it will - discard `argv` and replace it with a correctly decoded array or arguments - from win32 API. - - ```cpp - int main(int argc, char** argv) { - CLI::App app; - argv = app.ensure_utf8(argv); // new argv memory is held by app - // ... - CLI11_PARSE(app, argc, argv); - } - ``` - -2. If you pass unmodified command-line arguments to CLI11, call `app.parse()` - instead of `app.parse(argc, argv)` (or `CLI11_PARSE(app)` instead of - `CLI11_PARSE(app, argc, argv)`). The library will find correct arguments by - itself. - - Note: this approach may not work on weird OS configurations, such as when the - `/proc` dir is missing on Linux systems (see also - [#845](https://github.com/CLIUtils/CLI11/issues/845)). - - ```cpp - int main() { - CLI::App app; - // ... - CLI11_PARSE(app); - } - ``` - -3. Get correct arguments with which the program was originally executed using - provided functions: `CLI::argc()` and `CLI::argv()`. These three methods are - the only cross-platform ways of handling unicode correctly. - - ```cpp - int main() { - CLI::App app; - // ... - CLI11_PARSE(app, CLI::argc(), CLI::argv()); - } - ``` - -

Bad options (click to expand)

- -4. Use the Windows-only non-standard `wmain` function, which accepts - `wchar_t *argv[]` instead of `char* argv[]`. Parsing this will allow CLI to - convert wide strings to UTF-8 without losing information. - - ```cpp - int wmain(int argc, wchar_t *argv[]) { - CLI::App app; - // ... - CLI11_PARSE(app, argc, argv); - } - ``` - -5. Retrieve arguments yourself by using Windows APIs like - [`CommandLineToArgvW`](https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw) - and pass them to CLI. This is what the library is doing under the hood in - `CLI::argv()`. +not give you a correct string. To fix this, you have three options; the first is +recommended for cross-platform support: + +1\. Replace `argv` with `app.ensure_utf8(argv)` before any arguments are parsed. +`ensure_utf8` will do nothing on systems where `argv` is already in UTF-8 (Such +as Linux or macOS) and return `argv` unmodified. On Windows, it will discard +`argv` and replace it with a correctly decoded array or arguments from win32 +API. + +```cpp +int main(int argc, char** argv) { + CLI::App app; + argv = app.ensure_utf8(argv); // new argv memory is held by app + // ... + CLI11_PARSE(app, argc, argv); +} +``` + +Be sure you do not modify `argv` before this function call, as the correct +values will be reconstructed using Windows APIs and produced by this call. It +has no effect on other platforms and just passes through `argv`. + +

Other options (click to expand)

+ +2\. Use the Windows-only non-standard `wmain` function, which accepts +`wchar_t *argv[]` instead of `char* argv[]`. Parsing this will allow CLI to +convert wide strings to UTF-8 without losing information. + +```cpp +int wmain(int argc, wchar_t *argv[]) { + CLI::App app; + // ... + CLI11_PARSE(app, argc, argv); +} +``` + +3\. Retrieve arguments yourself by using Windows APIs like +[`CommandLineToArgvW`](https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw) +and pass them to CLI. This is what the library is doing under the hood in +`ensure_utf8`.


@@ -1580,6 +1573,9 @@ GitBook][gitbook]. Several short examples of different features are included in the repository. A brief description of each is included here +- [arg_capture](https://github.com/CLIUtils/CLI11/blob/main/examples/arg_capture.cpp): + Example of capturing all remaining arguments after a specific option, using + subcommand and prefix_command() with an alias. - [callback_passthrough](https://github.com/CLIUtils/CLI11/blob/main/examples/callback_passthrough.cpp): Example of directly passing remaining arguments through to a callback function which generates a CLI11 application based on existing arguments. @@ -1661,71 +1657,100 @@ thanks to all the contributors - - + + + + + + - - - - - + + - - - - - + + + + - + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + - - - - - - - - - - - + + + +
Henry Schreiner
Henry Schreiner

πŸ› πŸ“– πŸ’»
Philip Top
Philip Top

πŸ› πŸ“– πŸ’»
Alex Dewar
Alex Dewar

πŸ’»
Andrew Hardin
Andrew Hardin

πŸ’»
Andrey Zhukov
Andrey Zhukov

πŸ’»
Anton
Anton

πŸ’»
Artem Trokhymchuk
Artem Trokhymchuk

πŸ’»
Benjamin Beichler
Benjamin Beichler

πŸ’»
Christoph Bachhuber
Christoph Bachhuber

πŸ’‘ πŸ’»
Marcus Brinkmann
Marcus Brinkmann

πŸ› πŸ’»
Jonas Nilsson
Jonas Nilsson

πŸ› πŸ’»
Doug Johnston
Doug Johnston

πŸ› πŸ’»
Lucas Czech
Lucas Czech

πŸ› πŸ’»
Rafi Wiener
Rafi Wiener

πŸ› πŸ’»
D. Fleury
D. Fleury

πŸ’»
Dan Barowy
Dan Barowy

πŸ“–
Daniel Mensinger
Daniel Mensinger

πŸ“¦
Jesus Briales
Jesus Briales

πŸ’» πŸ›
Sean Fisk
Sean Fisk

πŸ› πŸ’»
fpeng1985
fpeng1985

πŸ’»
almikhayl
almikhayl

πŸ’» πŸ“¦
Andrew Hardin
Andrew Hardin

πŸ’»
DarkWingMcQuack
DarkWingMcQuack

πŸ’»
Dominik Steinberger
Dominik Steinberger

πŸ’»
Doug Johnston
Doug Johnston

πŸ› πŸ’»
Eli Schwartz
Eli Schwartz

πŸ’»
Anton
Anton

πŸ’»
Fred HelmesjΓΆ
Fred HelmesjΓΆ

πŸ› πŸ’»
Henry Schreiner
Henry Schreiner

πŸ› πŸ“– πŸ’»
Isabella Muerte
Isabella Muerte

πŸ“¦
Izzy Muerte
Izzy Muerte

πŸ’»
Jakob Lover
Jakob Lover

πŸ’»
James Gerity
James Gerity

πŸ“–
Jesus Briales
Jesus Briales

πŸ’» πŸ›
Jonas Nilsson
Jonas Nilsson

πŸ› πŸ’»
Jose Luis Rivero
Jose Luis Rivero

πŸ’»
Josh Soref
Josh Soref

πŸ”§
KOLANICH
KOLANICH

πŸ“¦
Kannan
Kannan

πŸ› πŸ’»
Khem Raj
Khem Raj

πŸ’»
Lars Nielsen
Lars Nielsen

πŸ’»
Lucas Czech
Lucas Czech

πŸ› πŸ’»
Mak Kolybabi
Mak Kolybabi

πŸ“–
Marcin Ropa
Marcin Ropa

πŸ’»
Marcus Brinkmann
Marcus Brinkmann

πŸ› πŸ’»
Mathias Soeken
Mathias Soeken

πŸ“–
Nathan Hourt
Nathan Hourt

πŸ› πŸ’»
Matt McCormick
Matt McCormick

πŸ’»
Max
Max

πŸ’»
Michael Hall
Michael Hall

πŸ“–
Nathan Hourt
Nathan Hourt

πŸ› πŸ’»
Nathaniel Hourt
Nathaniel Hourt

πŸ’»
Olaf Meeuwissen
Olaf Meeuwissen

πŸ’»
OndΕ™ej ČertΓ­k
OndΕ™ej ČertΓ­k

πŸ›
Paul le Roux
Paul le Roux

πŸ’» πŸ“¦
PaweΕ‚ Bylica
PaweΕ‚ Bylica

πŸ“¦
PeteAudinate
PeteAudinate

πŸ’»
Peter Azmanov
Peter Azmanov

πŸ’»
Peter Harris
Peter Harris

πŸ’»
Peter Heywood
Peter Heywood

πŸ’»
Philip Top
Philip Top

πŸ› πŸ“– πŸ’»
Rafi Wiener
Rafi Wiener

πŸ› πŸ’»
RangeMachine
RangeMachine

πŸ’»
Robert Adam
Robert Adam

πŸ’»
Ryan Curtin
Ryan Curtin

πŸ“–
Ryan Sherlock
Ryan Sherlock

πŸ’»
Sam Hocevar
Sam Hocevar

πŸ’»
Sean Fisk
Sean Fisk

πŸ› πŸ’»
StΓ©phane Del Pino
StΓ©phane Del Pino

πŸ’»
Viacheslav Kroilov
Viacheslav Kroilov

πŸ’»
Volker Christian
Volker Christian

πŸ’»
almikhayl
almikhayl

πŸ’» πŸ“¦
ayum
ayum

πŸ’»
captainurist
captainurist

πŸ’»
christos
christos

πŸ’»
deining
deining

πŸ“–
dherrera-fb
dherrera-fb

πŸ’»
djerius
djerius

πŸ’»
dryleev
dryleev

πŸ’»
elszon
elszon

πŸ’»
ncihnegn
ncihnegn

πŸ’»
nurelin
nurelin

πŸ’»
ryan4729
ryan4729

⚠️
Isabella Muerte
Isabella Muerte

πŸ“¦
KOLANICH
KOLANICH

πŸ“¦
James Gerity
James Gerity

πŸ“–
Josh Soref
Josh Soref

πŸ”§
geir-t
geir-t

πŸ“¦
OndΕ™ej ČertΓ­k
OndΕ™ej ČertΓ­k

πŸ›
Sam Hocevar
Sam Hocevar

πŸ’»
Ryan Curtin
Ryan Curtin

πŸ“–
Michael Hall
Michael Hall

πŸ“–
ferdymercury
ferdymercury

πŸ“–
fpeng1985
fpeng1985

πŸ’»
geir-t
geir-t

πŸ“¦
ncihnegn
ncihnegn

πŸ’»
Jakob Lover
Jakob Lover

πŸ’»
Dominik Steinberger
Dominik Steinberger

πŸ’»
D. Fleury
D. Fleury

πŸ’»
Dan Barowy
Dan Barowy

πŸ“–
Olaf Meeuwissen
Olaf Meeuwissen

πŸ’»
dryleev
dryleev

πŸ’»
Max
Max

πŸ’»
Alex Dewar
Alex Dewar

πŸ’»
Artem Trokhymchuk
Artem Trokhymchuk

πŸ’»
nurelin
nurelin

πŸ’»
polistern
polistern

πŸ’»
ryan4729
ryan4729

⚠️
shameekganguly
shameekganguly

πŸ’»
@@ -1757,9 +1782,6 @@ try! Feedback is always welcome. [actions-link]: https://github.com/CLIUtils/CLI11/actions [actions-badge]: https://github.com/CLIUtils/CLI11/actions/workflows/tests.yml/badge.svg -[appveyor-badge]: - https://ci.appveyor.com/api/projects/status/82niaxpaa28dwbms/branch/main?svg=true -[appveyor]: https://ci.appveyor.com/project/HenrySchreiner/cli11 [repology-badge]: https://repology.org/badge/latest-versions/cli11.svg [repology]: https://repology.org/project/cli11/versions [codecov-badge]: @@ -1806,7 +1828,7 @@ try! Feedback is always welcome. [version 1.6 post]: https://iscinumpy.gitlab.io/post/announcing-cli11-16/ [version 2.0 post]: https://iscinumpy.gitlab.io/post/announcing-cli11-20/ [wandbox-badge]: https://img.shields.io/badge/try_2.1-online-blue.svg -[wandbox-link]: https://wandbox.org/permlink/CA5bymNHh0AczdeN +[wandbox-link]: https://wandbox.org/permlink/9eQyaD1DchlzukRv [releases-badge]: https://img.shields.io/github/release/CLIUtils/CLI11.svg [cli11-po-compare]: https://iscinumpy.gitlab.io/post/comparing-cli11-and-boostpo/ diff --git a/contrib/CLI11/include/CLI/App.hpp b/contrib/CLI11/include/CLI/App.hpp index 979237f3b..5d7761608 100644 --- a/contrib/CLI11/include/CLI/App.hpp +++ b/contrib/CLI11/include/CLI/App.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // @@ -35,9 +35,9 @@ namespace CLI { // [CLI11:app_hpp:verbatim] #ifndef CLI11_PARSE -#define CLI11_PARSE(app, argc, argv) \ +#define CLI11_PARSE(app, ...) \ try { \ - (app).parse((argc), (argv)); \ + (app).parse(__VA_ARGS__); \ } catch(const CLI::ParseError &e) { \ return (app).exit(e); \ } @@ -150,6 +150,12 @@ class App { /// @name Help ///@{ + /// Usage to put after program/subcommand description in the help output INHERITABLE + std::string usage_{}; + + /// This is a function that generates a usage to put after program/subcommand description in help output + std::function usage_callback_{}; + /// Footer to put after all options in the help output INHERITABLE std::string footer_{}; @@ -284,6 +290,14 @@ class App { ///@} +#ifdef _WIN32 + /// When normalizing argv to UTF-8 on Windows, this is the storage for normalized args. + std::vector normalized_argv_{}; + + /// When normalizing argv to UTF-8 on Windows, this is the `char**` value returned to the user. + std::vector normalized_argv_view_{}; +#endif + /// Special private constructor for subcommand App(std::string app_description, std::string app_name, App *parent); @@ -303,6 +317,9 @@ class App { /// virtual destructor virtual ~App() = default; + /// Convert the contents of argv to UTF-8. Only does something on Windows, does nothing elsewhere. + CLI11_NODISCARD char **ensure_utf8(char **argv); + /// Set a callback for execution when all parsing and processing has completed /// /// Due to a bug in c++11, @@ -834,12 +851,18 @@ class App { /// Parses the command line - throws errors. /// This must be called after the options are in but before the rest of the program. void parse(int argc, const char *const *argv); + void parse(int argc, const wchar_t *const *argv); + + private: + template void parse_char_t(int argc, const CharT *const *argv); + public: /// Parse a single string as if it contained command line arguments. /// This function splits the string into arguments then calls parse(std::vector &) /// the function takes an optional boolean argument specifying if the programName is included in the string to /// process void parse(std::string commandline, bool program_name_included = false); + void parse(std::wstring commandline, bool program_name_included = false); /// The real work is done here. Expects a reversed vector. /// Changes the vector to the remaining options. @@ -947,6 +970,16 @@ class App { /// @name Help ///@{ + /// Set usage. + App *usage(std::string usage_string) { + usage_ = std::move(usage_string); + return this; + } + /// Set usage. + App *usage(std::function usage_function) { + usage_callback_ = std::move(usage_function); + return this; + } /// Set footer. App *footer(std::string footer_string) { footer_ = std::move(footer_string); @@ -1055,6 +1088,11 @@ class App { /// Get the group of this subcommand CLI11_NODISCARD const std::string &get_group() const { return group_; } + /// Generate and return the usage. + CLI11_NODISCARD std::string get_usage() const { + return (usage_callback_) ? usage_callback_() + '\n' + usage_ : usage_; + } + /// Generate and return the footer. CLI11_NODISCARD std::string get_footer() const { return (footer_callback_) ? footer_callback_() + '\n' + footer_ : footer_; @@ -1192,6 +1230,9 @@ class App { /// Read and process a configuration file (main app only) void _process_config_file(); + /// Read and process a particular configuration file + bool _process_config_file(const std::string &config_file, bool throw_error); + /// Get envname options if not yet passed. Runs on *all* subcommands. void _process_env(); @@ -1264,8 +1305,9 @@ class App { bool _parse_subcommand(std::vector &args); /// Parse a short (false) or long (true) argument, must be at the top of the list + /// if local_processing_only is set to true then fallthrough is disabled will return false if not found /// return true if the argument was processed or false if nothing was done - bool _parse_arg(std::vector &args, detail::Classifier current_type); + bool _parse_arg(std::vector &args, detail::Classifier current_type, bool local_processing_only); /// Trigger the pre_parse callback if needed void _trigger_pre_parse(std::size_t remaining_args); diff --git a/contrib/CLI11/include/CLI/Argv.hpp b/contrib/CLI11/include/CLI/Argv.hpp new file mode 100644 index 000000000..619a7abf9 --- /dev/null +++ b/contrib/CLI11/include/CLI/Argv.hpp @@ -0,0 +1,29 @@ +// Copyright (c) 2017-2024, 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 + +#pragma once + +// [CLI11:public_includes:set] +#include +#include +// [CLI11:public_includes:end] + +#include + +namespace CLI { +// [CLI11:argv_hpp:verbatim] +namespace detail { +#ifdef _WIN32 +/// Decode and return UTF-8 argv from GetCommandLineW. +CLI11_INLINE std::vector compute_win32_argv(); +#endif +} // namespace detail +// [CLI11:argv_hpp:end] +} // namespace CLI + +#ifndef CLI11_COMPILE +#include "impl/Argv_inl.hpp" +#endif diff --git a/contrib/CLI11/include/CLI/CLI.hpp b/contrib/CLI11/include/CLI/CLI.hpp index ae4fc604d..df401e003 100644 --- a/contrib/CLI11/include/CLI/CLI.hpp +++ b/contrib/CLI11/include/CLI/CLI.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // @@ -13,6 +13,10 @@ #include "Macros.hpp" +#include "Encoding.hpp" + +#include "Argv.hpp" + #include "StringTools.hpp" #include "Error.hpp" diff --git a/contrib/CLI11/include/CLI/Config.hpp b/contrib/CLI11/include/CLI/Config.hpp index 8dfcddd95..942c43f40 100644 --- a/contrib/CLI11/include/CLI/Config.hpp +++ b/contrib/CLI11/include/CLI/Config.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // @@ -14,7 +14,7 @@ #include #include #include -// [CLI11:public_includes:set] +// [CLI11:public_includes:end] #include "App.hpp" #include "ConfigFwd.hpp" @@ -24,7 +24,10 @@ namespace CLI { // [CLI11:config_hpp:verbatim] namespace detail { -std::string convert_arg_for_ini(const std::string &arg, char stringQuote = '"', char characterQuote = '\''); +std::string convert_arg_for_ini(const std::string &arg, + char stringQuote = '"', + char literalQuote = '\'', + bool disable_multi_line = false); /// Comma separated join, adds quotes if needed std::string ini_join(const std::vector &args, @@ -32,7 +35,9 @@ std::string ini_join(const std::vector &args, char arrayStart = '[', char arrayEnd = ']', char stringQuote = '"', - char characterQuote = '\''); + char literalQuote = '\''); + +void clean_name_string(std::string &name, const std::string &keyChars); std::vector generate_parents(const std::string §ion, std::string &name, char parentSeparator); diff --git a/contrib/CLI11/include/CLI/ConfigFwd.hpp b/contrib/CLI11/include/CLI/ConfigFwd.hpp index a9ae2176a..fabf84dce 100644 --- a/contrib/CLI11/include/CLI/ConfigFwd.hpp +++ b/contrib/CLI11/include/CLI/ConfigFwd.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // @@ -10,6 +10,7 @@ #include #include #include +#include #include #include // [CLI11:public_includes:end] @@ -29,7 +30,6 @@ struct ConfigItem { /// This is the name std::string name{}; - /// Listing of inputs std::vector inputs{}; @@ -92,8 +92,8 @@ class ConfigBase : public Config { char valueDelimiter = '='; /// the character to use around strings char stringQuote = '"'; - /// the character to use around single characters - char characterQuote = '\''; + /// the character to use around single characters and literal strings + char literalQuote = '\''; /// the maximum number of layers to allow uint8_t maximumLayers{255}; /// the separator used to separator parent layers @@ -129,10 +129,10 @@ class ConfigBase : public Config { valueDelimiter = vSep; return this; } - /// Specify the quote characters used around strings and characters - ConfigBase *quoteCharacter(char qString, char qChar) { + /// Specify the quote characters used around strings and literal strings + ConfigBase *quoteCharacter(char qString, char literalChar) { stringQuote = qString; - characterQuote = qChar; + literalQuote = literalChar; return this; } /// Specify the maximum number of parents diff --git a/contrib/CLI11/include/CLI/Encoding.hpp b/contrib/CLI11/include/CLI/Encoding.hpp new file mode 100644 index 000000000..d723878f3 --- /dev/null +++ b/contrib/CLI11/include/CLI/Encoding.hpp @@ -0,0 +1,54 @@ +// Copyright (c) 2017-2024, 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 + +#pragma once + +#include + +// [CLI11:public_includes:set] +#include +// [CLI11:public_includes:end] + +// [CLI11:encoding_includes:verbatim] +#ifdef CLI11_CPP17 +#include +#endif // CLI11_CPP17 + +#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0 +#include +#include // NOLINT(build/include) +#endif // CLI11_HAS_FILESYSTEM +// [CLI11:encoding_includes:end] + +namespace CLI { +// [CLI11:encoding_hpp:verbatim] + +/// Convert a wide string to a narrow string. +CLI11_INLINE std::string narrow(const std::wstring &str); +CLI11_INLINE std::string narrow(const wchar_t *str); +CLI11_INLINE std::string narrow(const wchar_t *str, std::size_t size); + +/// Convert a narrow string to a wide string. +CLI11_INLINE std::wstring widen(const std::string &str); +CLI11_INLINE std::wstring widen(const char *str); +CLI11_INLINE std::wstring widen(const char *str, std::size_t size); + +#ifdef CLI11_CPP17 +CLI11_INLINE std::string narrow(std::wstring_view str); +CLI11_INLINE std::wstring widen(std::string_view str); +#endif // CLI11_CPP17 + +#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0 +/// Convert a char-string to a native path correctly. +CLI11_INLINE std::filesystem::path to_path(std::string_view str); +#endif // CLI11_HAS_FILESYSTEM + +// [CLI11:encoding_hpp:end] +} // namespace CLI + +#ifndef CLI11_COMPILE +#include "impl/Encoding_inl.hpp" +#endif diff --git a/contrib/CLI11/include/CLI/Error.hpp b/contrib/CLI11/include/CLI/Error.hpp index 0900da53c..2d6f673e9 100644 --- a/contrib/CLI11/include/CLI/Error.hpp +++ b/contrib/CLI11/include/CLI/Error.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // @@ -123,7 +123,13 @@ 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 BadPositionalName(std::string name) { + return BadNameString("Invalid positional Name: " + name); + } static BadNameString DashesOnly(std::string name) { return BadNameString("Must have a name, not just dashes: " + name); } diff --git a/contrib/CLI11/include/CLI/Formatter.hpp b/contrib/CLI11/include/CLI/Formatter.hpp index f58058f27..bc54caf55 100644 --- a/contrib/CLI11/include/CLI/Formatter.hpp +++ b/contrib/CLI11/include/CLI/Formatter.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // diff --git a/contrib/CLI11/include/CLI/FormatterFwd.hpp b/contrib/CLI11/include/CLI/FormatterFwd.hpp index 5ef0a5b58..a0949b49d 100644 --- a/contrib/CLI11/include/CLI/FormatterFwd.hpp +++ b/contrib/CLI11/include/CLI/FormatterFwd.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // diff --git a/contrib/CLI11/include/CLI/Macros.hpp b/contrib/CLI11/include/CLI/Macros.hpp index e85439030..3fd26475e 100644 --- a/contrib/CLI11/include/CLI/Macros.hpp +++ b/contrib/CLI11/include/CLI/Macros.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // @@ -66,6 +66,62 @@ #endif #endif +/** availability */ +#if defined CLI11_CPP17 && defined __has_include && !defined CLI11_HAS_FILESYSTEM +#if __has_include() +// Filesystem cannot be used if targeting macOS < 10.15 +#if defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 +#define CLI11_HAS_FILESYSTEM 0 +#elif defined(__wasi__) +// As of wasi-sdk-14, filesystem is not implemented +#define CLI11_HAS_FILESYSTEM 0 +#else +#include +#if defined __cpp_lib_filesystem && __cpp_lib_filesystem >= 201703 +#if defined _GLIBCXX_RELEASE && _GLIBCXX_RELEASE >= 9 +#define CLI11_HAS_FILESYSTEM 1 +#elif defined(__GLIBCXX__) +// if we are using gcc and Version <9 default to no filesystem +#define CLI11_HAS_FILESYSTEM 0 +#else +#define CLI11_HAS_FILESYSTEM 1 +#endif +#else +#define CLI11_HAS_FILESYSTEM 0 +#endif +#endif +#endif +#endif + +/** availability */ +#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER) && __GNUC__ < 5 +#define CLI11_HAS_CODECVT 0 +#else +#define CLI11_HAS_CODECVT 1 +#include +#endif + +/** disable deprecations */ +#if defined(__GNUC__) // GCC or clang +#define CLI11_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") +#define CLI11_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") + +#define CLI11_DIAGNOSTIC_IGNORE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + +#elif defined(_MSC_VER) +#define CLI11_DIAGNOSTIC_PUSH __pragma(warning(push)) +#define CLI11_DIAGNOSTIC_POP __pragma(warning(pop)) + +#define CLI11_DIAGNOSTIC_IGNORE_DEPRECATED __pragma(warning(disable : 4996)) + +#else +#define CLI11_DIAGNOSTIC_PUSH +#define CLI11_DIAGNOSTIC_POP + +#define CLI11_DIAGNOSTIC_IGNORE_DEPRECATED + +#endif + /** Inline macro **/ #ifdef CLI11_COMPILE #define CLI11_INLINE diff --git a/contrib/CLI11/include/CLI/Option.hpp b/contrib/CLI11/include/CLI/Option.hpp index d32350738..a0fa7ceac 100644 --- a/contrib/CLI11/include/CLI/Option.hpp +++ b/contrib/CLI11/include/CLI/Option.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner +// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner // under NSF AWARD 1414736 and by the respective contributors. // All rights reserved. // @@ -41,7 +41,8 @@ enum class MultiOptionPolicy : char { TakeFirst, //!< take only the first Expected number of arguments Join, //!< merge all the arguments together into a single string via the delimiter character default('\n') TakeAll, //!< just get all the passed argument regardless - Sum //!< sum all the arguments together if numerical or concatenate directly without delimiter + Sum, //!< sum all the arguments together if numerical or concatenate directly without delimiter + Reverse, //!< take only the last Expected number of arguments in reverse order }; /// This is the CRTP base class for Option and OptionDefaults. It was designed this way @@ -549,12 +550,12 @@ class Option : public OptionBase