Support 'const char**' arguments in Options::parse (#250)
`cxxopts` doesn't modify the contents of the argv strings. This changes the parse function to take a reference to a `const char**`.
This commit is contained in:
parent
07f5cb24f1
commit
15e8a74e95
@ -12,6 +12,7 @@ options. The project adheres to semantic versioning.
|
||||
* Fix duplicate default options when there is a short and long option.
|
||||
* Add `CXXOPTS_NO_EXCEPTIONS` to disable exceptions.
|
||||
* Fix char parsing for space and check for length.
|
||||
* Change argument type in `Options::parse` from `char**` to `const char**`.
|
||||
|
||||
## 2.2
|
||||
|
||||
|
@ -1211,7 +1211,7 @@ namespace cxxopts
|
||||
>,
|
||||
std::vector<std::string>,
|
||||
bool allow_unrecognised,
|
||||
int&, char**&);
|
||||
int&, const char**&);
|
||||
|
||||
size_t
|
||||
count(const std::string& o) const
|
||||
@ -1251,7 +1251,7 @@ namespace cxxopts
|
||||
private:
|
||||
|
||||
void
|
||||
parse(int& argc, char**& argv);
|
||||
parse(int& argc, const char**& argv);
|
||||
|
||||
void
|
||||
add_to_option(const std::string& option, const std::string& arg);
|
||||
@ -1274,7 +1274,7 @@ namespace cxxopts
|
||||
checked_parse_arg
|
||||
(
|
||||
int argc,
|
||||
char* argv[],
|
||||
const char* argv[],
|
||||
int& current,
|
||||
const std::shared_ptr<OptionDetails>& value,
|
||||
const std::string& name
|
||||
@ -1361,7 +1361,7 @@ namespace cxxopts
|
||||
}
|
||||
|
||||
ParseResult
|
||||
parse(int& argc, char**& argv);
|
||||
parse(int& argc, const char**& argv);
|
||||
|
||||
OptionAdder
|
||||
add_options(std::string group = "");
|
||||
@ -1620,7 +1620,7 @@ ParseResult::ParseResult
|
||||
> options,
|
||||
std::vector<std::string> positional,
|
||||
bool allow_unrecognised,
|
||||
int& argc, char**& argv
|
||||
int& argc, const char**& argv
|
||||
)
|
||||
: m_options(std::move(options))
|
||||
, m_positional(std::move(positional))
|
||||
@ -1734,7 +1734,7 @@ void
|
||||
ParseResult::checked_parse_arg
|
||||
(
|
||||
int argc,
|
||||
char* argv[],
|
||||
const char* argv[],
|
||||
int& current,
|
||||
const std::shared_ptr<OptionDetails>& value,
|
||||
const std::string& name
|
||||
@ -1835,7 +1835,7 @@ Options::parse_positional(std::initializer_list<std::string> options)
|
||||
|
||||
inline
|
||||
ParseResult
|
||||
Options::parse(int& argc, char**& argv)
|
||||
Options::parse(int& argc, const char**& argv)
|
||||
{
|
||||
ParseResult result(m_options, m_positional, m_allow_unrecognised, argc, argv);
|
||||
return result;
|
||||
@ -1843,7 +1843,7 @@ Options::parse(int& argc, char**& argv)
|
||||
|
||||
inline
|
||||
void
|
||||
ParseResult::parse(int& argc, char**& argv)
|
||||
ParseResult::parse(int& argc, const char**& argv)
|
||||
{
|
||||
int current = 1;
|
||||
|
||||
|
@ -27,7 +27,7 @@ THE SOFTWARE.
|
||||
#include "cxxopts.hpp"
|
||||
|
||||
void
|
||||
parse(int argc, char* argv[])
|
||||
parse(int argc, const char* argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -160,7 +160,7 @@ parse(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
parse(argc, argv);
|
||||
|
||||
|
@ -8,7 +8,7 @@ class Argv {
|
||||
public:
|
||||
|
||||
Argv(std::initializer_list<const char*> args)
|
||||
: m_argv(new char*[args.size()])
|
||||
: m_argv(new const char*[args.size()])
|
||||
, m_argc(static_cast<int>(args.size()))
|
||||
{
|
||||
int i = 0;
|
||||
@ -26,7 +26,7 @@ class Argv {
|
||||
}
|
||||
}
|
||||
|
||||
char** argv() const {
|
||||
const char** argv() const {
|
||||
return m_argv.get();
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ class Argv {
|
||||
private:
|
||||
|
||||
std::vector<std::unique_ptr<char[]>> m_args;
|
||||
std::unique_ptr<char*[]> m_argv;
|
||||
std::unique_ptr<const char*[]> m_argv;
|
||||
int m_argc;
|
||||
};
|
||||
|
||||
@ -69,7 +69,7 @@ TEST_CASE("Basic options", "[options]")
|
||||
"--space",
|
||||
});
|
||||
|
||||
char** actual_argv = argv.argv();
|
||||
auto** actual_argv = argv.argv();
|
||||
auto argc = argv.argc();
|
||||
|
||||
auto result = options.parse(argc, actual_argv);
|
||||
@ -125,7 +125,7 @@ TEST_CASE("No positional", "[positional]")
|
||||
|
||||
Argv av({"tester", "a", "b", "def"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
auto result = options.parse(argc, argv);
|
||||
|
||||
@ -177,7 +177,7 @@ TEST_CASE("Some positional explicit", "[positional]")
|
||||
|
||||
Argv av({"tester", "--output", "a", "b", "c", "d"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -203,7 +203,7 @@ TEST_CASE("No positional with extras", "[positional]")
|
||||
|
||||
Argv av({"extras", "--", "a", "b", "c", "d"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto old_argv = argv;
|
||||
@ -226,7 +226,7 @@ TEST_CASE("Positional not valid", "[positional]") {
|
||||
|
||||
Argv av({"foobar", "bar", "baz"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception&);
|
||||
@ -241,7 +241,7 @@ TEST_CASE("Empty with implicit value", "[implicit]")
|
||||
|
||||
Argv av({"implicit", "--implicit="});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -260,7 +260,7 @@ TEST_CASE("Boolean without implicit value", "[implicit]")
|
||||
SECTION("When no value provided") {
|
||||
Argv av({"no_implicit", "--bool"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::missing_argument_exception&);
|
||||
@ -269,7 +269,7 @@ TEST_CASE("Boolean without implicit value", "[implicit]")
|
||||
SECTION("With equal-separated true") {
|
||||
Argv av({"no_implicit", "--bool=true"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -280,7 +280,7 @@ TEST_CASE("Boolean without implicit value", "[implicit]")
|
||||
SECTION("With equal-separated false") {
|
||||
Argv av({"no_implicit", "--bool=false"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -291,7 +291,7 @@ TEST_CASE("Boolean without implicit value", "[implicit]")
|
||||
SECTION("With space-separated true") {
|
||||
Argv av({"no_implicit", "--bool", "true"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -302,7 +302,7 @@ TEST_CASE("Boolean without implicit value", "[implicit]")
|
||||
SECTION("With space-separated false") {
|
||||
Argv av({"no_implicit", "--bool", "false"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -323,7 +323,7 @@ TEST_CASE("Default values", "[default]")
|
||||
SECTION("Sets defaults") {
|
||||
Argv av({"implicit"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -339,7 +339,7 @@ TEST_CASE("Default values", "[default]")
|
||||
SECTION("When values provided") {
|
||||
Argv av({"implicit", "--default", "5"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -374,7 +374,7 @@ TEST_CASE("Integers", "[options]")
|
||||
|
||||
Argv av({"ints", "--", "5", "6", "-6", "0", "0xab", "0xAf", "0x0"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
options.parse_positional("positional");
|
||||
@ -401,7 +401,7 @@ TEST_CASE("Leading zero integers", "[options]")
|
||||
|
||||
Argv av({"ints", "--", "05", "06", "0x0ab", "0x0001"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
options.parse_positional("positional");
|
||||
@ -425,7 +425,7 @@ TEST_CASE("Unsigned integers", "[options]")
|
||||
|
||||
Argv av({"ints", "--", "-2"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
options.parse_positional("positional");
|
||||
@ -504,7 +504,7 @@ TEST_CASE("Floats", "[options]")
|
||||
|
||||
Argv av({"floats", "--double", "0.5", "--", "4", "-4", "1.5e6", "-1.5e6"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
options.parse_positional("positional");
|
||||
@ -529,7 +529,7 @@ TEST_CASE("Invalid integers", "[integer]") {
|
||||
|
||||
Argv av({"ints", "--", "Ae"});
|
||||
|
||||
char **argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
options.parse_positional("positional");
|
||||
@ -554,7 +554,7 @@ TEST_CASE("Booleans", "[boolean]") {
|
||||
|
||||
Argv av({"booleans", "--bool=false", "--debug=true", "--timing", "--verbose=1", "--dry-run=0", "extra"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
auto result = options.parse(argc, argv);
|
||||
@ -588,7 +588,7 @@ TEST_CASE("std::vector", "[vector]") {
|
||||
|
||||
Argv av({"vector", "--vector", "1,-2.1,3,4.5"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
options.parse(argc, argv);
|
||||
@ -609,7 +609,7 @@ TEST_CASE("std::optional", "[optional]") {
|
||||
|
||||
Argv av({"optional", "--optional", "foo"});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
options.parse(argc, argv);
|
||||
@ -634,7 +634,7 @@ TEST_CASE("Unrecognised options", "[options]") {
|
||||
"--another_unknown",
|
||||
});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
SECTION("Default behaviour") {
|
||||
@ -661,7 +661,7 @@ TEST_CASE("Allow bad short syntax", "[options]") {
|
||||
"-some_bad_short",
|
||||
});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
SECTION("Default behaviour") {
|
||||
@ -684,7 +684,7 @@ TEST_CASE("Invalid option syntax", "[options]") {
|
||||
"--a",
|
||||
});
|
||||
|
||||
char** argv = av.argv();
|
||||
auto** argv = av.argv();
|
||||
auto argc = av.argc();
|
||||
|
||||
SECTION("Default behaviour") {
|
||||
@ -704,7 +704,7 @@ TEST_CASE("Options empty", "[options]") {
|
||||
"--unknown"
|
||||
});
|
||||
auto argc = argv_.argc();
|
||||
char** argv = argv_.argv();
|
||||
auto** argv = argv_.argv();
|
||||
|
||||
CHECK(options.groups().empty());
|
||||
CHECK_THROWS_AS(options.parse(argc, argv), cxxopts::option_not_exists_exception&);
|
||||
@ -733,7 +733,7 @@ TEST_CASE("Initializer list with group", "[options]") {
|
||||
"8000",
|
||||
"-t",
|
||||
});
|
||||
char** actual_argv = argv.argv();
|
||||
auto** actual_argv = argv.argv();
|
||||
auto argc = argv.argc();
|
||||
auto result = options.parse(argc, actual_argv);
|
||||
|
||||
@ -763,7 +763,7 @@ TEST_CASE("Option add with add_option(string, Option)", "[options]") {
|
||||
"4"
|
||||
});
|
||||
auto argc = argv_.argc();
|
||||
char** argv = argv_.argv();
|
||||
auto** argv = argv_.argv();
|
||||
auto result = options.parse(argc, argv);
|
||||
|
||||
CHECK(result.arguments().size()==2);
|
||||
|
Loading…
Reference in New Issue
Block a user