mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-04 07:04:39 +00:00
Merge pull request #264 from skrobinson/feat-exit-choice
Add exit_on_default_arguments parameter to ArgumentParser
This commit is contained in:
commit
0b513829ac
22
README.md
22
README.md
@ -68,7 +68,7 @@ argparse::ArgumentParser program("program_name");
|
|||||||
|
|
||||||
**NOTE:** There is an optional second argument to the `ArgumentParser` which is the program version. Example: `argparse::ArgumentParser program("libfoo", "1.9.0");`
|
**NOTE:** There is an optional second argument to the `ArgumentParser` which is the program version. Example: `argparse::ArgumentParser program("libfoo", "1.9.0");`
|
||||||
|
|
||||||
**NOTE:** There is an optional third argument to the `ArgumentParser` which controls default arguments. Example: `argparse::ArgumentParser program("libfoo", "1.9.0", default_arguments::none);` See [Default Arguments](#default-arguments), below.
|
**NOTE:** There are optional third and fourth arguments to the `ArgumentParser` which control default arguments. Example: `argparse::ArgumentParser program("libfoo", "1.9.0", default_arguments::help, false);` See [Default Arguments](#default-arguments), below.
|
||||||
|
|
||||||
To add a new argument, simply call ```.add_argument(...)```. You can provide a variadic list of argument names that you want to group together, e.g., ```-v``` and ```--verbose```
|
To add a new argument, simply call ```.add_argument(...)```. You can provide a variadic list of argument names that you want to group together, e.g., ```-v``` and ```--verbose```
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ int main(int argc, char *argv[]) {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto input = program.get<int>("square");
|
auto input = program.get<int>("square");
|
||||||
@ -559,7 +559,9 @@ The grammar follows `std::from_chars`, but does not exactly duplicate it. For ex
|
|||||||
|
|
||||||
### Default Arguments
|
### Default Arguments
|
||||||
|
|
||||||
`argparse` provides predefined arguments and actions for `-h`/`--help` and `-v`/`--version`. These default actions **exit** the program after displaying a help or version message, respectively. These defaults arguments can be disabled during `ArgumentParser` creation so that you can handle these arguments in your own way. (Note that a program name and version must be included when choosing default arguments.)
|
`argparse` provides predefined arguments and actions for `-h`/`--help` and `-v`/`--version`. By default, these actions will **exit** the program after displaying a help or version message, respectively. This exit does not call destructors, skipping clean-up of taken resources.
|
||||||
|
|
||||||
|
These default arguments can be disabled during `ArgumentParser` creation so that you can handle these arguments in your own way. (Note that a program name and version must be included when choosing default arguments.)
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
argparse::ArgumentParser program("test", "1.0", default_arguments::none);
|
argparse::ArgumentParser program("test", "1.0", default_arguments::none);
|
||||||
@ -578,6 +580,12 @@ The above code snippet outputs a help message and continues to run. It does not
|
|||||||
|
|
||||||
The default is `default_arguments::all` for included arguments. No default arguments will be added with `default_arguments::none`. `default_arguments::help` and `default_arguments::version` will individually add `--help` and `--version`.
|
The default is `default_arguments::all` for included arguments. No default arguments will be added with `default_arguments::none`. `default_arguments::help` and `default_arguments::version` will individually add `--help` and `--version`.
|
||||||
|
|
||||||
|
The default arguments can be used while disabling the default exit with these arguments. This forth argument to `ArgumentParser` (`exit_on_default_arguments`) is a bool flag with a default **true** value. The following call will retain `--help` and `--version`, but will not exit when those arguments are used.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
argparse::ArgumentParser program("test", "1.0", default_arguments::all, false)
|
||||||
|
```
|
||||||
|
|
||||||
### Gathering Remaining Arguments
|
### Gathering Remaining Arguments
|
||||||
|
|
||||||
`argparse` supports gathering "remaining" arguments at the end of the command, e.g., for use in a compiler:
|
`argparse` supports gathering "remaining" arguments at the end of the command, e.g., for use in a compiler:
|
||||||
@ -773,7 +781,7 @@ int main(int argc, char *argv[]) {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use arguments
|
// Use arguments
|
||||||
@ -900,7 +908,7 @@ int main(int argc, char *argv[]) {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.is_used("+f")) {
|
if (program.is_used("+f")) {
|
||||||
@ -948,7 +956,7 @@ int main(int argc, char *argv[]) {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.is_used("--foo")) {
|
if (program.is_used("--foo")) {
|
||||||
@ -1096,7 +1104,7 @@ int main(int argc, char *argv[]) {
|
|||||||
catch (const std::runtime_error& err) {
|
catch (const std::runtime_error& err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.is_used("--foo")) {
|
if (program.is_used("--foo")) {
|
||||||
|
@ -1052,14 +1052,18 @@ class ArgumentParser {
|
|||||||
public:
|
public:
|
||||||
explicit ArgumentParser(std::string program_name = {},
|
explicit ArgumentParser(std::string program_name = {},
|
||||||
std::string version = "1.0",
|
std::string version = "1.0",
|
||||||
default_arguments add_args = default_arguments::all)
|
default_arguments add_args = default_arguments::all,
|
||||||
|
bool exit_on_default_arguments = true)
|
||||||
: m_program_name(std::move(program_name)), m_version(std::move(version)),
|
: m_program_name(std::move(program_name)), m_version(std::move(version)),
|
||||||
|
m_exit_on_default_arguments(exit_on_default_arguments),
|
||||||
m_parser_path(m_program_name) {
|
m_parser_path(m_program_name) {
|
||||||
if ((add_args & default_arguments::help) == default_arguments::help) {
|
if ((add_args & default_arguments::help) == default_arguments::help) {
|
||||||
add_argument("-h", "--help")
|
add_argument("-h", "--help")
|
||||||
.action([&](const auto & /*unused*/) {
|
.action([&](const auto & /*unused*/) {
|
||||||
std::cout << help().str();
|
std::cout << help().str();
|
||||||
std::exit(0);
|
if (m_exit_on_default_arguments) {
|
||||||
|
std::exit(0);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.default_value(false)
|
.default_value(false)
|
||||||
.help("shows help message and exits")
|
.help("shows help message and exits")
|
||||||
@ -1070,7 +1074,9 @@ public:
|
|||||||
add_argument("-v", "--version")
|
add_argument("-v", "--version")
|
||||||
.action([&](const auto & /*unused*/) {
|
.action([&](const auto & /*unused*/) {
|
||||||
std::cout << m_version << std::endl;
|
std::cout << m_version << std::endl;
|
||||||
std::exit(0);
|
if (m_exit_on_default_arguments) {
|
||||||
|
std::exit(0);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.default_value(false)
|
.default_value(false)
|
||||||
.help("prints version information and exits")
|
.help("prints version information and exits")
|
||||||
@ -1676,6 +1682,7 @@ private:
|
|||||||
std::string m_version;
|
std::string m_version;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
std::string m_epilog;
|
std::string m_epilog;
|
||||||
|
bool m_exit_on_default_arguments = true;
|
||||||
std::string m_prefix_chars{"-"};
|
std::string m_prefix_chars{"-"};
|
||||||
std::string m_assign_chars{"="};
|
std::string m_assign_chars{"="};
|
||||||
bool m_is_parsed = false;
|
bool m_is_parsed = false;
|
||||||
|
@ -19,7 +19,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto a = program.get<bool>("-a"); // true
|
auto a = program.get<bool>("-a"); // true
|
||||||
|
@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.is_used("--foo")) {
|
if (program.is_used("--foo")) {
|
||||||
|
@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.is_used("+f")) {
|
if (program.is_used("+f")) {
|
||||||
|
@ -12,7 +12,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto color = program.get<std::string>("--color"); // "orange"
|
auto color = program.get<std::string>("--color"); // "orange"
|
||||||
|
@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto colors = program.get<std::vector<std::string>>(
|
auto colors = program.get<std::vector<std::string>>(
|
||||||
|
@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto files = program.get<std::vector<std::string>>(
|
auto files = program.get<std::vector<std::string>>(
|
||||||
|
@ -17,7 +17,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.is_used("integer")) {
|
if (program.is_used("integer")) {
|
||||||
|
@ -15,7 +15,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program["--verbose"] == true) {
|
if (program["--verbose"] == true) {
|
||||||
|
@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int input = program.get<int>("square");
|
int input = program.get<int>("square");
|
||||||
|
@ -14,7 +14,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Output written to " << program.get("-o") << "\n";
|
std::cout << "Output written to " << program.get("-o") << "\n";
|
||||||
|
@ -60,7 +60,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} catch (const std::runtime_error &err) {
|
} catch (const std::runtime_error &err) {
|
||||||
std::cerr << err.what() << std::endl;
|
std::cerr << err.what() << std::endl;
|
||||||
std::cerr << program;
|
std::cerr << program;
|
||||||
std::exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use arguments
|
// Use arguments
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include <argparse/argparse.hpp>
|
#include <argparse/argparse.hpp>
|
||||||
#include <doctest.hpp>
|
#include <doctest.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
#include <streambuf>
|
||||||
|
|
||||||
using doctest::test_suite;
|
using doctest::test_suite;
|
||||||
|
|
||||||
@ -17,3 +19,13 @@ TEST_CASE("Do not include default arguments" * test_suite("default_args")) {
|
|||||||
REQUIRE_THROWS_AS(parser.get("--help"), std::logic_error);
|
REQUIRE_THROWS_AS(parser.get("--help"), std::logic_error);
|
||||||
REQUIRE_THROWS_AS(parser.get("--version"), std::logic_error);
|
REQUIRE_THROWS_AS(parser.get("--version"), std::logic_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Do not exit on default arguments" * test_suite("default_args")) {
|
||||||
|
argparse::ArgumentParser parser("test", "1.0",
|
||||||
|
argparse::default_arguments::all, false);
|
||||||
|
std::stringstream buf;
|
||||||
|
std::streambuf* saved_cout_buf = std::cout.rdbuf(buf.rdbuf());
|
||||||
|
parser.parse_args({"test", "--help"});
|
||||||
|
std::cout.rdbuf(saved_cout_buf);
|
||||||
|
REQUIRE(parser.is_used("--help"));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user