00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef TCLAP_ARGUMENT_H
00025 #define TCLAP_ARGUMENT_H
00026
00027 #include <string>
00028 #include <vector>
00029 #include <list>
00030 #include <iostream>
00031
00032 #include <tclap/ArgException.h>
00033 #include <tclap/Visitor.h>
00034 #include <tclap/CmdLineInterface.h>
00035
00036 namespace TCLAP {
00037
00043 class Arg
00044 {
00045 private:
00046
00050 static bool& ignoreRestRef() { static bool ign = false; return ign; }
00051
00056 static char& delimiterRef() { static char delim = ' '; return delim; }
00057
00058 protected:
00059
00068 std::string _flag;
00069
00077 std::string _name;
00078
00082 std::string _description;
00083
00087 bool _required;
00088
00093 std::string _requireLabel;
00094
00100 bool _valueRequired;
00101
00107 bool _alreadySet;
00108
00115 Visitor* _visitor;
00116
00120 bool _ignoreable;
00121
00126 bool _xorSet;
00127
00131 void _checkWithVisitor() const;
00132
00146 Arg( const std::string& flag,
00147 const std::string& name,
00148 const std::string& desc,
00149 bool req,
00150 bool valreq,
00151 Visitor* v = NULL );
00152
00153 public:
00157 virtual ~Arg();
00158
00163 virtual void addToList( std::list<Arg*>& argList ) const;
00164
00168 static void beginIgnoring() { ignoreRestRef() = true; }
00169
00173 static bool ignoreRest() { return ignoreRestRef(); }
00174
00179 static char delimiter() { return delimiterRef(); }
00180
00186 static const char blankChar() { return '*'; }
00187
00191 static const char flagStartChar() { return '-'; }
00192
00197 static const std::string flagStartString() { return "-"; }
00198
00203 static const std::string nameStartString() { return "--"; }
00204
00208 static const std::string ignoreNameString() { return "ignore_rest"; }
00209
00214 static void setDelimiter( char c ) { delimiterRef() = c; }
00215
00223 virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
00224
00230 virtual bool operator==(const Arg& a);
00231
00235 const std::string& getFlag() const;
00236
00240 const std::string& getName() const;
00241
00245 std::string getDescription() const;
00246
00250 virtual bool isRequired() const;
00251
00256 void forceRequired();
00257
00262 void xorSet();
00263
00267 bool isValueRequired() const;
00268
00273 bool isSet() const;
00274
00278 bool isIgnoreable() const;
00279
00288 virtual bool argMatches( const std::string& s ) const;
00289
00294 virtual std::string toString() const;
00295
00300 virtual std::string shortID( const std::string& valueId = "val" ) const;
00301
00306 virtual std::string longID( const std::string& valueId = "val" ) const;
00307
00315 virtual void trimFlag( std::string& flag, std::string& value ) const;
00316
00323 bool _hasBlanks( const std::string& s ) const;
00324
00330 void setRequireLabel( const std::string& s );
00331
00332 };
00333
00337 typedef std::list<Arg*>::iterator ArgIterator;
00338 typedef std::vector<Arg*>::iterator ArgVectorIterator;
00339
00341
00343
00344 inline Arg::Arg(const std::string& flag,
00345 const std::string& name,
00346 const std::string& desc,
00347 bool req,
00348 bool valreq,
00349 Visitor* v) :
00350 _flag(flag),
00351 _name(name),
00352 _description(desc),
00353 _required(req),
00354 _requireLabel("required"),
00355 _valueRequired(valreq),
00356 _alreadySet(false),
00357 _visitor( v ),
00358 _ignoreable(true),
00359 _xorSet(false)
00360 {
00361 if ( _flag.length() > 1 )
00362 throw(SpecificationException(
00363 "Argument flag can only be one character long", toString() ) );
00364
00365 if ( _name != ignoreNameString() &&
00366 ( _flag == Arg::flagStartString() ||
00367 _flag == Arg::nameStartString() ||
00368 _flag == " " ) )
00369 throw(SpecificationException("Argument flag cannot be either '" +
00370 Arg::flagStartString() + "' or '" +
00371 Arg::nameStartString() + "' or a space.",
00372 toString() ) );
00373
00374 if ( ( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) ||
00375 ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) ||
00376 ( _name.find( " ", 0 ) != std::string::npos ) )
00377 throw(SpecificationException("Argument name cannot contain either '" +
00378 Arg::flagStartString() + "' or '" +
00379 Arg::nameStartString() + "' or space.",
00380 toString() ) );
00381
00382 }
00383
00384 inline Arg::~Arg() { }
00385
00386 inline std::string Arg::shortID( const std::string& valueId ) const
00387 {
00388 std::string id = "";
00389
00390 if ( _flag != "" )
00391 id = Arg::flagStartString() + _flag;
00392 else
00393 id = Arg::nameStartString() + _name;
00394
00395 std::string delim = " ";
00396 delim[0] = Arg::delimiter();
00397
00398 if ( _valueRequired )
00399 id += delim + "<" + valueId + ">";
00400
00401 if ( !_required )
00402 id = "[" + id + "]";
00403
00404 return id;
00405 }
00406
00407 inline std::string Arg::longID( const std::string& valueId ) const
00408 {
00409 std::string id = "";
00410
00411 if ( _flag != "" )
00412 {
00413 id += Arg::flagStartString() + _flag;
00414
00415 if ( _valueRequired )
00416 id += " <" + valueId + ">";
00417
00418 id += ", ";
00419 }
00420
00421 id += Arg::nameStartString() + _name;
00422
00423 if ( _valueRequired )
00424 id += " <" + valueId + ">";
00425
00426 return id;
00427
00428 }
00429
00430 inline bool Arg::operator==(const Arg& a)
00431 {
00432 if ( ( _flag != "" && _flag == a._flag ) ||
00433 _name == a._name ||
00434 _description == a._description )
00435 return true;
00436 else
00437 return false;
00438 }
00439
00440 inline std::string Arg::getDescription() const
00441 {
00442 std::string desc = "";
00443 if ( _required )
00444 desc = "(" + _requireLabel + ") ";
00445
00446 if ( _valueRequired )
00447 desc += "(value required) ";
00448
00449 desc += _description;
00450 return desc;
00451 }
00452
00453 inline const std::string& Arg::getFlag() const { return _flag; }
00454
00455 inline const std::string& Arg::getName() const { return _name; }
00456
00457 inline bool Arg::isRequired() const { return _required; }
00458
00459 inline bool Arg::isValueRequired() const { return _valueRequired; }
00460
00461 inline bool Arg::isSet() const
00462 {
00463 if ( _alreadySet && !_xorSet )
00464 return true;
00465 else
00466 return false;
00467 }
00468
00469 inline bool Arg::isIgnoreable() const { return _ignoreable; }
00470
00471 inline void Arg::setRequireLabel( const std::string& s)
00472 {
00473 _requireLabel = s;
00474 }
00475
00476 inline bool Arg::argMatches( const std::string& argFlag ) const
00477 {
00478 if ( argFlag == Arg::flagStartString() + _flag ||
00479 argFlag == Arg::nameStartString() + _name )
00480 return true;
00481 else
00482 return false;
00483 }
00484
00485 inline std::string Arg::toString() const
00486 {
00487 std::string s = "";
00488
00489 if ( _flag != "" )
00490 s += Arg::flagStartString() + _flag + " ";
00491
00492 s += "(" + Arg::nameStartString() + _name + ")";
00493
00494 return s;
00495 }
00496
00497 inline void Arg::_checkWithVisitor() const
00498 {
00499 if ( _visitor != NULL )
00500 _visitor->visit();
00501 }
00502
00506 inline void Arg::trimFlag(std::string& flag, std::string& value) const
00507 {
00508 int stop = 0;
00509 for ( int i = 0; (unsigned int)i < flag.length(); i++ )
00510 if ( flag[i] == delimiter() )
00511 {
00512 stop = i;
00513 break;
00514 }
00515
00516 if ( stop > 1 )
00517 {
00518 value = flag.substr(stop+1);
00519 flag = flag.substr(0,stop);
00520 }
00521
00522 }
00523
00527 inline bool Arg::_hasBlanks( const std::string& s ) const
00528 {
00529 for ( int i = 1; (unsigned int)i < s.length(); i++ )
00530 if ( s[i] == Arg::blankChar() )
00531 return true;
00532
00533 return false;
00534 }
00535
00536 inline void Arg::forceRequired()
00537 {
00538 _required = true;
00539 }
00540
00541 inline void Arg::xorSet()
00542 {
00543 _alreadySet = true;
00544 _xorSet = true;
00545 }
00546
00550 inline void Arg::addToList( std::list<Arg*>& argList ) const
00551 {
00552 argList.push_front( (Arg*)this );
00553 }
00554
00556
00558
00559 }
00560
00561 #endif
00562