- Main Page
- Namespaces
- Classes
- Files

- File List
- 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:
    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  * Extract a value of type T from it's string representation contained
    00410  * in strVal. The ValueLike parameter used to select the correct
    00411  * specialization of ExtractValue depending on the value traits of T.
    00412  * ValueLike traits use operator>> to assign the value from strVal.
    00413  */
    00414 template<typename T> void
    00415 ExtractValue(T &destVal, const std::string& strVal, ValueLike vl)
    00416 {
    00417     static_cast<void>(vl); // Avoid warning about unused 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  * Extract a value of type T from it's string representation contained
    00447  * in strVal. The ValueLike parameter used to select the correct
    00448  * specialization of ExtractValue depending on the value traits of T.
    00449  * StringLike uses assignment (operator=) to assign from strVal.
    00450  */
    00451 template<typename T> void
    00452 ExtractValue(T &destVal, const std::string& strVal, StringLike sl)
    00453 {
    00454     static_cast<void>(sl); // Avoid warning about unused sl
    00455     SetString(destVal, strVal);
    00456 }
    00457
    00459 //BEGIN Arg.cpp
    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 //  if ( _valueRequired )
    00561 //      desc += "(value required)  ";
    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 //END Arg.cpp
    00688
    00689 } //namespace TCLAP
    00690
    00691 #endif
    00692