From cfdfc302dbd355495afc2b50bd0e6ca0ceea47af Mon Sep 17 00:00:00 2001 From: Martchus Date: Sun, 24 Mar 2019 21:52:10 +0100 Subject: [PATCH] Use exit function passed to argument parser --- application/argumentparser.cpp | 22 ++++++++++++++-------- application/argumentparser.h | 1 + tests/argumentparsertests.cpp | 10 ++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/application/argumentparser.cpp b/application/argumentparser.cpp index f25389d..efc2dff 100644 --- a/application/argumentparser.cpp +++ b/application/argumentparser.cpp @@ -416,12 +416,6 @@ std::vector dependencyVersions2; // TODO v5 use a struct for these properties -/*! - * \brief Specifies a function quit the application. - * \remarks Currently only used after printing Bash completion. Default is std::exit(). - */ -void (*exitFunction)(int) = &exit; - /// \cond inline bool notEmpty(const char *str) @@ -899,7 +893,7 @@ void ArgumentParser::parseArgsExt(int argc, const char *const *argv, ParseArgume if (behavior & ParseArgumentBehavior::ExitOnFailure) { CMD_UTILS_START_CONSOLE; cerr << failure; - exit(1); + invokeExit(1); } throw; } @@ -973,7 +967,7 @@ void ArgumentParser::readArgs(int argc, const char *const *argv) // print Bash completion and prevent the applicaton to continue with the regular execution if (completionMode) { printBashCompletion(argc, argv, currentWordIndex, reader); - exitFunction(0); + invokeExit(0); } } @@ -1609,6 +1603,18 @@ void ArgumentParser::invokeCallbacks(const ArgumentVector &args) } } +/*! + * \brief Exits using the assigned function or std::exit(). + */ +void ArgumentParser::invokeExit(int code) +{ + if (m_exitFunction) { + m_exitFunction(code); + return; + } + std::exit(code); +} + /*! * \class HelpArgument * \brief The HelpArgument class prints help information for an argument parser diff --git a/application/argumentparser.h b/application/argumentparser.h index 2eb54ab..f412b3d 100644 --- a/application/argumentparser.h +++ b/application/argumentparser.h @@ -478,6 +478,7 @@ private: void printBashCompletion(int argc, const char *const *argv, unsigned int cursorPos, const ArgumentReader &reader) const; void checkConstraints(const ArgumentVector &args); static void invokeCallbacks(const ArgumentVector &args); + void invokeExit(int code); ArgumentVector m_mainArgs; unsigned int m_actualArgc; diff --git a/tests/argumentparsertests.cpp b/tests/argumentparsertests.cpp index 3c23de2..1f50fbd 100644 --- a/tests/argumentparsertests.cpp +++ b/tests/argumentparsertests.cpp @@ -68,6 +68,7 @@ public: private: void callback(); + [[noreturn]] void failOnExit(int code); }; CPPUNIT_TEST_SUITE_REGISTRATION(ArgumentParserTests); @@ -84,6 +85,11 @@ void ArgumentParserTests::tearDown() { } +[[noreturn]] void ArgumentParserTests::failOnExit(int code) +{ + CPPUNIT_FAIL(argsToString("Exited unexpectedly with code ", code)); +} + /*! * \brief Tests the behaviour of the argument class. */ @@ -116,6 +122,7 @@ void ArgumentParserTests::testParsing() { // setup parser with some test argument definitions ArgumentParser parser; + parser.setExitFunction(std::bind(&ArgumentParserTests::failOnExit, this, std::placeholders::_1)); SET_APPLICATION_INFO; QT_CONFIG_ARGUMENTS qtConfigArgs; Argument verboseArg("verbose", 'v', "be verbose"); @@ -450,6 +457,7 @@ void ArgumentParserTests::testParsing() void ArgumentParserTests::testCallbacks() { ArgumentParser parser; + parser.setExitFunction(std::bind(&ArgumentParserTests::failOnExit, this, std::placeholders::_1)); Argument callbackArg("with-callback", 't', "callback test"); callbackArg.setRequiredValueCount(2); callbackArg.setCallback([](const ArgumentOccurrence &occurrence) { @@ -493,6 +501,7 @@ static bool exitCalled = false; void ArgumentParserTests::testBashCompletion() { ArgumentParser parser; + parser.setExitFunction(std::bind(&ArgumentParserTests::failOnExit, this, std::placeholders::_1)); HelpArgument helpArg(parser); Argument verboseArg("verbose", 'v', "be verbose"); verboseArg.setCombinable(true); @@ -832,6 +841,7 @@ void ArgumentParserTests::testHelp() void ArgumentParserTests::testSetMainArguments() { ArgumentParser parser; + parser.setExitFunction(std::bind(&ArgumentParserTests::failOnExit, this, std::placeholders::_1)); HelpArgument helpArg(parser); Argument subArg("sub-arg", 's', "mandatory sub arg"); subArg.setRequired(true);