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:
00070 Arg(const Arg& rhs);
00071
00075 Arg& operator=(const Arg& rhs);
00076
00080 static bool& ignoreRestRef() { static bool ign = false; return ign; }
00081
00086 static char& delimiterRef() { static char delim = ' '; return delim; }
00087
00088 protected:
00089
00098 std::string _flag;
00099
00107 std::string _name;
00108
00112 std::string _description;
00113
00117 bool _required;
00118
00123 std::string _requireLabel;
00124
00130 bool _valueRequired;
00131
00137 bool _alreadySet;
00138
00145 Visitor* _visitor;
00146
00150 bool _ignoreable;
00151
00156 bool _xorSet;
00157
00158 bool _acceptsMultipleValues;
00159
00163 void _checkWithVisitor() const;
00164
00178 Arg( const std::string& flag,
00179 const std::string& name,
00180 const std::string& desc,
00181 bool req,
00182 bool valreq,
00183 Visitor* v = NULL );
00184
00185 public:
00189 virtual ~Arg();
00190
00195 virtual void addToList( std::list<Arg*>& argList ) const;
00196
00200 static void beginIgnoring() { ignoreRestRef() = true; }
00201
00205 static bool ignoreRest() { return ignoreRestRef(); }
00206
00211 static char delimiter() { return delimiterRef(); }
00212
00217 static char blankChar() { return (char)7; }
00218
00223 #ifndef TCLAP_FLAGSTARTCHAR
00224 #define TCLAP_FLAGSTARTCHAR '-'
00225 #endif
00226 static char flagStartChar() { return TCLAP_FLAGSTARTCHAR; }
00227
00233 #ifndef TCLAP_FLAGSTARTSTRING
00234 #define TCLAP_FLAGSTARTSTRING "-"
00235 #endif
00236 static const std::string flagStartString() { return TCLAP_FLAGSTARTSTRING; }
00237
00242 #ifndef TCLAP_NAMESTARTSTRING
00243 #define TCLAP_NAMESTARTSTRING "--"
00244 #endif
00245 static const std::string nameStartString() { return TCLAP_NAMESTARTSTRING; }
00246
00250 static const std::string ignoreNameString() { return "ignore_rest"; }
00251
00256 static void setDelimiter( char c ) { delimiterRef() = c; }
00257
00265 virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
00266
00272 virtual bool operator==(const Arg& a) const;
00273
00277 const std::string& getFlag() const;
00278
00282 const std::string& getName() const;
00283
00287 std::string getDescription() const;
00288
00292 virtual bool isRequired() const;
00293
00298 void forceRequired();
00299
00304 void xorSet();
00305
00309 bool isValueRequired() const;
00310
00315 bool isSet() const;
00316
00320 bool isIgnoreable() const;
00321
00330 virtual bool argMatches( const std::string& s ) const;
00331
00336 virtual std::string toString() const;
00337
00342 virtual std::string shortID( const std::string& valueId = "val" ) const;
00343
00348 virtual std::string longID( const std::string& valueId = "val" ) const;
00349
00357 virtual void trimFlag( std::string& flag, std::string& value ) const;
00358
00365 bool _hasBlanks( const std::string& s ) const;
00366
00372 void setRequireLabel( const std::string& s );
00373
00378 virtual bool allowMore();
00379
00384 virtual bool acceptsMultipleValues();
00385
00390 virtual void reset();
00391 };
00392
00396 typedef std::list<Arg*>::iterator ArgListIterator;
00397
00401 typedef std::vector<Arg*>::iterator ArgVectorIterator;
00402
00406 typedef std::list<Visitor*>::iterator VisitorListIterator;
00407
00408
00409
00410
00411
00412
00413
00414 template<typename T> void
00415 ExtractValue(T &destVal, const std::string& strVal, ValueLike vl)
00416 {
00417 static_cast<void>(vl);
00418 std::istringstream is(strVal);
00419
00420 int valuesRead = 0;
00421 while ( is.good() ) {
00422 if ( is.peek() != EOF )
00423 #ifdef TCLAP_SETBASE_ZERO
00424 is >> std::setbase(0) >> destVal;
00425 #else
00426 is >> destVal;
00427 #endif
00428 else
00429 break;
00430
00431 valuesRead++;
00432 }
00433
00434 if ( is.fail() )
00435 throw( ArgParseException("Couldn't read argument value "
00436 "from string '" + strVal + "'"));
00437
00438
00439 if ( valuesRead > 1 )
00440 throw( ArgParseException("More than one valid value parsed from "
00441 "string '" + strVal + "'"));
00442
00443 }
00444
00445
00446
00447
00448
00449
00450
00451 template<typename T> void
00452 ExtractValue(T &destVal, const std::string& strVal, StringLike sl)
00453 {
00454 static_cast<void>(sl);
00455 SetString(destVal, strVal);
00456 }
00457
00459
00461
00462 inline Arg::Arg(const std::string& flag,
00463 const std::string& name,
00464 const std::string& desc,
00465 bool req,
00466 bool valreq,
00467 Visitor* v) :
00468 _flag(flag),
00469 _name(name),
00470 _description(desc),
00471 _required(req),
00472 _requireLabel("required"),
00473 _valueRequired(valreq),
00474 _alreadySet(false),
00475 _visitor( v ),
00476 _ignoreable(true),
00477 _xorSet(false),
00478 _acceptsMultipleValues(false)
00479 {
00480 if ( _flag.length() > 1 )
00481 throw(SpecificationException(
00482 "Argument flag can only be one character long", toString() ) );
00483
00484 if ( _name != ignoreNameString() &&
00485 ( _flag == Arg::flagStartString() ||
00486 _flag == Arg::nameStartString() ||
00487 _flag == " " ) )
00488 throw(SpecificationException("Argument flag cannot be either '" +
00489 Arg::flagStartString() + "' or '" +
00490 Arg::nameStartString() + "' or a space.",
00491 toString() ) );
00492
00493 if ( ( _name.substr( 0, Arg::flagStartString().length() ) == Arg::flagStartString() ) ||
00494 ( _name.substr( 0, Arg::nameStartString().length() ) == Arg::nameStartString() ) ||
00495 ( _name.find( " ", 0 ) != std::string::npos ) )
00496 throw(SpecificationException("Argument name begin with either '" +
00497 Arg::flagStartString() + "' or '" +
00498 Arg::nameStartString() + "' or space.",
00499 toString() ) );
00500
00501 }
00502
00503 inline Arg::~Arg() { }
00504
00505 inline std::string Arg::shortID( const std::string& valueId ) const
00506 {
00507 std::string id = "";
00508
00509 if ( _flag != "" )
00510 id = Arg::flagStartString() + _flag;
00511 else
00512 id = Arg::nameStartString() + _name;
00513
00514 if ( _valueRequired )
00515 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
00516
00517 if ( !_required )
00518 id = "[" + id + "]";
00519
00520 return id;
00521 }
00522
00523 inline std::string Arg::longID( const std::string& valueId ) const
00524 {
00525 std::string id = "";
00526
00527 if ( _flag != "" )
00528 {
00529 id += Arg::flagStartString() + _flag;
00530
00531 if ( _valueRequired )
00532 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
00533
00534 id += ", ";
00535 }
00536
00537 id += Arg::nameStartString() + _name;
00538
00539 if ( _valueRequired )
00540 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
00541
00542 return id;
00543
00544 }
00545
00546 inline bool Arg::operator==(const Arg& a) const
00547 {
00548 if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
00549 return true;
00550 else
00551 return false;
00552 }
00553
00554 inline std::string Arg::getDescription() const
00555 {
00556 std::string desc = "";
00557 if ( _required )
00558 desc = "(" + _requireLabel + ") ";
00559
00560
00561
00562
00563 desc += _description;
00564 return desc;
00565 }
00566
00567 inline const std::string& Arg::getFlag() const { return _flag; }
00568
00569 inline const std::string& Arg::getName() const { return _name; }
00570
00571 inline bool Arg::isRequired() const { return _required; }
00572
00573 inline bool Arg::isValueRequired() const { return _valueRequired; }
00574
00575 inline bool Arg::isSet() const
00576 {
00577 if ( _alreadySet && !_xorSet )
00578 return true;
00579 else
00580 return false;
00581 }
00582
00583 inline bool Arg::isIgnoreable() const { return _ignoreable; }
00584
00585 inline void Arg::setRequireLabel( const std::string& s)
00586 {
00587 _requireLabel = s;
00588 }
00589
00590 inline bool Arg::argMatches( const std::string& argFlag ) const
00591 {
00592 if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
00593 argFlag == Arg::nameStartString() + _name )
00594 return true;
00595 else
00596 return false;
00597 }
00598
00599 inline std::string Arg::toString() const
00600 {
00601 std::string s = "";
00602
00603 if ( _flag != "" )
00604 s += Arg::flagStartString() + _flag + " ";
00605
00606 s += "(" + Arg::nameStartString() + _name + ")";
00607
00608 return s;
00609 }
00610
00611 inline void Arg::_checkWithVisitor() const
00612 {
00613 if ( _visitor != NULL )
00614 _visitor->visit();
00615 }
00616
00620 inline void Arg::trimFlag(std::string& flag, std::string& value) const
00621 {
00622 int stop = 0;
00623 for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
00624 if ( flag[i] == Arg::delimiter() )
00625 {
00626 stop = i;
00627 break;
00628 }
00629
00630 if ( stop > 1 )
00631 {
00632 value = flag.substr(stop+1);
00633 flag = flag.substr(0,stop);
00634 }
00635
00636 }
00637
00641 inline bool Arg::_hasBlanks( const std::string& s ) const
00642 {
00643 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00644 if ( s[i] == Arg::blankChar() )
00645 return true;
00646
00647 return false;
00648 }
00649
00650 inline void Arg::forceRequired()
00651 {
00652 _required = true;
00653 }
00654
00655 inline void Arg::xorSet()
00656 {
00657 _alreadySet = true;
00658 _xorSet = true;
00659 }
00660
00664 inline void Arg::addToList( std::list<Arg*>& argList ) const
00665 {
00666 argList.push_front( const_cast<Arg*>(this) );
00667 }
00668
00669 inline bool Arg::allowMore()
00670 {
00671 return false;
00672 }
00673
00674 inline bool Arg::acceptsMultipleValues()
00675 {
00676 return _acceptsMultipleValues;
00677 }
00678
00679 inline void Arg::reset()
00680 {
00681 _xorSet = false;
00682 _alreadySet = false;
00683 }
00684
00686
00688
00689 }
00690
00691 #endif
00692