new update

This commit is contained in:
mes5k 2003-04-03 17:57:37 +00:00
parent 052681e0f0
commit 52b15b6e6e
3 changed files with 121 additions and 89 deletions

View File

@ -24,6 +24,8 @@
namespace TCLAP { namespace TCLAP {
bool Arg::_ignoreRest = false;
Arg::Arg( const string& flag, Arg::Arg( const string& flag,
const string& name, const string& name,
const string& desc, const string& desc,
@ -36,12 +38,12 @@ Arg::Arg( const string& flag,
_required(req), _required(req),
_valueRequired(valreq), _valueRequired(valreq),
_alreadySet(false), _alreadySet(false),
_ignoreable(true),
_visitor( v ) _visitor( v )
{ {
if ( _flag == "" ) if ( _flag.length() > 1 )
_labeled = false; throw(ArgException("Argument flag can only be one character long",
else toString() ) );
_labeled = true;
}; };
Arg::Arg() Arg::Arg()
@ -50,8 +52,7 @@ Arg::Arg()
_flag(""), _flag(""),
_required(false), _required(false),
_valueRequired(false), _valueRequired(false),
_alreadySet(false), _alreadySet(false)
_labeled(false)
{ }; { };
Arg::Arg(const Arg& a) Arg::Arg(const Arg& a)
@ -60,8 +61,7 @@ Arg::Arg(const Arg& a)
_flag(a._flag), _flag(a._flag),
_required(a._required), _required(a._required),
_valueRequired(a._valueRequired), _valueRequired(a._valueRequired),
_alreadySet(a._alreadySet), _alreadySet(a._alreadySet)
_labeled(a._labeled)
{ }; { };
Arg::~Arg() { }; Arg::~Arg() { };
@ -76,62 +76,81 @@ Arg& Arg::operator=(const Arg& a)
_required = a._required; _required = a._required;
_valueRequired = a._valueRequired; _valueRequired = a._valueRequired;
_alreadySet = a._alreadySet; _alreadySet = a._alreadySet;
_labeled = a._labeled;
} }
return *this; return *this;
}; };
/* string Arg::shortID( const string& valueId ) const
bool Arg::operator<(const Arg& a) const
{ {
if ( _required && !a._required ) string id = "";
return false;
if ( !_required && a._required ) id = "-" + _flag;
return true;
if ( _labeled && !a._labeled ) if ( _valueRequired )
return false; id += " <" + valueId + ">";
if ( !_labeled && a._labeled ) if ( !_required )
return true; id = "[" + id + "]";
return id;
}
string Arg::longID( const string& valueId ) const
{
string id = "";
id = "-" + _flag;
if ( _valueRequired )
id += " <" + valueId + ">";
id += ", --" + _name;
if ( _valueRequired )
id += " <" + valueId + ">";
return id;
return false;
} }
*/
bool Arg::operator==(const Arg& a) bool Arg::operator==(const Arg& a)
{ {
if ( _labeled ) if ( _flag == a._flag ||
{ _name == a._name ||
if ( _flag == a._flag || _name == a._name ) _description == a._description )
return true; return true;
else else
return false; return false;
} }
else
{
if ( _name == a._name || _description == a._description )
return true;
else
return false;
}
}
// should be overridden // should be overridden
bool Arg::processArg(int* i, int argc, char** argv) bool Arg::processArg(int* i, vector<string>& args )
{ {
cerr << "WARNING: Ignoring unknown argument: " << argv[*i] << endl; cerr << "WARNING: Ignoring unknown argument: " << args[*i] << endl;
return false; return false;
} }
const string& Arg::getName() const { return _name; } ; const string& Arg::getName() const { return _name; } ;
const string& Arg::getDescription() const { return _description; };
string Arg::getDescription() const
{
string desc = "";
if ( _required )
desc = "(required) ";
if ( _valueRequired )
desc += "(value required) ";
desc += _description;
return desc;
};
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::isAlreadySet() const { return _alreadySet; }
bool Arg::isLabeled() const { return _labeled; } bool Arg::isIgnoreable() const { return _ignoreable; }
bool Arg::argMatches( const string& argFlag ) const bool Arg::argMatches( const string& argFlag ) const
{ {

View File

@ -28,18 +28,22 @@ CmdLine::CmdLine(char *progName, const string& m, const string& v )
: _progName(progName), : _progName(progName),
_message(m), _message(m),
_version(v), _version(v),
_numRequired(0), _numRequired(0)
_maxLength(0)
{ {
SwitchArg* help = new SwitchArg("h","help", SwitchArg* help = new SwitchArg("h","help",
"displays usage information and exits", "Displays usage information and exits.",
false, new HelpVisitor( this ) ); false, new HelpVisitor( this ) );
add( *help ); add( *help );
SwitchArg* vers = new SwitchArg("v","version", SwitchArg* vers = new SwitchArg("v","version",
"displays version information and exits", "Displays version information and exits.",
false, new VersionVisitor( this ) ); false, new VersionVisitor( this ) );
add( *vers ); add( *vers );
SwitchArg* ignore = new SwitchArg("-","ignore_rest",
"Ignores the rest of the labeled arguments following this flag.",
false, new IgnoreRestVisitor() );
add( *ignore );
} }
void CmdLine::add( Arg& a ) void CmdLine::add( Arg& a )
@ -51,12 +55,11 @@ void CmdLine::add( Arg& a )
return; return;
} }
if ( a.isLabeled() ) if ( a.getFlag() == "" )
_argList.push_front( &a );
else
_argList.push_back( &a ); _argList.push_back( &a );
else
_argList.push_front( &a );
_maxLength = max( _maxLength, (int)((a.getName()).length()) );
if ( a.isRequired() ) _numRequired++; if ( a.isRequired() ) _numRequired++;
} }
@ -73,45 +76,13 @@ void CmdLine::usage( int exitVal )
cout << endl << "USAGE: " << endl << endl << " " << _progName ; cout << endl << "USAGE: " << endl << endl << " " << _progName ;
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++) for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
{ cout << " " << (*it)->shortID();
cout << " ";
if ( !(*it)->isRequired() ) cout << "[";
if ( (*it)->isLabeled() )
cout << "-" << ((*it))->getFlag();
if ( (*it)->isValueRequired() )
{
if ( (*it)->isLabeled() ) cout << " ";
cout << (*it)->getName();
}
if ( !(*it)->isRequired() ) cout << "]";
}
cout << endl << endl << "Where: " << endl << endl; cout << endl << endl << "Where: " << endl << endl;
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++) for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
{ cout << " " << (*it)->longID() << endl << " "
cout.setf(ios::left); << (*it)->getDescription() << endl << endl;
string s;
if ( !(*it)->isRequired() ) s += "[";
else s += " ";
if ( (*it)->isLabeled() )
s = s + "-" + (*it)->getFlag();
if ( (*it)->isValueRequired() )
{
if ( (*it)->isLabeled() ) s += " ";
s += (*it)->getName();
}
if ( !(*it)->isRequired() ) s += "]";
cout << " " << setw(_maxLength + 5) << s.c_str() << " = "
<< (*it)->getDescription() << endl;
}
cout << endl << endl << _message << endl << endl; cout << endl << endl << _message << endl << endl;
exit( exitVal ); exit( exitVal );
@ -121,14 +92,19 @@ void CmdLine::parse(int argc, char** argv)
{ {
try { try {
// this step is necessary so that we have easy access to mutable strings.
vector<string> args;
for (int i = 1; i < argc; i++)
args.push_back(argv[i]);
int requiredCount = 0; int requiredCount = 0;
for (int i = 1; i < argc; i++) for (int i = 0; i < args.size(); i++)
{ {
bool matched = false; bool matched = false;
for (ArgIterator it = _argList.begin(); it != _argList.end(); it++) for (ArgIterator it = _argList.begin(); it != _argList.end(); it++)
{ {
if ( (*it)->processArg( &i, argc, argv ) ) if ( (*it)->processArg( &i, args ) )
{ {
if ( (*it)->isRequired() ) requiredCount++; if ( (*it)->isRequired() ) requiredCount++;
matched = true; matched = true;
@ -136,8 +112,8 @@ void CmdLine::parse(int argc, char** argv)
} }
} }
if ( !matched ) if ( !matched && !Arg::ignoreRest() )
throw( ArgException("Couldn't find match for argument",argv[i])); throw( ArgException("Couldn't find match for argument",args[i]));
} }
if ( requiredCount < _numRequired ) if ( requiredCount < _numRequired )

View File

@ -40,10 +40,47 @@ SwitchArg::~SwitchArg() { };
bool SwitchArg::getValue() { return _value; }; bool SwitchArg::getValue() { return _value; };
bool SwitchArg::processArg(int *i, int argc, char** argv) bool SwitchArg::combinedSwitchesMatch(string& combinedSwitches )
{ {
if ( argMatches( argv[*i] ) ) // make sure this is actually a combined switch
if ( combinedSwitches[0] != '-' )
return false;
// make sure it isn't a long name
if ( combinedSwitches[1] == '-' )
return false;
// ok, we're not specifying a ValueArg, so we know that we have
// a combined switch list.
for ( int i = 1; i < combinedSwitches.length(); i++ )
if ( combinedSwitches[i] == _flag[0] )
{ {
// update the combined switches so this one is no longer present
// this is necessary so that no unlabeled args are matched
// later in the processing.
combinedSwitches.erase(i,1);
return true;
}
// none of the switches passed in the list match.
return false;
}
bool SwitchArg::processArg(int *i, vector<string>& args)
{
if ( _ignoreable && Arg::ignoreRest() )
return false;
if ( argMatches( args[*i] ) || combinedSwitchesMatch( args[*i] ) )
{
// If we match on a combined switch, then we want to return false
// 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 ) if ( _alreadySet )
throw(ArgException("Argument already set!", toString())); throw(ArgException("Argument already set!", toString()));
@ -56,7 +93,7 @@ bool SwitchArg::processArg(int *i, int argc, char** argv)
_checkWithVisitor(); _checkWithVisitor();
return true; return ret;
} }
else else
return false; return false;