From f0f5191121381e632b5fc27cae4c8cf2abd3c73c Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Thu, 6 Feb 2025 23:26:48 +0100 Subject: [PATCH 1/3] Update tutorial --- tutorial/CMakeLists.txt | 1 + tutorial/nohandling2.cpp | 14 +++++++++++++ tutorial/readme.md | 44 +++++++++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 tutorial/nohandling2.cpp diff --git a/tutorial/CMakeLists.txt b/tutorial/CMakeLists.txt index 943f1c51..b32ea36a 100644 --- a/tutorial/CMakeLists.txt +++ b/tutorial/CMakeLists.txt @@ -20,6 +20,7 @@ set(targets undesired nohandling nohandling1 + nohandling2 custom custom1 custom2 diff --git a/tutorial/nohandling2.cpp b/tutorial/nohandling2.cpp new file mode 100644 index 00000000..17aa947b --- /dev/null +++ b/tutorial/nohandling2.cpp @@ -0,0 +1,14 @@ +#include "argparse.h" +#include + +int main(int argc, char * argv[]) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::errors_and_help); + parser.add_argument("--version").action(argparse::version); + auto parsed = parser.parse_args(argc, argv); + if (parsed.get_value("version")) + { + std::cout << "This is program version 1.0.0\n"; + } + return 0; +} diff --git a/tutorial/readme.md b/tutorial/readme.md index 7dfacd27..25dcaeec 100644 --- a/tutorial/readme.md +++ b/tutorial/readme.md @@ -966,7 +966,7 @@ optional arguments: -h, --help show this help message and exit ``` -### Help and error handling +### Help, version, and error handling As you have noticed, the parser automatically adds the `-h/--help` optional argument and handles help requests and parsing errors. There are some cases, when this may be undesirable. @@ -986,7 +986,7 @@ $ nohelp --help unrecognised arguments: --help usage: nohelp ``` -The automatic help and error handling consists of printing a relevant message and exiting the program by a call to `std::exit`. The reason this may be undesirable is that `std::exit` does not ensure cleanup of local variables (`undesired.cpp`): +The automatic help, version, and error handling consists of printing a relevant message and exiting the program by a call to `std::exit`. The reason this may be undesirable is that `std::exit` does not ensure cleanup of local variables (`undesired.cpp`): ```c++ #include "argparse.h" #include @@ -1031,7 +1031,7 @@ usage: undesired [-h] optional arguments: -h, --help show this help message and exit ``` -To improve this situation, you may tell the logger not to handle help and errors (`nohandling.cpp`): +To improve this situation, you may tell the logger not to handle help, version, and errors (`nohandling.cpp`): ```c++ #include "argparse.h" #include @@ -1057,7 +1057,7 @@ int main(int argc, char * argv[]) parser.parse_args(argc, argv); } ``` -In such a case, you'll most likely want to handle help requests yourself. Also, you will now **need** to handle errors, otherwise you will encounter unhandled exceptions. Let's extend the program (`nohandling1.cpp`): +In such a case, you'll most likely want to handle help and version requests yourself. Also, you will now **need** to handle errors, otherwise you will encounter unhandled exceptions. Let's extend the program (`nohandling1.cpp`): ```c++ #include "argparse.h" #include @@ -1113,13 +1113,47 @@ Log started unrecognised arguments: foo Log ended ``` +The following example illustrates handling version requests (`nohandling2.cpp`): +```c++ +#include "argparse.h" +#include + +int main(int argc, char * argv[]) +{ + auto parser = argparse::ArgumentParser().handle(argparse::Handle::errors_and_help); + parser.add_argument("--version").action(argparse::version); + auto parsed = parser.parse_args(argc, argv); + if (parsed.get_value("version")) + { + std::cout << "This is program version 1.0.0\n"; + } + return 0; +} +``` +Its automatically generated help message looks like this: +``` +$ nohandling2 --help +usage: nohandling2 [-h] [--version] + +optional arguments: + -h, --help show this help message and exit + --version show program's version number and exit +``` +Let's see how it prints version: +``` +$ nohandling2 --version +This is program version 1.0.0 +``` + Some things to note here: * You can use parser's `format_help` and `format_usage` functions to generate the messages for you. * In case of error, parser throws an exception of type `argparse::parsing_error` (or type derived from it), which derives from `std::runtime_error`. * The control is more granular; you can tell the parser to handle: * only help (`argparse::Handle::help`), + * only version (`argparse::Handle::version`), * only errors (`argparse::Handle::errors`), - * both help and errors (`argparse::Handle::errors_and_help`), which is the default. + * both help and errors (`argparse::Handle::errors_and_help`), + * help, version, and errors (`argparse::Handle::errors_help_version`) which is the default. ## Conclusion From 4a8e128e50b6ff809464815242b012caa875126a Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Thu, 6 Feb 2025 23:35:23 +0100 Subject: [PATCH 2/3] Update tutorial --- tutorial/CMakeLists.txt | 1 + tutorial/readme.md | 16 ++++++++++++++++ tutorial/version.cpp | 8 ++++++++ 3 files changed, 25 insertions(+) create mode 100644 tutorial/version.cpp diff --git a/tutorial/CMakeLists.txt b/tutorial/CMakeLists.txt index b32ea36a..1fafbfb1 100644 --- a/tutorial/CMakeLists.txt +++ b/tutorial/CMakeLists.txt @@ -21,6 +21,7 @@ set(targets nohandling nohandling1 nohandling2 + version custom custom1 custom2 diff --git a/tutorial/readme.md b/tutorial/readme.md index 25dcaeec..731079e7 100644 --- a/tutorial/readme.md +++ b/tutorial/readme.md @@ -1144,6 +1144,22 @@ Let's see how it prints version: $ nohandling2 --version This is program version 1.0.0 ``` +Of course, handling version requests can be fully automatic (`version.cpp`): +```c++ +#include "argparse.h" + +int main(int argc, char * argv[]) +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("--version").action(argparse::version).version("1.0.0-rc1"); + parser.parse_args(argc, argv); +} +``` +Let's see how it works: +``` +$ version --version +1.0.0-rc1 +``` Some things to note here: * You can use parser's `format_help` and `format_usage` functions to generate the messages for you. diff --git a/tutorial/version.cpp b/tutorial/version.cpp new file mode 100644 index 00000000..e8ff31d1 --- /dev/null +++ b/tutorial/version.cpp @@ -0,0 +1,8 @@ +#include "argparse.h" + +int main(int argc, char * argv[]) +{ + auto parser = argparse::ArgumentParser(); + parser.add_argument("--version").action(argparse::version).version("1.0.0-rc1"); + parser.parse_args(argc, argv); +} From 17ab5420c078e4d09bf688fad1dfbb3b1765b6d8 Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Thu, 6 Feb 2025 23:39:48 +0100 Subject: [PATCH 3/3] Use trailing function return type --- tutorial/nohandling2.cpp | 2 +- tutorial/version.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorial/nohandling2.cpp b/tutorial/nohandling2.cpp index 17aa947b..3f07cac8 100644 --- a/tutorial/nohandling2.cpp +++ b/tutorial/nohandling2.cpp @@ -1,7 +1,7 @@ #include "argparse.h" #include -int main(int argc, char * argv[]) +auto main(int argc, char * argv[]) -> int { auto parser = argparse::ArgumentParser().handle(argparse::Handle::errors_and_help); parser.add_argument("--version").action(argparse::version); diff --git a/tutorial/version.cpp b/tutorial/version.cpp index e8ff31d1..f5c71473 100644 --- a/tutorial/version.cpp +++ b/tutorial/version.cpp @@ -1,6 +1,6 @@ #include "argparse.h" -int main(int argc, char * argv[]) +auto main(int argc, char * argv[]) -> int { auto parser = argparse::ArgumentParser(); parser.add_argument("--version").action(argparse::version).version("1.0.0-rc1");