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),
_description(desc),
_required(req),
_requireLabel("required"),
_valueRequired(valreq),
_alreadySet(false),
_visitor( v ),
_ignoreable(true)
_ignoreable(true),
_xorSet(false)
{
if ( _flag.length() > 1 )
throw(ArgException("Argument flag can only be one character long",
@ -59,8 +61,12 @@ Arg::Arg()
_name(""),
_description(""),
_required(false),
_requireLabel("required"),
_valueRequired(false),
_alreadySet(false)
_alreadySet(false),
_visitor( NULL ),
_ignoreable(false),
_xorSet(false)
{ };
Arg::Arg(const Arg& a)
@ -69,8 +75,12 @@ Arg::Arg(const Arg& a)
_name(a._name),
_description(a._description),
_required(a._required),
_requireLabel(a._requireLabel),
_valueRequired(a._valueRequired),
_alreadySet(a._alreadySet)
_alreadySet(a._alreadySet),
_visitor( a._visitor ),
_ignoreable(a._ignoreable),
_xorSet(a._xorSet)
{ };
Arg::~Arg() { };
@ -83,8 +93,12 @@ Arg& Arg::operator=(const Arg& a)
_name = a._name;
_description = a._description;
_required = a._required;
_requireLabel = a._requireLabel;
_valueRequired = a._valueRequired;
_alreadySet = a._alreadySet;
_visitor = a._visitor;
_ignoreable = a._ignoreable;
_xorSet = a._xorSet;
}
return *this;
};
@ -149,7 +163,7 @@ string Arg::getDescription() const
{
string desc = "";
if ( _required )
desc = "(required) ";
desc = "(" + _requireLabel + ") ";
if ( _valueRequired )
desc += "(value required) ";
@ -161,9 +175,22 @@ string Arg::getDescription() const
const string& Arg::getFlag() const { return _flag; };
bool Arg::isRequired() const { return _required; }
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; }
void Arg::setRequireLabel( const string& s)
{
_requireLabel = s;
}
bool Arg::argMatches( const string& argFlag ) const
{
if ( argFlag == Arg::flagStartString + _flag ||
@ -218,4 +245,15 @@ bool Arg::_hasBlanks( const string& s ) const
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 {
@ -62,23 +62,50 @@ void CmdLine::_constructor()
"Ignores the rest of the labeled arguments following this flag.",
false, new IgnoreRestVisitor() );
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 )
{
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: "
<< a.toString() << " Ignoring!" << endl;
<< a->toString() << " Ignoring!" << endl;
return;
}
if ( a.getFlag() == "" )
_argList.push_back( &a );
if ( a->getFlag() == "" )
_argList.push_back( a );
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 ;
_xorHandler.shortUsage();
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
if ( !_xorHandler.contains( (*it) ) )
cout << " " << (*it)->shortID();
cout << endl << endl << "Where: " << endl << endl;
_xorHandler.longUsage();
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
if ( !_xorHandler.contains( (*it) ) )
cout << " " << (*it)->longID() << endl << " "
<< (*it)->getDescription() << endl << endl;
@ -126,8 +159,7 @@ void CmdLine::parse(int argc, char** argv)
{
if ( (*it)->processArg( &i, args ) )
{
if ( (*it)->isRequired() )
requiredCount++;
requiredCount += _xorHandler.check( *it );
matched = true;
break;
}

View File

@ -1,7 +1,7 @@
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

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