mirror of
https://github.com/cuberite/TCLAP.git
synced 2025-09-09 04:09:31 -04:00
Allow internal handling of parse errors to be turned off.
This allows exceptions for parse errors to be propagated to the caller. Exiting the program in parse is a bad idea generally, as we have no way of knowing what cleanup needs to be done in the main program.
This commit is contained in:
parent
9a32ab6294
commit
3431fcfd78
@ -1,7 +1,7 @@
|
||||
|
||||
noinst_PROGRAMS = test1 test2 test3 test4 test5 test6 test7 test8 test9 \
|
||||
test10 test11 test12 test13 test14 test15 test16 \
|
||||
test17
|
||||
test17 test18
|
||||
|
||||
test1_SOURCES = test1.cpp
|
||||
test2_SOURCES = test2.cpp
|
||||
@ -20,7 +20,8 @@ test14_SOURCES = test14.cpp
|
||||
test15_SOURCES = test15.cpp
|
||||
test16_SOURCES = test16.cpp
|
||||
test17_SOURCES = test17.cpp test17-a.cpp
|
||||
test18_SOURCES = test18.cpp
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
AM_CXXFLAGS = -Wall -Wextra
|
||||
|
24
examples/test18.cpp
Normal file
24
examples/test18.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include "tclap/CmdLine.h"
|
||||
|
||||
using namespace TCLAP;
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try {
|
||||
|
||||
CmdLine cmd("Command description message", ' ', "0.9", false);
|
||||
|
||||
cmd.setExceptionHandling(false);
|
||||
|
||||
cmd.parse(argc, argv);
|
||||
|
||||
} catch (ArgException &e) { // catch any exceptions
|
||||
cerr << "error: " << e.error() << " for arg " << e.argId() << endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +129,11 @@ class CmdLine : public CmdLineInterface
|
||||
*/
|
||||
CmdLineOutput* _output;
|
||||
|
||||
/**
|
||||
* Should CmdLine handle parsing exceptions internally?
|
||||
*/
|
||||
bool _handleExceptions;
|
||||
|
||||
/**
|
||||
* Throws an exception listing the missing args.
|
||||
*/
|
||||
@ -232,7 +237,7 @@ private:
|
||||
|
||||
/**
|
||||
* Parses the command line.
|
||||
* \param args - A vector of strings representing the args.
|
||||
* \param args - A vector of strings representing the args.
|
||||
* args[0] is still the program name.
|
||||
*/
|
||||
void parse(std::vector<std::string>& args);
|
||||
@ -281,6 +286,21 @@ private:
|
||||
*
|
||||
*/
|
||||
bool hasHelpAndVersion();
|
||||
|
||||
/**
|
||||
* Disables or enables CmdLine's internal parsing exception handling.
|
||||
*
|
||||
* @param state Should CmdLine handle parsing exceptions internally?
|
||||
*/
|
||||
void setExceptionHandling(const bool state);
|
||||
|
||||
/**
|
||||
* Returns the current state of the internal exception handling.
|
||||
*
|
||||
* @retval true Parsing exceptions are handled internally.
|
||||
* @retval false Parsing exceptions are propagated to the caller.
|
||||
*/
|
||||
bool getExceptionHandling() const;
|
||||
};
|
||||
|
||||
|
||||
@ -297,6 +317,7 @@ inline CmdLine::CmdLine(const std::string& m,
|
||||
_version(v),
|
||||
_numRequired(0),
|
||||
_delimiter(delim),
|
||||
_handleExceptions(true),
|
||||
_userSetOutput(false),
|
||||
_helpAndVersion(help)
|
||||
{
|
||||
@ -307,7 +328,7 @@ inline CmdLine::~CmdLine()
|
||||
{
|
||||
ClearContainer(_argDeleteOnExitList);
|
||||
ClearContainer(_visitorDeleteOnExitList);
|
||||
|
||||
|
||||
if ( !_userSetOutput ) {
|
||||
delete _output;
|
||||
_output = 0;
|
||||
@ -395,7 +416,7 @@ inline void CmdLine::add( Arg* a )
|
||||
inline void CmdLine::parse(int argc, const char * const * argv)
|
||||
{
|
||||
// this step is necessary so that we have easy access to
|
||||
// mutable strings.
|
||||
// mutable strings.
|
||||
std::vector<std::string> args;
|
||||
for (int i = 0; i < argc; i++)
|
||||
args.push_back(argv[i]);
|
||||
@ -416,7 +437,7 @@ inline void CmdLine::parse(std::vector<std::string>& args)
|
||||
|
||||
for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++) {
|
||||
bool matched = false;
|
||||
for (ArgListIterator it = _argList.begin();
|
||||
for (ArgListIterator it = _argList.begin();
|
||||
it != _argList.end(); it++) {
|
||||
if ( (*it)->processArg( &i, args ) )
|
||||
{
|
||||
@ -443,14 +464,19 @@ inline void CmdLine::parse(std::vector<std::string>& args)
|
||||
if ( requiredCount > _numRequired )
|
||||
throw(CmdLineParseException("Too many arguments!"));
|
||||
|
||||
} catch ( ArgException& e ) {
|
||||
try {
|
||||
_output->failure(*this,e);
|
||||
} catch ( ExitException &ee ) {
|
||||
} catch ( ArgException& e ) {
|
||||
// If we're not handling the exceptions, rethrow.
|
||||
if ( !_handleExceptions) {
|
||||
throw;
|
||||
}
|
||||
|
||||
try {
|
||||
_output->failure(*this,e);
|
||||
} catch ( ExitException &ee ) {
|
||||
estat = ee.getExitStatus();
|
||||
shouldExit = true;
|
||||
}
|
||||
} catch (ExitException &ee) {
|
||||
} catch (ExitException &ee) {
|
||||
estat = ee.getExitStatus();
|
||||
shouldExit = true;
|
||||
}
|
||||
@ -471,7 +497,7 @@ inline bool CmdLine::_emptyCombined(const std::string& s)
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void CmdLine::missingArgsException()
|
||||
inline void CmdLine::missingArgsException()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
@ -486,7 +512,7 @@ inline void CmdLine::missingArgsException()
|
||||
}
|
||||
}
|
||||
missingArgList = missingArgList.substr(0,missingArgList.length()-2);
|
||||
|
||||
|
||||
std::string msg;
|
||||
if ( count > 1 )
|
||||
msg = "Required arguments missing: ";
|
||||
@ -554,6 +580,16 @@ inline bool CmdLine::hasHelpAndVersion()
|
||||
return _helpAndVersion;
|
||||
}
|
||||
|
||||
inline void CmdLine::setExceptionHandling(const bool state)
|
||||
{
|
||||
_handleExceptions = state;
|
||||
}
|
||||
|
||||
inline bool CmdLine::getExceptionHandling() const
|
||||
{
|
||||
return _handleExceptions;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//End CmdLine.cpp
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,7 +67,8 @@ TESTS = test1.sh \
|
||||
test65.sh \
|
||||
test66.sh \
|
||||
test67.sh \
|
||||
test68.sh
|
||||
test68.sh \
|
||||
test69.sh
|
||||
|
||||
EXTRA_DIST = $(TESTS) \
|
||||
test1.out \
|
||||
@ -137,6 +138,7 @@ EXTRA_DIST = $(TESTS) \
|
||||
test65.out \
|
||||
test66.out \
|
||||
test67.out \
|
||||
test68.out
|
||||
test68.out \
|
||||
test69.out
|
||||
|
||||
CLEANFILES = tmp.out
|
||||
|
1
tests/test69.out
Normal file
1
tests/test69.out
Normal file
@ -0,0 +1 @@
|
||||
error: Couldn't find match for argument for arg Argument: --bob
|
12
tests/test69.sh
Executable file
12
tests/test69.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Checks that parsing exceptions are properly
|
||||
# propagated to the caller.
|
||||
../examples/test18 --bob > tmp.out 2>&1
|
||||
|
||||
if cmp -s tmp.out $srcdir/test69.out; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
Loading…
x
Reference in New Issue
Block a user