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