ValueArg.h

Go to the documentation of this file.
00001 /****************************************************************************** 
00002  * 
00003  *  file:  ValueArg.h
00004  * 
00005  *  Copyright (c) 2003, Michael E. Smoot .
00006  *  Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
00007  *  All rights reverved.
00008  * 
00009  *  See the file COPYING in the top directory of this distribution for
00010  *  more information.
00011  *  
00012  *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 
00013  *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
00014  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
00015  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
00016  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
00017  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
00018  *  DEALINGS IN THE SOFTWARE.  
00019  *  
00020  *****************************************************************************/ 
00021 
00022 
00023 #ifndef TCLAP_VALUE_ARGUMENT_H
00024 #define TCLAP_VALUE_ARGUMENT_H
00025 
00026 #include <string>
00027 #include <vector>
00028 
00029 #include <tclap/Arg.h>
00030 
00031 #ifdef HAVE_CONFIG_H
00032 #include <config.h>
00033 #else
00034 #define HAVE_SSTREAM
00035 #endif
00036 
00037 #if defined(HAVE_SSTREAM)
00038 #include <sstream>
00039 #elif defined(HAVE_STRSTREAM)
00040 #include <strstream>
00041 #else
00042 #error "Need a stringstream (sstream or strstream) to compile!"
00043 #endif
00044 
00045 namespace TCLAP {
00046 
00047 template<class T> class ValueArg;
00048 
00049 namespace VALUE_ARG_HELPER {
00050 
00051 enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY };
00052 
00062 template<class T> class ValueExtractor 
00063 {
00067      friend class ValueArg<T>;
00068 
00069      private:
00070 
00075         T &_value;
00076 
00081         ValueExtractor(T &value) : _value(value) { }
00082 
00088         int extractValue( const std::string& val ) 
00089           {
00090 
00091 #if defined(HAVE_SSTREAM)
00092                std::istringstream is(val);
00093 #elif defined(HAVE_STRSTREAM)
00094                std::istrstream is(val.c_str());
00095 #else
00096 #error "Need a stringstream (sstream or strstream) to compile!"
00097 #endif
00098 
00099             int valuesRead = 0;
00100             while ( is.good() ) 
00101                {
00102                 if ( is.peek() != EOF )
00103                     is >> _value;
00104                 else
00105                     break;
00106      
00107                 valuesRead++;
00108             }
00109       
00110             if ( is.fail() ) 
00111                 return EXTRACT_FAILURE;
00112 
00113             if ( valuesRead > 1 )
00114                 return EXTRACT_TOO_MANY;
00115 
00116             return 0;
00117         }
00118 };
00119 
00125 template<> class ValueExtractor<std::string> 
00126 {
00130     friend class ValueArg<std::string>;
00131 
00132     private:
00133      
00138         std::string &_value;
00139 
00144         ValueExtractor(std::string &value) : _value(value) {}
00145 
00151         int extractValue( const std::string& val ) 
00152           {
00153             _value = val;
00154             return 0;
00155         }
00156 };
00157 
00158 } //namespace VALUE_ARG_HELPER 
00159 
00168 template<class T>
00169 class ValueArg : public Arg 
00170 {
00171     protected:
00172 
00178         T _value;
00179 
00186         std::vector<T> _allowed;
00187 
00195         std::string _typeDesc;
00196 
00203         void _extractValue( const std::string& val );
00204 
00209         void _checkAllowed( const std::string& val );
00210 
00211      public:
00212 
00236         ValueArg( const std::string& flag, 
00237                   const std::string& name, 
00238                   const std::string& desc, 
00239                   bool req, 
00240                   T value,
00241                   const std::string& typeDesc,
00242                   Visitor* v = NULL);
00243                      
00244                      
00269         ValueArg( const std::string& flag, 
00270                   const std::string& name, 
00271                   const std::string& desc, 
00272                   bool req, 
00273                   T value,
00274                   const std::string& typeDesc,
00275                   CmdLineInterface& parser,
00276                   Visitor* v = NULL );
00277  
00300         ValueArg( const std::string& flag, 
00301                   const std::string& name, 
00302                   const std::string& desc, 
00303                   bool req, 
00304                   T value,
00305                   const std::vector<T>& allowed,
00306                   CmdLineInterface& parser,
00307                   Visitor* v = NULL );
00308        
00330         ValueArg( const std::string& flag, 
00331                   const std::string& name, 
00332                   const std::string& desc, 
00333                   bool req, 
00334                   T value,
00335                   const std::vector<T>& allowed,
00336                   Visitor* v = NULL );
00337 
00347         virtual bool processArg(int* i, std::vector<std::string>& args); 
00348 
00352         T& getValue() ;
00353 
00358         virtual std::string shortID(const std::string& val = "val") const;
00359 
00364         virtual std::string longID(const std::string& val = "val") const;
00365 
00366      private: 
00367           
00371         void allowedInit();
00372 
00373 };
00374 
00375 
00376 template<class T>
00377 void ValueArg<T>::allowedInit()
00378 {
00379     for ( unsigned int i = 0; i < _allowed.size(); i++ )
00380     {
00381 
00382 #if defined(HAVE_SSTREAM)
00383         std::ostringstream os;
00384 #elif defined(HAVE_STRSTREAM)
00385         std::ostrstream os;
00386 #else
00387 #error "Need a stringstream (sstream or strstream) to compile!"
00388 #endif
00389 
00390         os << _allowed[i];
00391 
00392         std::string temp( os.str() ); 
00393 
00394         if ( i > 0 )
00395                _typeDesc += "|";
00396         _typeDesc += temp;
00397     }
00398 }
00399 
00403 template<class T>
00404 ValueArg<T>::ValueArg(const std::string& flag, 
00405                       const std::string& name, 
00406                       const std::string& desc, 
00407                       bool req, 
00408                       T val,
00409                       const std::string& typeDesc,
00410                       Visitor* v)
00411 : Arg(flag, name, desc, req, true, v),
00412   _value( val ),
00413   _typeDesc( typeDesc )
00414 { }
00415 
00416 template<class T>
00417 ValueArg<T>::ValueArg(const std::string& flag, 
00418                       const std::string& name, 
00419                       const std::string& desc, 
00420                       bool req, 
00421                       T val,
00422                       const std::string& typeDesc,
00423                       CmdLineInterface& parser,
00424                       Visitor* v)
00425 : Arg(flag, name, desc, req, true, v),
00426   _value( val ),
00427   _typeDesc( typeDesc )
00428 { 
00429     parser.add( this );
00430 }
00431 
00435 template<class T>
00436 ValueArg<T>::ValueArg(const std::string& flag, 
00437                       const std::string& name, 
00438                       const std::string& desc, 
00439                       bool req, 
00440                       T val,
00441                       const std::vector<T>& allowed,
00442                       Visitor* v)
00443 : Arg(flag, name, desc, req, true, v),
00444   _value( val ),
00445   _allowed( allowed )
00446 { 
00447     allowedInit();
00448 }
00449 
00450 template<class T>
00451 ValueArg<T>::ValueArg(const std::string& flag, 
00452                       const std::string& name, 
00453                       const std::string& desc, 
00454                       bool req, 
00455                       T val,
00456                       const std::vector<T>& allowed,
00457                       CmdLineInterface& parser,
00458                       Visitor* v)
00459 : Arg(flag, name, desc, req, true, v),
00460 _value( val ),
00461 _allowed( allowed )
00462 { 
00463     allowedInit();
00464     parser.add( this );
00465 }
00466 
00467 
00471 template<class T>
00472 T& ValueArg<T>::getValue() { return _value; }
00473 
00477 template<class T>
00478 bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
00479 {
00480     if ( _ignoreable && Arg::ignoreRest() )
00481           return false;
00482 
00483     if ( _hasBlanks( args[*i] ) )
00484           return false;
00485 
00486     std::string flag = args[*i];
00487 
00488     std::string value = "";
00489     trimFlag( flag, value );
00490 
00491     if ( argMatches( flag ) )
00492     {
00493         if ( _alreadySet )
00494                throw( CmdLineParseException("Argument already set!", toString()) );
00495 
00496         if ( Arg::delimiter() != ' ' && value == "" )
00497                throw( ArgParseException( 
00498                                    "Couldn't find delimiter for this argument!",
00499                              toString() ) );
00500 
00501         if ( value == "" )
00502         {
00503             (*i)++;
00504             if ( (unsigned int)*i < args.size() ) 
00505                     _extractValue( args[*i] );
00506             else
00507                     throw( ArgParseException("Missing a value for this argument!",
00508                                                     toString() ) );
00509         }
00510         else
00511                _extractValue( value );
00512                     
00513         _alreadySet = true;
00514         _checkWithVisitor();
00515         return true;
00516     }     
00517     else
00518           return false;
00519 }
00520 
00524 template<class T>
00525 void ValueArg<T>::_checkAllowed( const std::string& val )
00526 {
00527     if ( _allowed.size() > 0 )
00528           if ( find(_allowed.begin(),_allowed.end(),_value) == _allowed.end() )
00529             throw( CmdLineParseException( "Couldn't find '" + val + 
00530                                           "' in allowed list.", toString() ) );
00531 }
00532 
00536 template<class T>
00537 std::string ValueArg<T>::shortID(const std::string& val) const
00538 {
00539     return Arg::shortID( _typeDesc );   
00540 }
00541 
00545 template<class T>
00546 std::string ValueArg<T>::longID(const std::string& val) const
00547 {
00548     return Arg::longID( _typeDesc );    
00549 }
00550 
00551 template<class T>
00552 void ValueArg<T>::_extractValue( const std::string& val ) 
00553 {
00554      VALUE_ARG_HELPER::ValueExtractor<T> ve(_value);
00555 
00556      int err = ve.extractValue(val);
00557 
00558      if ( err == VALUE_ARG_HELPER::EXTRACT_FAILURE )
00559           throw( ArgParseException("Couldn't read argument value from string '" +
00560                                   val + "'", toString() ) );
00561 
00562      if ( err == VALUE_ARG_HELPER::EXTRACT_TOO_MANY )
00563           throw( ArgParseException(
00564                          "More than one valid value parsed from string '" +
00565                         val + "'", toString() ) );
00566 
00567      _checkAllowed( val );           
00568 }
00569 
00570 } // namespace TCLAP
00571 
00572 #endif

Generated on Sun Mar 11 15:33:24 2007 for MetalWarriors by  doxygen 1.4.7