finally fixed bug relating to mutually exclusive combined switched

This commit is contained in:
mes5k 2011-01-03 00:20:46 +00:00
parent 4ba45abdb9
commit fc9d87a003
2 changed files with 77 additions and 37 deletions

View File

@ -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;

View File

@ -107,6 +107,16 @@ 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();