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 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00037 namespace TCLAP {
00038
00045 class Arg
00046 {
00047 private:
00048
00052 static bool& ignoreRestRef() { static bool ign = false; return ign; }
00053
00058 static char& delimiterRef() { static char delim = ' '; return delim; }
00059
00060 protected:
00061
00070 std::string _flag;
00071
00079 std::string _name;
00080
00084 std::string _description;
00085
00089 bool _required;
00090
00095 std::string _requireLabel;
00096
00102 bool _valueRequired;
00103
00109 bool _alreadySet;
00110
00117 Visitor* _visitor;
00118
00122 bool _ignoreable;
00123
00128 bool _xorSet;
00129
00130 bool _acceptsMultipleValues;
00131
00135 void _checkWithVisitor() const;
00136
00150 Arg( const std::string& flag,
00151 const std::string& name,
00152 const std::string& desc,
00153 bool req,
00154 bool valreq,
00155 Visitor* v = NULL );
00156
00157 public:
00161 virtual ~Arg();
00162
00167 virtual void addToList( std::list<Arg*>& argList ) const;
00168
00172 static void beginIgnoring() { ignoreRestRef() = true; }
00173
00177 static bool ignoreRest() { return ignoreRestRef(); }
00178
00183 static char delimiter() { return delimiterRef(); }
00184
00190 static const char blankChar() { return '*'; }
00191
00195 static const char flagStartChar() { return '-'; }
00196
00201 static const std::string flagStartString() { return "-"; }
00202
00207 static const std::string nameStartString() { return "--"; }
00208
00212 static const std::string ignoreNameString() { return "ignore_rest"; }
00213
00218 static void setDelimiter( char c ) { delimiterRef() = c; }
00219
00227 virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
00228
00234 virtual bool operator==(const Arg& a) const;
00235
00239 const std::string& getFlag() const;
00240
00244 const std::string& getName() const;
00245
00249 std::string getDescription() const;
00250
00254 virtual bool isRequired() const;
00255
00260 void forceRequired();
00261
00266 void xorSet();
00267
00271 bool isValueRequired() const;
00272
00277 bool isSet() const;
00278
00282 bool isIgnoreable() const;
00283
00292 virtual bool argMatches( const std::string& s ) const;
00293
00298 virtual std::string toString() const;
00299
00304 virtual std::string shortID( const std::string& valueId = "val" ) const;
00305
00310 virtual std::string longID( const std::string& valueId = "val" ) const;
00311
00319 virtual void trimFlag( std::string& flag, std::string& value ) const;
00320
00327 bool _hasBlanks( const std::string& s ) const;
00328
00334 void setRequireLabel( const std::string& s );
00335
00336 virtual bool allowMore();
00337 virtual bool acceptsMultipleValues();
00338
00339 };
00340
00344 typedef std::list<Arg*>::iterator ArgListIterator;
00345
00349 typedef std::vector<Arg*>::iterator ArgVectorIterator;
00350
00354 typedef std::list<Visitor*>::iterator VisitorListIterator;
00355
00356
00358
00360
00361 inline Arg::Arg(const std::string& flag,
00362 const std::string& name,
00363 const std::string& desc,
00364 bool req,
00365 bool valreq,
00366 Visitor* v) :
00367 _flag(flag),
00368 _name(name),
00369 _description(desc),
00370 _required(req),
00371 _requireLabel("required"),
00372 _valueRequired(valreq),
00373 _alreadySet(false),
00374 _visitor( v ),
00375 _ignoreable(true),
00376 _xorSet(false),
00377 _acceptsMultipleValues(false)
00378 {
00379 if ( _flag.length() > 1 )
00380 throw(SpecificationException(
00381 "Argument flag can only be one character long", toString() ) );
00382
00383 if ( _name != ignoreNameString() &&
00384 ( _flag == Arg::flagStartString() ||
00385 _flag == Arg::nameStartString() ||
00386 _flag == " " ) )
00387 throw(SpecificationException("Argument flag cannot be either '" +
00388 Arg::flagStartString() + "' or '" +
00389 Arg::nameStartString() + "' or a space.",
00390 toString() ) );
00391
00392 _name.find("--");
00393 if ( ( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) ||
00394 ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) ||
00395 ( _name.find( " ", 0 ) != std::string::npos ) )
00396 throw(SpecificationException("Argument name cannot contain either '" +
00397 Arg::flagStartString() + "' or '" +
00398 Arg::nameStartString() + "' or space.",
00399 toString() ) );
00400
00401 }
00402
00403 inline Arg::~Arg() { }
00404
00405 inline std::string Arg::shortID( const std::string& valueId ) const
00406 {
00407 std::string id = "";
00408
00409 if ( _flag != "" )
00410 id = Arg::flagStartString() + _flag;
00411 else
00412 id = Arg::nameStartString() + _name;
00413
00414 std::string delim = " ";
00415 delim[0] = Arg::delimiter();
00416
00417 if ( _valueRequired )
00418 id += delim + "<" + valueId + ">";
00419
00420 if ( !_required )
00421 id = "[" + id + "]";
00422
00423 return id;
00424 }
00425
00426 inline std::string Arg::longID( const std::string& valueId ) const
00427 {
00428 std::string id = "";
00429
00430 if ( _flag != "" )
00431 {
00432 id += Arg::flagStartString() + _flag;
00433
00434 if ( _valueRequired )
00435 id += " <" + valueId + ">";
00436
00437 id += ", ";
00438 }
00439
00440 id += Arg::nameStartString() + _name;
00441
00442 if ( _valueRequired )
00443 id += " <" + valueId + ">";
00444
00445 return id;
00446
00447 }
00448
00449 inline bool Arg::operator==(const Arg& a) const
00450 {
00451 if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
00452 return true;
00453 else
00454 return false;
00455 }
00456
00457 inline std::string Arg::getDescription() const
00458 {
00459 std::string desc = "";
00460 if ( _required )
00461 desc = "(" + _requireLabel + ") ";
00462
00463
00464
00465
00466 desc += _description;
00467 return desc;
00468 }
00469
00470 inline const std::string& Arg::getFlag() const { return _flag; }
00471
00472 inline const std::string& Arg::getName() const { return _name; }
00473
00474 inline bool Arg::isRequired() const { return _required; }
00475
00476 inline bool Arg::isValueRequired() const { return _valueRequired; }
00477
00478 inline bool Arg::isSet() const
00479 {
00480 if ( _alreadySet && !_xorSet )
00481 return true;
00482 else
00483 return false;
00484 }
00485
00486 inline bool Arg::isIgnoreable() const { return _ignoreable; }
00487
00488 inline void Arg::setRequireLabel( const std::string& s)
00489 {
00490 _requireLabel = s;
00491 }
00492
00493 inline bool Arg::argMatches( const std::string& argFlag ) const
00494 {
00495 if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
00496 argFlag == Arg::nameStartString() + _name )
00497 return true;
00498 else
00499 return false;
00500 }
00501
00502 inline std::string Arg::toString() const
00503 {
00504 std::string s = "";
00505
00506 if ( _flag != "" )
00507 s += Arg::flagStartString() + _flag + " ";
00508
00509 s += "(" + Arg::nameStartString() + _name + ")";
00510
00511 return s;
00512 }
00513
00514 inline void Arg::_checkWithVisitor() const
00515 {
00516 if ( _visitor != NULL )
00517 _visitor->visit();
00518 }
00519
00523 inline void Arg::trimFlag(std::string& flag, std::string& value) const
00524 {
00525 int stop = 0;
00526 for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
00527 if ( flag[i] == Arg::delimiter() )
00528 {
00529 stop = i;
00530 break;
00531 }
00532
00533 if ( stop > 1 )
00534 {
00535 value = flag.substr(stop+1);
00536 flag = flag.substr(0,stop);
00537 }
00538
00539 }
00540
00544 inline bool Arg::_hasBlanks( const std::string& s ) const
00545 {
00546 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00547 if ( s[i] == Arg::blankChar() )
00548 return true;
00549
00550 return false;
00551 }
00552
00553 inline void Arg::forceRequired()
00554 {
00555 _required = true;
00556 }
00557
00558 inline void Arg::xorSet()
00559 {
00560 _alreadySet = true;
00561 _xorSet = true;
00562 }
00563
00567 inline void Arg::addToList( std::list<Arg*>& argList ) const
00568 {
00569 argList.push_front( const_cast<Arg*>(this) );
00570 }
00571
00572 inline bool Arg::allowMore()
00573 {
00574 return false;
00575 }
00576
00577 inline bool Arg::acceptsMultipleValues()
00578 {
00579 return _acceptsMultipleValues;
00580 }
00581
00583
00585
00586 }
00587 #endif
00588
00589
00590 #endif
00591