As the user did not include the argument, the longest name for the unused
argument is in the last position of mNames.
This is an API change that may affect programs trying to match the
specific "No value provided" message. The new error message appends the
argument that caused the error.
A solution which works with both versions is to look for "No value
provided" at the beginning of the error message.
- if (err.what() == "No value provided")
+ if (std:string(err.what()).rfind("No value provided", 0) == 0)
Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
These test the API shown in README.md, rather than the Argument::get
function that does most of the work.
Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
While it's good to test around error conditions, the main purpose of this
test is to catch future changes in the error type and message.
Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
This fills a tiny gap in the positional_arguments suite. Most existing
tests have positional arguments. The one case without an argument uses
Argument::remaining so that ArgumentParserArgument::parse_args does not
throw, instead ArgumentParser::get<> throws std::logic_error.
Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
This silences the following warning:
No project() command is present. The top-level CMakeLists.txt file must
contain a literal, direct call to the project() command. Add a line of
code such as
project(ProjectName)
near the top of the file, but after cmake_minimum_required().
CMake is pretending there is a "project(Project)" command on the first
line.
Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
Argument.scan handles simple string to numeric type conversions, removing
the need to create a lambda. Argument.action is still necessary for more
complex conversions and those are left unchanged.
Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
.present returns std::nullopt if the optional argument is not given by the
user -- as long as a .default_value is not defined. With a .default_value,
.present cannot be used to determine if a value is user-provided or the
default.
.is_used fills that role and only returns true if the argument was passed
by the user.
Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
The default behavior with optional arguments is to allow only a single use
per invocation. One alternative is to use .nargs, but this requires
previously knowing, and limiting, the quantity of values. The .append
method removes the restriction on repeats for a single Argument.
Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
Two differences that diverge from the existing behavior:
1. Leading zeros are not allowed for integers. Negative
octal numbers such as `-066` are not meant to be treated
as positional arguments, but existing code recognize them
as decimal numbers. Note that negative floating-point
numbers with leading zeros (`-003.`) are unambiguous and
are recognized.
2. Inf and NaN are not recognized. This is because options
like `-inf` is indistinguishable from a compound argument
that meant to be a shorthand for `-i -n -f`.
fixes: p-ranav/argparse#55
The change also fixes a rare bug introduced in 9007958:
when there are duplicated keys, insert_or_update overrides
previously inserted ones, emplace doesn't.
fixes: p-ranav/argparse#59
This change also explicitly lists the source files
for CMake. This is because `GLOB` does not remove
old files when switching branches in Git, and
`CONFIGURE_DEPENDS` will add unstaged files after
stashing.
See also: https://cmake.org/cmake/help/latest/command/file.html#glob
Before this change:
1. When the input is built-in string literal or cv-`char*`,
`is_optional` constructs temporary `std::string` while
`mNames` initializer is also constructing `std::string`
due to the use of `std::initializer_list`.
2. When the input is `std::string_view`, doesn't compile.
3. When the input is `std::string`, `mNames` initializer
moves `args`. If argument name is longer than
`std::string`'s SSO buffer, bad thing will happen because
`is_optional` will be accessing `args` in moved-from
states.
Because of the use of `strtol` which expects nul-terminated
input, `is_*` series functions must take `std::string`. This
restriction may be removed after AppleClang adds `<charconv>`.
But for now, it complicates the patch. My solution is to
create an array prvalue still, but use a array reference
rather than `std::initializer_list` to refer to it, so that
the code in delegated constructor can keep using fold
expressions after the necessary `std::string` objects being
created.