UniversalIndentGUI 1.2.0
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines