Use exit function passed to argument parser

This commit is contained in:
Martchus 2019-03-24 21:52:10 +01:00
parent 57c896b547
commit cfdfc302db
3 changed files with 25 additions and 8 deletions

View File

@ -416,12 +416,6 @@ std::vector<const char *> dependencyVersions2;
// TODO v5 use a struct for these properties // 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 /// \cond
inline bool notEmpty(const char *str) inline bool notEmpty(const char *str)
@ -899,7 +893,7 @@ void ArgumentParser::parseArgsExt(int argc, const char *const *argv, ParseArgume
if (behavior & ParseArgumentBehavior::ExitOnFailure) { if (behavior & ParseArgumentBehavior::ExitOnFailure) {
CMD_UTILS_START_CONSOLE; CMD_UTILS_START_CONSOLE;
cerr << failure; cerr << failure;
exit(1); invokeExit(1);
} }
throw; 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 // print Bash completion and prevent the applicaton to continue with the regular execution
if (completionMode) { if (completionMode) {
printBashCompletion(argc, argv, currentWordIndex, reader); 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 * \class HelpArgument
* \brief The HelpArgument class prints help information for an argument parser * \brief The HelpArgument class prints help information for an argument parser

View File

@ -478,6 +478,7 @@ private:
void printBashCompletion(int argc, const char *const *argv, unsigned int cursorPos, const ArgumentReader &reader) const; void printBashCompletion(int argc, const char *const *argv, unsigned int cursorPos, const ArgumentReader &reader) const;
void checkConstraints(const ArgumentVector &args); void checkConstraints(const ArgumentVector &args);
static void invokeCallbacks(const ArgumentVector &args); static void invokeCallbacks(const ArgumentVector &args);
void invokeExit(int code);
ArgumentVector m_mainArgs; ArgumentVector m_mainArgs;
unsigned int m_actualArgc; unsigned int m_actualArgc;

View File

@ -68,6 +68,7 @@ public:
private: private:
void callback(); void callback();
[[noreturn]] void failOnExit(int code);
}; };
CPPUNIT_TEST_SUITE_REGISTRATION(ArgumentParserTests); 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. * \brief Tests the behaviour of the argument class.
*/ */
@ -116,6 +122,7 @@ void ArgumentParserTests::testParsing()
{ {
// setup parser with some test argument definitions // setup parser with some test argument definitions
ArgumentParser parser; ArgumentParser parser;
parser.setExitFunction(std::bind(&ArgumentParserTests::failOnExit, this, std::placeholders::_1));
SET_APPLICATION_INFO; SET_APPLICATION_INFO;
QT_CONFIG_ARGUMENTS qtConfigArgs; QT_CONFIG_ARGUMENTS qtConfigArgs;
Argument verboseArg("verbose", 'v', "be verbose"); Argument verboseArg("verbose", 'v', "be verbose");
@ -450,6 +457,7 @@ void ArgumentParserTests::testParsing()
void ArgumentParserTests::testCallbacks() void ArgumentParserTests::testCallbacks()
{ {
ArgumentParser parser; ArgumentParser parser;
parser.setExitFunction(std::bind(&ArgumentParserTests::failOnExit, this, std::placeholders::_1));
Argument callbackArg("with-callback", 't', "callback test"); Argument callbackArg("with-callback", 't', "callback test");
callbackArg.setRequiredValueCount(2); callbackArg.setRequiredValueCount(2);
callbackArg.setCallback([](const ArgumentOccurrence &occurrence) { callbackArg.setCallback([](const ArgumentOccurrence &occurrence) {
@ -493,6 +501,7 @@ static bool exitCalled = false;
void ArgumentParserTests::testBashCompletion() void ArgumentParserTests::testBashCompletion()
{ {
ArgumentParser parser; ArgumentParser parser;
parser.setExitFunction(std::bind(&ArgumentParserTests::failOnExit, this, std::placeholders::_1));
HelpArgument helpArg(parser); HelpArgument helpArg(parser);
Argument verboseArg("verbose", 'v', "be verbose"); Argument verboseArg("verbose", 'v', "be verbose");
verboseArg.setCombinable(true); verboseArg.setCombinable(true);
@ -832,6 +841,7 @@ void ArgumentParserTests::testHelp()
void ArgumentParserTests::testSetMainArguments() void ArgumentParserTests::testSetMainArguments()
{ {
ArgumentParser parser; ArgumentParser parser;
parser.setExitFunction(std::bind(&ArgumentParserTests::failOnExit, this, std::placeholders::_1));
HelpArgument helpArg(parser); HelpArgument helpArg(parser);
Argument subArg("sub-arg", 's', "mandatory sub arg"); Argument subArg("sub-arg", 's', "mandatory sub arg");
subArg.setRequired(true); subArg.setRequired(true);