mirror of
https://github.com/cuberite/TCLAP.git
synced 2025-08-04 02:06:29 -04:00
finally fixed bug relating to mutually exclusive combined switched
This commit is contained in:
parent
4ba45abdb9
commit
fc9d87a003
@ -116,27 +116,38 @@ class SwitchArg : public Arg
|
|||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Checks to see if we've found the last match in
|
||||||
|
* a combined string.
|
||||||
|
*/
|
||||||
|
bool lastCombined(std::string& combined);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the common processing of processArg.
|
||||||
|
*/
|
||||||
|
void commonProcessing();
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//BEGIN SwitchArg.cpp
|
//BEGIN SwitchArg.cpp
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
inline SwitchArg::SwitchArg(const std::string& flag,
|
inline SwitchArg::SwitchArg(const std::string& flag,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& desc,
|
const std::string& desc,
|
||||||
bool default_val,
|
bool default_val,
|
||||||
Visitor* v )
|
Visitor* v )
|
||||||
: Arg(flag, name, desc, false, false, v),
|
: Arg(flag, name, desc, false, false, v),
|
||||||
_value( default_val ),
|
_value( default_val ),
|
||||||
_default( default_val )
|
_default( default_val )
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
inline SwitchArg::SwitchArg(const std::string& flag,
|
inline SwitchArg::SwitchArg(const std::string& flag,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& desc,
|
const std::string& desc,
|
||||||
CmdLineInterface& parser,
|
CmdLineInterface& parser,
|
||||||
bool default_val,
|
bool default_val,
|
||||||
Visitor* v )
|
Visitor* v )
|
||||||
: Arg(flag, name, desc, false, false, v),
|
: Arg(flag, name, desc, false, false, v),
|
||||||
_value( default_val ),
|
_value( default_val ),
|
||||||
_default(default_val)
|
_default(default_val)
|
||||||
@ -146,6 +157,15 @@ inline SwitchArg::SwitchArg(const std::string& flag,
|
|||||||
|
|
||||||
inline bool SwitchArg::getValue() { return _value; }
|
inline bool SwitchArg::getValue() { return _value; }
|
||||||
|
|
||||||
|
inline bool SwitchArg::lastCombined(std::string& combinedSwitches )
|
||||||
|
{
|
||||||
|
for ( unsigned int i = 1; i < combinedSwitches.length(); i++ )
|
||||||
|
if ( combinedSwitches[i] != Arg::blankChar() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches )
|
inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches )
|
||||||
{
|
{
|
||||||
// make sure this is actually a combined switch
|
// make sure this is actually a combined switch
|
||||||
@ -155,7 +175,7 @@ inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches )
|
|||||||
|
|
||||||
// make sure it isn't a long name
|
// make sure it isn't a long name
|
||||||
if ( combinedSwitches.substr( 0, Arg::nameStartString().length() ) ==
|
if ( combinedSwitches.substr( 0, Arg::nameStartString().length() ) ==
|
||||||
Arg::nameStartString() )
|
Arg::nameStartString() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// make sure the delimiter isn't in the string
|
// make sure the delimiter isn't in the string
|
||||||
@ -181,42 +201,52 @@ inline bool SwitchArg::combinedSwitchesMatch(std::string& combinedSwitches )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void SwitchArg::commonProcessing()
|
||||||
|
{
|
||||||
|
if ( _xorSet )
|
||||||
|
throw(CmdLineParseException(
|
||||||
|
"Mutually exclusive argument already set!", toString()));
|
||||||
|
|
||||||
|
if ( _alreadySet )
|
||||||
|
throw(CmdLineParseException("Argument already set!", toString()));
|
||||||
|
|
||||||
|
_alreadySet = true;
|
||||||
|
|
||||||
|
if ( _value == true )
|
||||||
|
_value = false;
|
||||||
|
else
|
||||||
|
_value = true;
|
||||||
|
|
||||||
|
_checkWithVisitor();
|
||||||
|
}
|
||||||
|
|
||||||
inline bool SwitchArg::processArg(int *i, std::vector<std::string>& args)
|
inline bool SwitchArg::processArg(int *i, std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
if ( _ignoreable && Arg::ignoreRest() )
|
if ( _ignoreable && Arg::ignoreRest() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( argMatches( args[*i] ) || combinedSwitchesMatch( args[*i] ) )
|
// if the whole string matches the flag or name string
|
||||||
|
if ( argMatches( args[*i] ) )
|
||||||
{
|
{
|
||||||
// If we match on a combined switch, then we want to return false
|
commonProcessing();
|
||||||
// so that other switches in the combination will also have a
|
|
||||||
// chance to match.
|
|
||||||
bool ret = false;
|
|
||||||
if ( argMatches( args[*i] ) )
|
|
||||||
ret = true;
|
|
||||||
|
|
||||||
if ( _alreadySet || ( !ret && combinedSwitchesMatch( args[*i] ) ) )
|
return true;
|
||||||
{
|
}
|
||||||
if ( _xorSet )
|
// if a substring matches the flag as part of a combination
|
||||||
throw(CmdLineParseException(
|
else if ( combinedSwitchesMatch( args[*i] ) )
|
||||||
"Mutually exclusive argument already set!",
|
{
|
||||||
toString()));
|
// check again to ensure we don't misinterpret
|
||||||
else
|
// this as a MultiSwitchArg
|
||||||
throw(CmdLineParseException("Argument already set!",
|
if ( combinedSwitchesMatch( args[*i] ) )
|
||||||
toString()));
|
throw(CmdLineParseException("Argument already set!",
|
||||||
}
|
toString()));
|
||||||
|
|
||||||
_alreadySet = true;
|
commonProcessing();
|
||||||
|
|
||||||
if ( _value == true )
|
// We only want to return true if we've found the last combined
|
||||||
_value = false;
|
// match in the string, otherwise we return true so that other
|
||||||
else
|
// switches in the combination will have a chance to match.
|
||||||
_value = true;
|
return lastCombined( args[*i] );
|
||||||
|
|
||||||
_checkWithVisitor();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -107,10 +107,20 @@ inline int XorHandler::check( const Arg* a )
|
|||||||
_orList[i].end(), a );
|
_orList[i].end(), a );
|
||||||
if ( ait != _orList[i].end() )
|
if ( ait != _orList[i].end() )
|
||||||
{
|
{
|
||||||
|
// first check to see if a mutually exclusive switch
|
||||||
|
// has not already been set
|
||||||
|
for ( ArgVectorIterator it = _orList[i].begin();
|
||||||
|
it != _orList[i].end();
|
||||||
|
it++ )
|
||||||
|
if ( a != (*it) && (*it)->isSet() )
|
||||||
|
throw(CmdLineParseException(
|
||||||
|
"Mutually exclusive argument already set!",
|
||||||
|
(*it)->toString()));
|
||||||
|
|
||||||
// go through and set each arg that is not a
|
// go through and set each arg that is not a
|
||||||
for ( ArgVectorIterator it = _orList[i].begin();
|
for ( ArgVectorIterator it = _orList[i].begin();
|
||||||
it != _orList[i].end();
|
it != _orList[i].end();
|
||||||
it++ )
|
it++ )
|
||||||
if ( a != (*it) )
|
if ( a != (*it) )
|
||||||
(*it)->xorSet();
|
(*it)->xorSet();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user