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   virtual std::string getValueAsString()const = 0; 
00338 };
00339 
00343 typedef std::list<Arg*>::iterator ArgListIterator;
00344 
00348 typedef std::vector<Arg*>::iterator ArgVectorIterator;
00349 
00353 typedef std::list<Visitor*>::iterator VisitorListIterator;
00354 
00355 
00357 //BEGIN Arg.cpp
00359 
00360 inline Arg::Arg(const std::string& flag, 
00361                 const std::string& name, 
00362                 const std::string& desc, 
00363                 bool req, 
00364                 bool valreq,
00365                 Visitor* v) :
00366   _flag(flag),
00367   _name(name),
00368   _description(desc),
00369   _required(req),
00370   _requireLabel("required"),
00371   _valueRequired(valreq),
00372   _alreadySet(false),
00373   _visitor( v ),
00374   _ignoreable(true),
00375   _xorSet(false),
00376   _acceptsMultipleValues(false)
00377 {
00378   if ( _flag.length() > 1 ) 
00379     throw(SpecificationException(
00380             "Argument flag can only be one character long", toString() ) );
00381 
00382   if ( _name != ignoreNameString() &&  
00383        ( _flag == Arg::flagStartString() || 
00384          _flag == Arg::nameStartString() || 
00385          _flag == " " ) )
00386     throw(SpecificationException("Argument flag cannot be either '" + 
00387                                  Arg::flagStartString() + "' or '" + 
00388                                  Arg::nameStartString() + "' or a space.",
00389                                  toString() ) );
00390 
00391   if ( ( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) || 
00392        ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) ||
00393        ( _name.find( " ", 0 ) != std::string::npos ) )
00394     throw(SpecificationException("Argument name cannot contain either '" + 
00395                                  Arg::flagStartString() + "' or '" + 
00396                                  Arg::nameStartString() + "' or space.",
00397                                  toString() ) );
00398 
00399 }
00400 
00401 inline Arg::~Arg() { }
00402 
00403 inline std::string Arg::shortID( const std::string& valueId ) const
00404 {
00405   std::string id = "";
00406 
00407   if ( _flag != "" )
00408     id = Arg::flagStartString() + _flag;
00409   else
00410     id = Arg::nameStartString() + _name;
00411 
00412   std::string delim = " "; 
00413   delim[0] = Arg::delimiter(); // ugly!!!
00414   
00415   if ( _valueRequired )
00416     id += delim + "<" + valueId  + ">";
00417 
00418   if ( !_required )
00419     id = "[" + id + "]";
00420 
00421   return id;
00422 }
00423 
00424 inline std::string Arg::longID( const std::string& valueId ) const
00425 {
00426   std::string id = "";
00427 
00428   if ( _flag != "" )
00429     {
00430     id += Arg::flagStartString() + _flag;
00431 
00432     if ( _valueRequired )
00433       id += " <" + valueId + ">";
00434     
00435     id += ",  ";
00436     }
00437 
00438   id += Arg::nameStartString() + _name;
00439 
00440   if ( _valueRequired )
00441     id += " <" + valueId + ">";
00442       
00443   return id;
00444 
00445 }
00446 
00447 inline bool Arg::operator==(const Arg& a) const
00448 {
00449   if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
00450     return true;
00451   else
00452     return false;
00453 }
00454 
00455 inline std::string Arg::getDescription() const 
00456 {
00457   std::string desc = "";
00458   if ( _required )
00459     desc = "(" + _requireLabel + ")  ";
00460 
00461 //  if ( _valueRequired )
00462 //    desc += "(value required)  ";
00463 
00464   desc += _description;
00465   return desc; 
00466 }
00467 
00468 inline const std::string& Arg::getFlag() const { return _flag; }
00469 
00470 inline const std::string& Arg::getName() const { return _name; } 
00471 
00472 inline bool Arg::isRequired() const { return _required; }
00473 
00474 inline bool Arg::isValueRequired() const { return _valueRequired; }
00475 
00476 inline bool Arg::isSet() const 
00477 { 
00478   if ( _alreadySet && !_xorSet )
00479     return true;
00480   else
00481     return false;
00482 }
00483 
00484 inline bool Arg::isIgnoreable() const { return _ignoreable; }
00485 
00486 inline void Arg::setRequireLabel( const std::string& s) 
00487 { 
00488   _requireLabel = s;
00489 }
00490 
00491 inline bool Arg::argMatches( const std::string& argFlag ) const
00492 {
00493   // allow matching for patterns like --load-dicom with --load_dicom 
00494   // (more standard and user friendly)
00495   // only change dashes to underscores if the string starts with --
00496   std::string fixedFlag(argFlag);
00497   if ( argFlag.find_first_of(Arg::nameStartString()) == 0 )
00498     {
00499     const std::string::size_type nameStartLen = Arg::nameStartString().length(); 
00500     std::string::size_type dashIndex; 
00501     while ( (dashIndex = fixedFlag.find_first_of("-", nameStartLen)) != std::string::npos )
00502       {
00503       fixedFlag[dashIndex] = '_';
00504       }
00505     }
00506 
00507   if ( ( fixedFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
00508        fixedFlag == Arg::nameStartString() + _name )
00509     return true;
00510   else
00511     return false;
00512 }
00513 
00514 inline std::string Arg::toString() const
00515 {
00516   std::string s = "";
00517 
00518   if ( _flag != "" )
00519     s += Arg::flagStartString() + _flag + " ";
00520 
00521   s += "(" + Arg::nameStartString() + _name + ")";
00522 
00523   return s;
00524 }
00525 
00526 inline void Arg::_checkWithVisitor() const
00527 {
00528   if ( _visitor != NULL )
00529     _visitor->visit();
00530 }
00531 
00535 inline void Arg::trimFlag(std::string& flag, std::string& value) const
00536 {
00537   int stop = 0;
00538   for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
00539     if ( flag[i] == Arg::delimiter() )
00540       {
00541       stop = i;
00542       break;
00543       }
00544 
00545   if ( stop > 1 )
00546     {
00547     value = flag.substr(stop+1);
00548     flag = flag.substr(0,stop);
00549     }
00550 
00551 }
00552 
00556 inline bool Arg::_hasBlanks( const std::string& s ) const
00557 {
00558   for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00559     if ( s[i] == Arg::blankChar() )
00560       return true;
00561 
00562   return false;
00563 }
00564 
00565 inline void Arg::forceRequired()
00566 {
00567   _required = true;
00568 }
00569 
00570 inline void Arg::xorSet()
00571 {
00572   _alreadySet = true;
00573   _xorSet = true;
00574 }
00575 
00579 inline void Arg::addToList( std::list<Arg*>& argList ) const
00580 {
00581   argList.push_front( const_cast<Arg*>(this) );
00582 }
00583 
00584 inline bool Arg::allowMore()
00585 {
00586   return false;
00587 }
00588 
00589 inline bool Arg::acceptsMultipleValues()
00590 {
00591   return _acceptsMultipleValues;
00592 }
00593 
00595 //END Arg.cpp
00597 
00598 } //namespace TCLAP
00599 
00600 #endif
00601 

Generated on 6 Apr 2011 for Slicer3 by  doxygen 1.6.1