mirror of
https://github.com/cuberite/TCLAP.git
synced 2025-09-10 12:49:08 -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 \
|
noinst_PROGRAMS = test1 test2 test3 test4 test5 test6 test7 test8 test9 \
|
||||||
test10 test11 test12 test13 test14 test15 test16 \
|
test10 test11 test12 test13 test14 test15 test16 \
|
||||||
test17
|
test17 test18
|
||||||
|
|
||||||
test1_SOURCES = test1.cpp
|
test1_SOURCES = test1.cpp
|
||||||
test2_SOURCES = test2.cpp
|
test2_SOURCES = test2.cpp
|
||||||
@ -20,7 +20,8 @@ test14_SOURCES = test14.cpp
|
|||||||
test15_SOURCES = test15.cpp
|
test15_SOURCES = test15.cpp
|
||||||
test16_SOURCES = test16.cpp
|
test16_SOURCES = test16.cpp
|
||||||
test17_SOURCES = test17.cpp test17-a.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
|
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;
|
CmdLineOutput* _output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should CmdLine handle parsing exceptions internally?
|
||||||
|
*/
|
||||||
|
bool _handleExceptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws an exception listing the missing args.
|
* Throws an exception listing the missing args.
|
||||||
*/
|
*/
|
||||||
@ -232,7 +237,7 @@ private:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the command line.
|
* 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.
|
* args[0] is still the program name.
|
||||||
*/
|
*/
|
||||||
void parse(std::vector<std::string>& args);
|
void parse(std::vector<std::string>& args);
|
||||||
@ -281,6 +286,21 @@ private:
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool hasHelpAndVersion();
|
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),
|
_version(v),
|
||||||
_numRequired(0),
|
_numRequired(0),
|
||||||
_delimiter(delim),
|
_delimiter(delim),
|
||||||
|
_handleExceptions(true),
|
||||||
_userSetOutput(false),
|
_userSetOutput(false),
|
||||||
_helpAndVersion(help)
|
_helpAndVersion(help)
|
||||||
{
|
{
|
||||||
@ -307,7 +328,7 @@ inline CmdLine::~CmdLine()
|
|||||||
{
|
{
|
||||||
ClearContainer(_argDeleteOnExitList);
|
ClearContainer(_argDeleteOnExitList);
|
||||||
ClearContainer(_visitorDeleteOnExitList);
|
ClearContainer(_visitorDeleteOnExitList);
|
||||||
|
|
||||||
if ( !_userSetOutput ) {
|
if ( !_userSetOutput ) {
|
||||||
delete _output;
|
delete _output;
|
||||||
_output = 0;
|
_output = 0;
|
||||||
@ -395,7 +416,7 @@ inline void CmdLine::add( Arg* a )
|
|||||||
inline void CmdLine::parse(int argc, const char * const * argv)
|
inline void CmdLine::parse(int argc, const char * const * argv)
|
||||||
{
|
{
|
||||||
// this step is necessary so that we have easy access to
|
// this step is necessary so that we have easy access to
|
||||||
// mutable strings.
|
// mutable strings.
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
for (int i = 0; i < argc; i++)
|
for (int i = 0; i < argc; i++)
|
||||||
args.push_back(argv[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++) {
|
for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++) {
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for (ArgListIterator it = _argList.begin();
|
for (ArgListIterator it = _argList.begin();
|
||||||
it != _argList.end(); it++) {
|
it != _argList.end(); it++) {
|
||||||
if ( (*it)->processArg( &i, args ) )
|
if ( (*it)->processArg( &i, args ) )
|
||||||
{
|
{
|
||||||
@ -443,14 +464,19 @@ inline void CmdLine::parse(std::vector<std::string>& args)
|
|||||||
if ( requiredCount > _numRequired )
|
if ( requiredCount > _numRequired )
|
||||||
throw(CmdLineParseException("Too many arguments!"));
|
throw(CmdLineParseException("Too many arguments!"));
|
||||||
|
|
||||||
} catch ( ArgException& e ) {
|
} catch ( ArgException& e ) {
|
||||||
try {
|
// If we're not handling the exceptions, rethrow.
|
||||||
_output->failure(*this,e);
|
if ( !_handleExceptions) {
|
||||||
} catch ( ExitException &ee ) {
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_output->failure(*this,e);
|
||||||
|
} catch ( ExitException &ee ) {
|
||||||
estat = ee.getExitStatus();
|
estat = ee.getExitStatus();
|
||||||
shouldExit = true;
|
shouldExit = true;
|
||||||
}
|
}
|
||||||
} catch (ExitException &ee) {
|
} catch (ExitException &ee) {
|
||||||
estat = ee.getExitStatus();
|
estat = ee.getExitStatus();
|
||||||
shouldExit = true;
|
shouldExit = true;
|
||||||
}
|
}
|
||||||
@ -471,7 +497,7 @@ inline bool CmdLine::_emptyCombined(const std::string& s)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CmdLine::missingArgsException()
|
inline void CmdLine::missingArgsException()
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
@ -486,7 +512,7 @@ inline void CmdLine::missingArgsException()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
missingArgList = missingArgList.substr(0,missingArgList.length()-2);
|
missingArgList = missingArgList.substr(0,missingArgList.length()-2);
|
||||||
|
|
||||||
std::string msg;
|
std::string msg;
|
||||||
if ( count > 1 )
|
if ( count > 1 )
|
||||||
msg = "Required arguments missing: ";
|
msg = "Required arguments missing: ";
|
||||||
@ -554,6 +580,16 @@ inline bool CmdLine::hasHelpAndVersion()
|
|||||||
return _helpAndVersion;
|
return _helpAndVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void CmdLine::setExceptionHandling(const bool state)
|
||||||
|
{
|
||||||
|
_handleExceptions = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool CmdLine::getExceptionHandling() const
|
||||||
|
{
|
||||||
|
return _handleExceptions;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//End CmdLine.cpp
|
//End CmdLine.cpp
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -67,7 +67,8 @@ TESTS = test1.sh \
|
|||||||
test65.sh \
|
test65.sh \
|
||||||
test66.sh \
|
test66.sh \
|
||||||
test67.sh \
|
test67.sh \
|
||||||
test68.sh
|
test68.sh \
|
||||||
|
test69.sh
|
||||||
|
|
||||||
EXTRA_DIST = $(TESTS) \
|
EXTRA_DIST = $(TESTS) \
|
||||||
test1.out \
|
test1.out \
|
||||||
@ -137,6 +138,7 @@ EXTRA_DIST = $(TESTS) \
|
|||||||
test65.out \
|
test65.out \
|
||||||
test66.out \
|
test66.out \
|
||||||
test67.out \
|
test67.out \
|
||||||
test68.out
|
test68.out \
|
||||||
|
test69.out
|
||||||
|
|
||||||
CLEANFILES = tmp.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