added xor

This commit is contained in:
mes5k 2004-02-04 03:22:09 +00:00
parent 848a66aa75
commit 000ffbb417
4 changed files with 195 additions and 18 deletions

View File

@ -43,10 +43,12 @@ Arg::Arg( const string& flag,
_name(name), _name(name),
_description(desc), _description(desc),
_required(req), _required(req),
_requireLabel("required"),
_valueRequired(valreq), _valueRequired(valreq),
_alreadySet(false), _alreadySet(false),
_visitor( v ), _visitor( v ),
_ignoreable(true) _ignoreable(true),
_xorSet(false)
{ {
if ( _flag.length() > 1 ) if ( _flag.length() > 1 )
throw(ArgException("Argument flag can only be one character long", throw(ArgException("Argument flag can only be one character long",
@ -59,8 +61,12 @@ Arg::Arg()
_name(""), _name(""),
_description(""), _description(""),
_required(false), _required(false),
_requireLabel("required"),
_valueRequired(false), _valueRequired(false),
_alreadySet(false) _alreadySet(false),
_visitor( NULL ),
_ignoreable(false),
_xorSet(false)
{ }; { };
Arg::Arg(const Arg& a) Arg::Arg(const Arg& a)
@ -69,8 +75,12 @@ Arg::Arg(const Arg& a)
_name(a._name), _name(a._name),
_description(a._description), _description(a._description),
_required(a._required), _required(a._required),
_requireLabel(a._requireLabel),
_valueRequired(a._valueRequired), _valueRequired(a._valueRequired),
_alreadySet(a._alreadySet) _alreadySet(a._alreadySet),
_visitor( a._visitor ),
_ignoreable(a._ignoreable),
_xorSet(a._xorSet)
{ }; { };
Arg::~Arg() { }; Arg::~Arg() { };
@ -83,8 +93,12 @@ Arg& Arg::operator=(const Arg& a)
_name = a._name; _name = a._name;
_description = a._description; _description = a._description;
_required = a._required; _required = a._required;
_requireLabel = a._requireLabel;
_valueRequired = a._valueRequired; _valueRequired = a._valueRequired;
_alreadySet = a._alreadySet; _alreadySet = a._alreadySet;
_visitor = a._visitor;
_ignoreable = a._ignoreable;
_xorSet = a._xorSet;
} }
return *this; return *this;
}; };
@ -149,7 +163,7 @@ string Arg::getDescription() const
{ {
string desc = ""; string desc = "";
if ( _required ) if ( _required )
desc = "(required) "; desc = "(" + _requireLabel + ") ";
if ( _valueRequired ) if ( _valueRequired )
desc += "(value required) "; desc += "(value required) ";
@ -161,9 +175,22 @@ string Arg::getDescription() const
const string& Arg::getFlag() const { return _flag; }; const string& Arg::getFlag() const { return _flag; };
bool Arg::isRequired() const { return _required; } bool Arg::isRequired() const { return _required; }
bool Arg::isValueRequired() const { return _valueRequired; } bool Arg::isValueRequired() const { return _valueRequired; }
bool Arg::isAlreadySet() const { return _alreadySet; }
bool Arg::isSet() const
{
if ( _alreadySet && !_xorSet )
return true;
else
return false;
}
bool Arg::isIgnoreable() const { return _ignoreable; } bool Arg::isIgnoreable() const { return _ignoreable; }
void Arg::setRequireLabel( const string& s)
{
_requireLabel = s;
}
bool Arg::argMatches( const string& argFlag ) const bool Arg::argMatches( const string& argFlag ) const
{ {
if ( argFlag == Arg::flagStartString + _flag || if ( argFlag == Arg::flagStartString + _flag ||
@ -218,4 +245,15 @@ bool Arg::_hasBlanks( const string& s ) const
return false; return false;
} }
void Arg::forceRequired()
{
_required = true;
}
void Arg::xorSet()
{
_alreadySet = true;
_xorSet = true;
}
} }

View File

@ -20,7 +20,7 @@
*****************************************************************************/ *****************************************************************************/
#include <tclap/CmdLine.h> #include <tclap/CommandLine.h>
namespace TCLAP { namespace TCLAP {
@ -62,23 +62,50 @@ void CmdLine::_constructor()
"Ignores the rest of the labeled arguments following this flag.", "Ignores the rest of the labeled arguments following this flag.",
false, new IgnoreRestVisitor() ); false, new IgnoreRestVisitor() );
add( *ignore ); add( *ignore );
}
void CmdLine::xorAdd( vector<Arg*>& ors )
{
_xorHandler.add( ors );
for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
{
(*it)->forceRequired();
(*it)->setRequireLabel( "OR required" );
add( *it );
}
}
void CmdLine::xorAdd( Arg& a, Arg& b )
{
vector<Arg*> ors;
ors.push_back( &a );
ors.push_back( &b );
xorAdd( ors );
} }
void CmdLine::add( Arg& a ) void CmdLine::add( Arg& a )
{ {
if ( find(_argList.begin(),_argList.end(), &a) != _argList.end() ) add( &a );
}
void CmdLine::add( Arg* a )
{
if ( find(_argList.begin(),_argList.end(), a) != _argList.end() )
{ {
cerr << "ADD ERROR: Argument with same flag/name already exists: " cerr << "ADD ERROR: Argument with same flag/name already exists: "
<< a.toString() << " Ignoring!" << endl; << a->toString() << " Ignoring!" << endl;
return; return;
} }
if ( a.getFlag() == "" ) if ( a->getFlag() == "" )
_argList.push_back( &a ); _argList.push_back( a );
else else
_argList.push_front( &a ); _argList.push_front( a );
if ( a.isRequired() ) _numRequired++; if ( a->isRequired() ) _numRequired++;
} }
@ -93,12 +120,18 @@ void CmdLine::usage( int exitVal )
{ {
cout << endl << "USAGE: " << endl << endl << " " << _progName ; cout << endl << "USAGE: " << endl << endl << " " << _progName ;
_xorHandler.shortUsage();
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++) for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
if ( !_xorHandler.contains( (*it) ) )
cout << " " << (*it)->shortID(); cout << " " << (*it)->shortID();
cout << endl << endl << "Where: " << endl << endl; cout << endl << endl << "Where: " << endl << endl;
_xorHandler.longUsage();
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++) for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
if ( !_xorHandler.contains( (*it) ) )
cout << " " << (*it)->longID() << endl << " " cout << " " << (*it)->longID() << endl << " "
<< (*it)->getDescription() << endl << endl; << (*it)->getDescription() << endl << endl;
@ -126,8 +159,7 @@ void CmdLine::parse(int argc, char** argv)
{ {
if ( (*it)->processArg( &i, args ) ) if ( (*it)->processArg( &i, args ) )
{ {
if ( (*it)->isRequired() ) requiredCount += _xorHandler.check( *it );
requiredCount++;
matched = true; matched = true;
break; break;
} }

View File

@ -1,7 +1,7 @@
lib_LIBRARIES = libtclap.a lib_LIBRARIES = libtclap.a
libtclap_a_SOURCES = Arg.cpp CmdLine.cpp SwitchArg.cpp libtclap_a_SOURCES = Arg.cpp CmdLine.cpp SwitchArg.cpp XorHandler.cpp
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include

107
src/XorHandler.cpp Normal file
View File

@ -0,0 +1,107 @@
/******************************************************************************
*
* file: XorHandler.cpp
*
* Copyright (c) 2003, Michael E. Smoot .
* All rights reverved.
*
* See the file COPYING in the top directory of this distribution for
* more information.
*
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include <tclap/XorHandler.h>
namespace TCLAP {
XorHandler::XorHandler( )
{ }
void XorHandler::add( vector<Arg*>& ors )
{
_orList.push_back( ors );
}
void XorHandler::shortUsage()
{
string out = "";
for ( int i = 0; (unsigned int)i < _orList.size(); i++ )
{
out += " {";
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end(); it++ )
out += (*it)->shortID() + "|";
out[out.length()-1] = '}';
}
cout << out;
}
void XorHandler::longUsage()
{
for ( int i = 0; (unsigned int)i < _orList.size(); i++ )
{
int orCount = 0;
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end(); it++, orCount++ )
{
cout << " " << (*it)->longID() << endl
<< " " << (*it)->getDescription() << endl;
if ( (orCount % 2) == 0 )
cout << " -- OR -- " << endl;
}
cout << endl << endl;
}
}
int XorHandler::check( const Arg* a )
{
// iterate over each XOR list
for ( int i = 0; (unsigned int)i < _orList.size(); i++ )
{
// if the XOR list contains the arg..
if ( find( _orList[i].begin(), _orList[i].end(), a ) !=
_orList[i].end() )
{
// go through and set each arg that is not a
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
if ( a != (*it) )
(*it)->xorSet();
// return the number of required args that have now been set
return (int)_orList[i].size();
}
}
if ( a->isRequired() )
return 1;
else
return 0;
}
bool XorHandler::contains( const Arg* a )
{
for ( int i = 0; (unsigned int)i < _orList.size(); i++ )
for ( ArgVectorIterator it = _orList[i].begin();
it != _orList[i].end();
it++ )
if ( a == (*it) )
return true;
return false;
}
}