Arg.h

Go to the documentation of this file.
00001 
00002 /****************************************************************************** 
00003  * 
00004  *  file:  Arg.h
00005  * 
00006  *  Copyright (c) 2003, Michael E. Smoot .
00007  *  Copyright (c) 2004, Michael E. Smoot, Daniel Aarno .
00008  *  All rights reverved.
00009  * 
00010  *  See the file COPYING in the top directory of this distribution for
00011  *  more information.
00012  *  
00013  *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 
00014  *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
00015  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
00016  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
00017  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
00018  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
00019  *  DEALINGS IN THE SOFTWARE.  
00020  *  
00021  *****************************************************************************/ 
00022 
00023 
00024 #ifndef TCLAP_ARGUMENT_H
00025 #define TCLAP_ARGUMENT_H
00026 
00027 #include <string>
00028 #include <vector>
00029 #include <list>
00030 #include <iostream>
00031 
00032 #include <tclap/ArgException.h>
00033 #include <tclap/Visitor.h>
00034 #include <tclap/CmdLineInterface.h>
00035 
00036 namespace TCLAP {
00037 
00043 class Arg
00044 {
00045     private: 
00046 
00050         static bool& ignoreRestRef() { static bool ign = false; return ign; }
00051 
00056         static char& delimiterRef() { static char delim = ' '; return delim; } 
00057 
00058     protected:
00059 
00068         std::string _flag;
00069 
00077         std::string _name;
00078 
00082         std::string _description;
00083 
00087         bool _required;
00088 
00093         std::string _requireLabel;
00094 
00100         bool _valueRequired;
00101 
00107         bool _alreadySet;
00108 
00115         Visitor* _visitor;
00116 
00120         bool _ignoreable;
00121 
00126         bool _xorSet;
00127 
00128         bool _acceptsMultipleValues;
00129 
00133         void _checkWithVisitor() const;
00134 
00148         Arg( const std::string& flag, 
00149              const std::string& name, 
00150              const std::string& desc, 
00151              bool req, 
00152              bool valreq,
00153              Visitor* v = NULL );
00154 
00155     public:
00159         virtual ~Arg();
00160 
00165         virtual void addToList( std::list<Arg*>& argList ) const;
00166         
00170         static void beginIgnoring() { ignoreRestRef() = true; }
00171         
00175         static bool ignoreRest() { return ignoreRestRef(); }
00176 
00181         static char delimiter() { return delimiterRef(); } 
00182         
00188         static const char blankChar() { return '*'; }
00189         
00193         static const char flagStartChar() { return '-'; }
00194         
00199         static const std::string flagStartString() { return "-"; }
00200         
00205         static const std::string nameStartString() { return "--"; }
00206 
00210         static const std::string ignoreNameString() { return "ignore_rest"; }
00211 
00216         static void setDelimiter( char c ) { delimiterRef() = c; }
00217 
00225         virtual bool processArg(int *i, std::vector<std::string>& args) = 0; 
00226 
00232         virtual bool operator==(const Arg& a) const;
00233 
00237         const std::string& getFlag() const;
00238 
00242         const std::string& getName() const;
00243 
00247         std::string getDescription() const;
00248 
00252         virtual bool isRequired() const;
00253 
00258         void forceRequired();
00259 
00264         void xorSet();
00265 
00269         bool isValueRequired() const;
00270 
00275         bool isSet() const;
00276 
00280         bool isIgnoreable() const;
00281 
00290         virtual bool argMatches( const std::string& s ) const;
00291 
00296         virtual std::string toString() const;
00297 
00302         virtual std::string shortID( const std::string& valueId = "val" ) const;
00303 
00308         virtual std::string longID( const std::string& valueId = "val" ) const;
00309 
00317         virtual void trimFlag( std::string& flag, std::string& value ) const;
00318 
00325         bool _hasBlanks( const std::string& s ) const;
00326 
00332         void setRequireLabel( const std::string& s );
00333 
00334         virtual bool allowMore();
00335         virtual bool acceptsMultipleValues();
00336 
00337 };
00338 
00342 typedef std::list<Arg*>::iterator ArgListIterator;
00343 
00347 typedef std::vector<Arg*>::iterator ArgVectorIterator;
00348 
00352 typedef std::list<Visitor*>::iterator VisitorListIterator;
00353 
00354 
00356 //BEGIN Arg.cpp
00358 
00359 inline Arg::Arg(const std::string& flag, 
00360          const std::string& name, 
00361          const std::string& desc, 
00362          bool req, 
00363          bool valreq,
00364          Visitor* v) :
00365   _flag(flag),
00366   _name(name),
00367   _description(desc),
00368   _required(req),
00369   _requireLabel("required"),
00370   _valueRequired(valreq),
00371   _alreadySet(false),
00372   _visitor( v ),
00373   _ignoreable(true),
00374   _xorSet(false),
00375   _acceptsMultipleValues(false)
00376 {
00377     if ( _flag.length() > 1 ) 
00378         throw(SpecificationException(
00379                 "Argument flag can only be one character long", toString() ) );
00380 
00381     if ( _name != ignoreNameString() &&  
00382          ( _flag == Arg::flagStartString() || 
00383            _flag == Arg::nameStartString() || 
00384            _flag == " " ) )
00385         throw(SpecificationException("Argument flag cannot be either '" + 
00386                             Arg::flagStartString() + "' or '" + 
00387                             Arg::nameStartString() + "' or a space.",
00388                             toString() ) );
00389 
00390     if ( ( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) || 
00391          ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) ||
00392          ( _name.find( " ", 0 ) != std::string::npos ) )
00393         throw(SpecificationException("Argument name cannot contain either '" + 
00394                             Arg::flagStartString() + "' or '" + 
00395                             Arg::nameStartString() + "' or space.",
00396                             toString() ) );
00397 
00398 }
00399 
00400 inline Arg::~Arg() { }
00401 
00402 inline std::string Arg::shortID( const std::string& valueId ) const
00403 {
00404     std::string id = "";
00405 
00406     if ( _flag != "" )
00407         id = Arg::flagStartString() + _flag;
00408     else
00409         id = Arg::nameStartString() + _name;
00410 
00411     std::string delim = " "; 
00412     delim[0] = Arg::delimiter(); // ugly!!!
00413     
00414     if ( _valueRequired )
00415         id += delim + "<" + valueId  + ">";
00416 
00417     if ( !_required )
00418         id = "[" + id + "]";
00419 
00420     return id;
00421 }
00422 
00423 inline std::string Arg::longID( const std::string& valueId ) const
00424 {
00425     std::string id = "";
00426 
00427     if ( _flag != "" )
00428     {
00429         id += Arg::flagStartString() + _flag;
00430 
00431         if ( _valueRequired )
00432             id += " <" + valueId + ">";
00433         
00434         id += ",  ";
00435     }
00436 
00437     id += Arg::nameStartString() + _name;
00438 
00439     if ( _valueRequired )
00440         id += " <" + valueId + ">";
00441             
00442     return id;
00443 
00444 }
00445 
00446 inline bool Arg::operator==(const Arg& a) const
00447 {
00448     if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
00449         return true;
00450     else
00451         return false;
00452 }
00453 
00454 inline std::string Arg::getDescription() const 
00455 {
00456     std::string desc = "";
00457     if ( _required )
00458         desc = "(" + _requireLabel + ")  ";
00459 
00460 //  if ( _valueRequired )
00461 //      desc += "(value required)  ";
00462 
00463     desc += _description;
00464     return desc; 
00465 }
00466 
00467 inline const std::string& Arg::getFlag() const { return _flag; }
00468 
00469 inline const std::string& Arg::getName() const { return _name; } 
00470 
00471 inline bool Arg::isRequired() const { return _required; }
00472 
00473 inline bool Arg::isValueRequired() const { return _valueRequired; }
00474 
00475 inline bool Arg::isSet() const 
00476 { 
00477     if ( _alreadySet && !_xorSet )
00478         return true;
00479     else
00480         return false;
00481 }
00482 
00483 inline bool Arg::isIgnoreable() const { return _ignoreable; }
00484 
00485 inline void Arg::setRequireLabel( const std::string& s) 
00486 { 
00487     _requireLabel = s;
00488 }
00489 
00490 inline bool Arg::argMatches( const std::string& argFlag ) const
00491 {
00492     if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
00493          argFlag == Arg::nameStartString() + _name )
00494         return true;
00495     else
00496         return false;
00497 }
00498 
00499 inline std::string Arg::toString() const
00500 {
00501     std::string s = "";
00502 
00503     if ( _flag != "" )
00504         s += Arg::flagStartString() + _flag + " ";
00505 
00506     s += "(" + Arg::nameStartString() + _name + ")";
00507 
00508     return s;
00509 }
00510 
00511 inline void Arg::_checkWithVisitor() const
00512 {
00513     if ( _visitor != NULL )
00514         _visitor->visit();
00515 }
00516 
00520 inline void Arg::trimFlag(std::string& flag, std::string& value) const
00521 {
00522     int stop = 0;
00523     for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
00524         if ( flag[i] == Arg::delimiter() )
00525         {
00526             stop = i;
00527             break;
00528         }
00529 
00530     if ( stop > 1 )
00531     {
00532         value = flag.substr(stop+1);
00533         flag = flag.substr(0,stop);
00534     }
00535 
00536 }
00537 
00541 inline bool Arg::_hasBlanks( const std::string& s ) const
00542 {
00543     for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00544         if ( s[i] == Arg::blankChar() )
00545             return true;
00546 
00547     return false;
00548 }
00549 
00550 inline void Arg::forceRequired()
00551 {
00552     _required = true;
00553 }
00554 
00555 inline void Arg::xorSet()
00556 {
00557     _alreadySet = true;
00558     _xorSet = true;
00559 }
00560 
00564 inline void Arg::addToList( std::list<Arg*>& argList ) const
00565 {
00566     argList.push_front( const_cast<Arg*>(this) );
00567 }
00568 
00569 inline bool Arg::allowMore()
00570 {
00571     return false;
00572 }
00573 
00574 inline bool Arg::acceptsMultipleValues()
00575 {
00576     return _acceptsMultipleValues;
00577 }
00578 
00580 //END Arg.cpp
00582 
00583 } //namespace TCLAP
00584 
00585 #endif
00586 

Generated on Thu Dec 14 23:01:53 2006 for tclap by  doxygen 1.5.1