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 #include <tclap/Constraint.h>
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #else
00035 #define HAVE_SSTREAM
00036 #endif
00037 
00038 #if defined(HAVE_SSTREAM)
00039 #include <sstream>
00040 #elif defined(HAVE_STRSTREAM)
00041 #include <strstream>
00042 #else
00043 #error "Need a stringstream (sstream or strstream) to compile!"
00044 #endif
00045 
00046 namespace TCLAP {
00047 
00048 template<class T> class ValueArg;
00049 
00050 namespace VALUE_ARG_HELPER {
00051 
00052 enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY };
00053 
00063 template<class T> class ValueExtractor 
00064 {
00068     friend class ValueArg<T>;
00069 
00070     private:
00071 
00076         T &_value;
00077 
00082         ValueExtractor(T &value) : _value(value) { }
00083 
00089         int extractValue( const std::string& val ) 
00090         {
00091 
00092 #if defined(HAVE_SSTREAM)
00093             std::istringstream is(val);
00094 #elif defined(HAVE_STRSTREAM)
00095             std::istrstream is(val.c_str());
00096 #else
00097 #error "Need a stringstream (sstream or strstream) to compile!"
00098 #endif
00099 
00100             int valuesRead = 0;
00101             while ( is.good() ) 
00102             {
00103                 if ( is.peek() != EOF )
00104                     is >> _value;
00105                 else
00106                     break;
00107     
00108                 valuesRead++;
00109             }
00110       
00111             if ( is.fail() ) 
00112                 return EXTRACT_FAILURE;
00113 
00114             if ( valuesRead > 1 )
00115                 return EXTRACT_TOO_MANY;
00116 
00117             return 0;
00118         }
00119 };
00120 
00126 template<> class ValueExtractor<std::string> 
00127 {
00131     friend class ValueArg<std::string>;
00132 
00133     private:
00134     
00139         std::string &_value;
00140 
00145         ValueExtractor(std::string &value) : _value(value) {}
00146 
00152         int extractValue( const std::string& val ) 
00153         {
00154             _value = val;
00155             return 0;
00156         }
00157 };
00158 
00159 } //namespace VALUE_ARG_HELPER 
00160 
00169 template<class T>
00170 class ValueArg : public Arg 
00171 {
00172     protected:
00173 
00179         T _value;
00180 
00188         std::string _typeDesc;
00189 
00193         Constraint<T>* _constraint;
00194 
00201         void _extractValue( const std::string& val );
00202 
00203     public:
00204 
00228         ValueArg( const std::string& flag, 
00229                   const std::string& name, 
00230                   const std::string& desc, 
00231                   bool req, 
00232                   T value,
00233                   const std::string& typeDesc,
00234                   Visitor* v = NULL);
00235                  
00236                  
00261         ValueArg( const std::string& flag, 
00262                   const std::string& name, 
00263                   const std::string& desc, 
00264                   bool req, 
00265                   T value,
00266                   const std::string& typeDesc,
00267                   CmdLineInterface& parser,
00268                   Visitor* v = NULL );
00269  
00292         ValueArg( const std::string& flag, 
00293                   const std::string& name, 
00294                   const std::string& desc, 
00295                   bool req, 
00296                   T value,
00297                   Constraint<T>* constraint,
00298                   CmdLineInterface& parser,
00299                   Visitor* v = NULL );
00300       
00322         ValueArg( const std::string& flag, 
00323                   const std::string& name, 
00324                   const std::string& desc, 
00325                   bool req, 
00326                   T value,
00327                   Constraint<T>* constraint,
00328                   Visitor* v = NULL );
00329 
00339         virtual bool processArg(int* i, std::vector<std::string>& args); 
00340 
00344         T& getValue() ;
00345 
00350         virtual std::string shortID(const std::string& val = "val") const;
00351 
00356         virtual std::string longID(const std::string& val = "val") const;
00357 
00358 };
00359 
00360 
00364 template<class T>
00365 ValueArg<T>::ValueArg(const std::string& flag, 
00366                       const std::string& name, 
00367                       const std::string& desc, 
00368                       bool req, 
00369                       T val,
00370                       const std::string& typeDesc,
00371                       Visitor* v)
00372 : Arg(flag, name, desc, req, true, v),
00373   _value( val ),
00374   _typeDesc( typeDesc ),
00375   _constraint( NULL )
00376 { }
00377 
00378 template<class T>
00379 ValueArg<T>::ValueArg(const std::string& flag, 
00380                       const std::string& name, 
00381                       const std::string& desc, 
00382                       bool req, 
00383                       T val,
00384                       const std::string& typeDesc,
00385                       CmdLineInterface& parser,
00386                       Visitor* v)
00387 : Arg(flag, name, desc, req, true, v),
00388   _value( val ),
00389   _typeDesc( typeDesc ),
00390   _constraint( NULL )
00391 { 
00392     parser.add( this );
00393 }
00394 
00395 template<class T>
00396 ValueArg<T>::ValueArg(const std::string& flag, 
00397                       const std::string& name, 
00398                       const std::string& desc, 
00399                       bool req, 
00400                       T val,
00401                       Constraint<T>* constraint,
00402                       Visitor* v)
00403 : Arg(flag, name, desc, req, true, v),
00404   _value( val ),
00405   _typeDesc( constraint->shortID() ),
00406   _constraint( constraint )
00407 { }
00408 
00409 template<class T>
00410 ValueArg<T>::ValueArg(const std::string& flag, 
00411                       const std::string& name, 
00412                       const std::string& desc, 
00413                       bool req, 
00414                       T val,
00415                       Constraint<T>* constraint,
00416                       CmdLineInterface& parser,
00417                       Visitor* v)
00418 : Arg(flag, name, desc, req, true, v),
00419   _value( val ),
00420   _typeDesc( constraint->shortID() ),
00421   _constraint( constraint )
00422 { 
00423     parser.add( this );
00424 }
00425 
00426 
00430 template<class T>
00431 T& ValueArg<T>::getValue() { return _value; }
00432 
00436 template<class T>
00437 bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
00438 {
00439     if ( _ignoreable && Arg::ignoreRest() )
00440         return false;
00441 
00442     if ( _hasBlanks( args[*i] ) )
00443         return false;
00444 
00445     std::string flag = args[*i];
00446 
00447     std::string value = "";
00448     trimFlag( flag, value );
00449 
00450     if ( argMatches( flag ) )
00451     {
00452         if ( _alreadySet )
00453             throw( CmdLineParseException("Argument already set!", toString()) );
00454 
00455         if ( Arg::delimiter() != ' ' && value == "" )
00456             throw( ArgParseException( 
00457                             "Couldn't find delimiter for this argument!",
00458                              toString() ) );
00459 
00460         if ( value == "" )
00461         {
00462             (*i)++;
00463             if ( static_cast<unsigned int>(*i) < args.size() ) 
00464                 _extractValue( args[*i] );
00465             else
00466                 throw( ArgParseException("Missing a value for this argument!",
00467                                                     toString() ) );
00468         }
00469         else
00470             _extractValue( value );
00471                 
00472         _alreadySet = true;
00473         _checkWithVisitor();
00474         return true;
00475     }   
00476     else
00477         return false;
00478 }
00479 
00483 template<class T>
00484 std::string ValueArg<T>::shortID(const std::string& val) const
00485 {
00486     return Arg::shortID( _typeDesc ); 
00487 }
00488 
00492 template<class T>
00493 std::string ValueArg<T>::longID(const std::string& val) const
00494 {
00495     return Arg::longID( _typeDesc ); 
00496 }
00497 
00498 template<class T>
00499 void ValueArg<T>::_extractValue( const std::string& val ) 
00500 {
00501     VALUE_ARG_HELPER::ValueExtractor<T> ve(_value);
00502 
00503     int err = ve.extractValue(val);
00504 
00505     if ( err == VALUE_ARG_HELPER::EXTRACT_FAILURE )
00506         throw( ArgParseException("Couldn't read argument value from string '" +
00507                                  val + "'", toString() ) );
00508 
00509     if ( err == VALUE_ARG_HELPER::EXTRACT_TOO_MANY )
00510         throw( ArgParseException(
00511                     "More than one valid value parsed from string '" +
00512                     val + "'", toString() ) );
00513 
00514     if ( _constraint != NULL )
00515         if ( ! _constraint->check( _value ) )
00516             throw( CmdLineParseException( "Value '" + val + 
00517                                           "' does not meet constraint: " + 
00518                                           _constraint->description(),
00519                                           toString() ) );
00520 }
00521 
00522 } // namespace TCLAP
00523 
00524 #endif

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