00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef TCLAP_ARGUMENT_H
00026 #define TCLAP_ARGUMENT_H
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #else
00031 #define HAVE_SSTREAM
00032 #endif
00033
00034 #include <string>
00035 #include <vector>
00036 #include <list>
00037 #include <iostream>
00038 #include <iomanip>
00039 #include <cstdio>
00040
00041 #if defined(HAVE_SSTREAM)
00042 #include <sstream>
00043 typedef std::istringstream istringstream;
00044 #elif defined(HAVE_STRSTREAM)
00045 #include <strstream>
00046 typedef std::istrstream istringstream;
00047 #else
00048 #error "Need a stringstream (sstream or strstream) to compile!"
00049 #endif
00050
00051 #include <tclap/ArgException.h>
00052 #include <tclap/Visitor.h>
00053 #include <tclap/CmdLineInterface.h>
00054 #include <tclap/ArgTraits.h>
00055 #include <tclap/StandardTraits.h>
00056
00057 namespace TCLAP {
00058
00064 class Arg
00065 {
00066 private:
00067
00071 static bool& ignoreRestRef() { static bool ign = false; return ign; }
00072
00077 static char& delimiterRef() { static char delim = ' '; return delim; }
00078
00079 protected:
00080
00089 std::string _flag;
00090
00098 std::string _name;
00099
00103 std::string _description;
00104
00108 bool _required;
00109
00114 std::string _requireLabel;
00115
00121 bool _valueRequired;
00122
00128 bool _alreadySet;
00129
00136 Visitor* _visitor;
00137
00141 bool _ignoreable;
00142
00147 bool _xorSet;
00148
00149 bool _acceptsMultipleValues;
00150
00154 void _checkWithVisitor() const;
00155
00169 Arg( const std::string& flag,
00170 const std::string& name,
00171 const std::string& desc,
00172 bool req,
00173 bool valreq,
00174 Visitor* v = NULL );
00175
00176 public:
00180 virtual ~Arg();
00181
00186 virtual void addToList( std::list<Arg*>& argList ) const;
00187
00191 static void beginIgnoring() { ignoreRestRef() = true; }
00192
00196 static bool ignoreRest() { return ignoreRestRef(); }
00197
00202 static char delimiter() { return delimiterRef(); }
00203
00208 static char blankChar() { return (char)7; }
00209
00213 static char flagStartChar() { return '-'; }
00214
00219 static const std::string flagStartString() { return "-"; }
00220
00225 static const std::string nameStartString() { return "--"; }
00226
00230 static const std::string ignoreNameString() { return "ignore_rest"; }
00231
00236 static void setDelimiter( char c ) { delimiterRef() = c; }
00237
00245 virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
00246
00252 virtual bool operator==(const Arg& a) const;
00253
00257 const std::string& getFlag() const;
00258
00262 const std::string& getName() const;
00263
00267 std::string getDescription() const;
00268
00272 virtual bool isRequired() const;
00273
00278 void forceRequired();
00279
00284 void xorSet();
00285
00289 bool isValueRequired() const;
00290
00295 bool isSet() const;
00296
00300 bool isIgnoreable() const;
00301
00310 virtual bool argMatches( const std::string& s ) const;
00311
00316 virtual std::string toString() const;
00317
00322 virtual std::string shortID( const std::string& valueId = "val" ) const;
00323
00328 virtual std::string longID( const std::string& valueId = "val" ) const;
00329
00337 virtual void trimFlag( std::string& flag, std::string& value ) const;
00338
00345 bool _hasBlanks( const std::string& s ) const;
00346
00352 void setRequireLabel( const std::string& s );
00353
00358 virtual bool allowMore();
00359
00364 virtual bool acceptsMultipleValues();
00365
00370 virtual void reset();
00371 };
00372
00376 typedef std::list<Arg*>::iterator ArgListIterator;
00377
00381 typedef std::vector<Arg*>::iterator ArgVectorIterator;
00382
00386 typedef std::list<Visitor*>::iterator VisitorListIterator;
00387
00388
00389
00390
00391
00392
00393
00394 template<typename T> void
00395 ExtractValue(T &destVal, const std::string& strVal, ValueLike vl)
00396 {
00397 static_cast<void>(vl);
00398 std::istringstream is(strVal);
00399
00400 int valuesRead = 0;
00401 while ( is.good() ) {
00402 if ( is.peek() != EOF )
00403 #ifdef TCLAP_SETBASE_ZERO
00404 is >> std::setbase(0) >> destVal;
00405 #else
00406 is >> destVal;
00407 #endif
00408 else
00409 break;
00410
00411 valuesRead++;
00412 }
00413
00414 if ( is.fail() )
00415 throw( ArgParseException("Couldn't read argument value "
00416 "from string '" + strVal + "'"));
00417
00418
00419 if ( valuesRead > 1 )
00420 throw( ArgParseException("More than one valid value parsed from "
00421 "string '" + strVal + "'"));
00422
00423 }
00424
00425
00426
00427
00428
00429
00430
00431 template<typename T> void
00432 ExtractValue(T &destVal, const std::string& strVal, StringLike sl)
00433 {
00434 static_cast<void>(sl);
00435 SetString(destVal, strVal);
00436 }
00437
00439
00441
00442 inline Arg::Arg(const std::string& flag,
00443 const std::string& name,
00444 const std::string& desc,
00445 bool req,
00446 bool valreq,
00447 Visitor* v) :
00448 _flag(flag),
00449 _name(name),
00450 _description(desc),
00451 _required(req),
00452 _requireLabel("required"),
00453 _valueRequired(valreq),
00454 _alreadySet(false),
00455 _visitor( v ),
00456 _ignoreable(true),
00457 _xorSet(false),
00458 _acceptsMultipleValues(false)
00459 {
00460 if ( _flag.length() > 1 )
00461 throw(SpecificationException(
00462 "Argument flag can only be one character long", toString() ) );
00463
00464 if ( _name != ignoreNameString() &&
00465 ( _flag == Arg::flagStartString() ||
00466 _flag == Arg::nameStartString() ||
00467 _flag == " " ) )
00468 throw(SpecificationException("Argument flag cannot be either '" +
00469 Arg::flagStartString() + "' or '" +
00470 Arg::nameStartString() + "' or a space.",
00471 toString() ) );
00472
00473 if ( ( _name.substr( 0, Arg::flagStartString().length() ) == Arg::flagStartString() ) ||
00474 ( _name.substr( 0, Arg::nameStartString().length() ) == Arg::nameStartString() ) ||
00475 ( _name.find( " ", 0 ) != std::string::npos ) )
00476 throw(SpecificationException("Argument name begin with either '" +
00477 Arg::flagStartString() + "' or '" +
00478 Arg::nameStartString() + "' or space.",
00479 toString() ) );
00480
00481 }
00482
00483 inline Arg::~Arg() { }
00484
00485 inline std::string Arg::shortID( const std::string& valueId ) const
00486 {
00487 std::string id = "";
00488
00489 if ( _flag != "" )
00490 id = Arg::flagStartString() + _flag;
00491 else
00492 id = Arg::nameStartString() + _name;
00493
00494 if ( _valueRequired )
00495 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
00496
00497 if ( !_required )
00498 id = "[" + id + "]";
00499
00500 return id;
00501 }
00502
00503 inline std::string Arg::longID( const std::string& valueId ) const
00504 {
00505 std::string id = "";
00506
00507 if ( _flag != "" )
00508 {
00509 id += Arg::flagStartString() + _flag;
00510
00511 if ( _valueRequired )
00512 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
00513
00514 id += ", ";
00515 }
00516
00517 id += Arg::nameStartString() + _name;
00518
00519 if ( _valueRequired )
00520 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
00521
00522 return id;
00523
00524 }
00525
00526 inline bool Arg::operator==(const Arg& a) const
00527 {
00528 if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
00529 return true;
00530 else
00531 return false;
00532 }
00533
00534 inline std::string Arg::getDescription() const
00535 {
00536 std::string desc = "";
00537 if ( _required )
00538 desc = "(" + _requireLabel + ") ";
00539
00540
00541
00542
00543 desc += _description;
00544 return desc;
00545 }
00546
00547 inline const std::string& Arg::getFlag() const { return _flag; }
00548
00549 inline const std::string& Arg::getName() const { return _name; }
00550
00551 inline bool Arg::isRequired() const { return _required; }
00552
00553 inline bool Arg::isValueRequired() const { return _valueRequired; }
00554
00555 inline bool Arg::isSet() const
00556 {
00557 if ( _alreadySet && !_xorSet )
00558 return true;
00559 else
00560 return false;
00561 }
00562
00563 inline bool Arg::isIgnoreable() const { return _ignoreable; }
00564
00565 inline void Arg::setRequireLabel( const std::string& s)
00566 {
00567 _requireLabel = s;
00568 }
00569
00570 inline bool Arg::argMatches( const std::string& argFlag ) const
00571 {
00572 if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
00573 argFlag == Arg::nameStartString() + _name )
00574 return true;
00575 else
00576 return false;
00577 }
00578
00579 inline std::string Arg::toString() const
00580 {
00581 std::string s = "";
00582
00583 if ( _flag != "" )
00584 s += Arg::flagStartString() + _flag + " ";
00585
00586 s += "(" + Arg::nameStartString() + _name + ")";
00587
00588 return s;
00589 }
00590
00591 inline void Arg::_checkWithVisitor() const
00592 {
00593 if ( _visitor != NULL )
00594 _visitor->visit();
00595 }
00596
00600 inline void Arg::trimFlag(std::string& flag, std::string& value) const
00601 {
00602 int stop = 0;
00603 for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
00604 if ( flag[i] == Arg::delimiter() )
00605 {
00606 stop = i;
00607 break;
00608 }
00609
00610 if ( stop > 1 )
00611 {
00612 value = flag.substr(stop+1);
00613 flag = flag.substr(0,stop);
00614 }
00615
00616 }
00617
00621 inline bool Arg::_hasBlanks( const std::string& s ) const
00622 {
00623 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00624 if ( s[i] == Arg::blankChar() )
00625 return true;
00626
00627 return false;
00628 }
00629
00630 inline void Arg::forceRequired()
00631 {
00632 _required = true;
00633 }
00634
00635 inline void Arg::xorSet()
00636 {
00637 _alreadySet = true;
00638 _xorSet = true;
00639 }
00640
00644 inline void Arg::addToList( std::list<Arg*>& argList ) const
00645 {
00646 argList.push_front( const_cast<Arg*>(this) );
00647 }
00648
00649 inline bool Arg::allowMore()
00650 {
00651 return false;
00652 }
00653
00654 inline bool Arg::acceptsMultipleValues()
00655 {
00656 return _acceptsMultipleValues;
00657 }
00658
00659 inline void Arg::reset()
00660 {
00661 _xorSet = false;
00662 _alreadySet = false;
00663 }
00664
00666
00668
00669 }
00670
00671 #endif
00672