tclap: Arg.h Source File

Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

# Arg.h

Go to the documentation of this file.

    00001 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
    00002
    00003 /******************************************************************************
    00004  *
    00005  *  file:  Arg.h
    00006  *
    00007  *  Copyright (c) 2003, Michael E. Smoot .
    00008  *  Copyright (c) 2004, Michael E. Smoot, Daniel Aarno .
    00009  *  All rights reverved.
    00010  *
    00011  *  See the file COPYING in the top directory of this distribution for
    00012  *  more information.
    00013  *
    00014  *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
    00015  *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00016  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    00017  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00018  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    00019  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    00020  *  DEALINGS IN THE SOFTWARE.
    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  * Extract a value of type T from it's string representation contained
    00390  * in strVal. The ValueLike parameter used to select the correct
    00391  * specialization of ExtractValue depending on the value traits of T.
    00392  * ValueLike traits use operator>> to assign the value from strVal.
    00393  */
    00394 template<typename T> void
    00395 ExtractValue(T &destVal, const std::string& strVal, ValueLike vl)
    00396 {
    00397     static_cast<void>(vl); // Avoid warning about unused 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  * Extract a value of type T from it's string representation contained
    00427  * in strVal. The ValueLike parameter used to select the correct
    00428  * specialization of ExtractValue depending on the value traits of T.
    00429  * StringLike uses assignment (operator=) to assign from strVal.
    00430  */
    00431 template<typename T> void
    00432 ExtractValue(T &destVal, const std::string& strVal, StringLike sl)
    00433 {
    00434     static_cast<void>(sl); // Avoid warning about unused sl
    00435     SetString(destVal, strVal);
    00436 }
    00437
    00439 //BEGIN Arg.cpp
    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 //  if ( _valueRequired )
    00541 //      desc += "(value required)  ";
    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 //END Arg.cpp
    00668
    00669 } //namespace TCLAP
    00670
    00671 #endif
    00672