$search
00001 00011 /***************************************************************************** 00012 ** Ifdefs 00013 *****************************************************************************/ 00014 00015 #ifndef TCLAP_VALUE_ARGUMENT_H 00016 #define TCLAP_VALUE_ARGUMENT_H 00017 00018 #include <string> 00019 #include <vector> 00020 #include <cstdio> 00021 #include "arg.hpp" 00022 #include "constraint.hpp" 00023 00024 #define HAVE_SSTREAM 00025 00026 #if defined(HAVE_SSTREAM) 00027 #include <sstream> 00028 #elif defined(HAVE_STRSTREAM) 00029 #include <strstream> 00030 #else 00031 #error "Need a stringstream (sstream or strstream) to compile!" 00032 #endif 00033 00034 namespace ecl { 00035 00036 template<class T> class ValueArg; 00037 00038 namespace ValueArgHelper { 00039 00040 enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY }; 00041 00053 template<class T> class ValueExtractor 00054 { 00055 friend class ValueArg<T>; 00056 00057 private: 00058 00063 T &_value; 00064 00069 ValueExtractor(T &value) : _value(value) { } 00070 00076 int extractValue( const std::string& val ) 00077 { 00078 00079 #if defined(HAVE_SSTREAM) 00080 std::istringstream is(val); 00081 #elif defined(HAVE_STRSTREAM) 00082 std::istrstream is(val.c_str()); 00083 #else 00084 #error "Need a stringstream (sstream or strstream) to compile!" 00085 #endif 00086 00087 int valuesRead = 0; 00088 while ( is.good() ) 00089 { 00090 if ( is.peek() != EOF ) 00091 is >> _value; 00092 else 00093 break; 00094 00095 valuesRead++; 00096 } 00097 00098 if ( is.fail() ) 00099 return EXTRACT_FAILURE; 00100 00101 if ( valuesRead > 1 ) 00102 return EXTRACT_TOO_MANY; 00103 00104 return 0; 00105 } 00106 }; 00107 00115 template<> class ValueExtractor<std::string> 00116 { 00117 friend class ValueArg<std::string>; 00118 00119 private: 00120 00125 std::string &_value; 00126 00131 ValueExtractor(std::string &value) : _value(value) {} 00132 00138 int extractValue( const std::string& val ) 00139 { 00140 _value = val; 00141 return 0; 00142 } 00143 }; 00144 00145 } //namespace ValueArgHelper 00146 00155 template<class T> 00156 class ValueArg : public Arg 00157 { 00158 protected: 00159 00165 T _value; 00166 00174 std::string _typeDesc; 00175 00179 Constraint<T>* _constraint; 00180 00187 void _extractValue( const std::string& val ); 00188 00189 public: 00190 00214 ValueArg( const std::string& flag, 00215 const std::string& name, 00216 const std::string& desc, 00217 bool req, 00218 T value, 00219 const std::string& typeDesc, 00220 Visitor* v = NULL); 00221 00222 00247 ValueArg( const std::string& flag, 00248 const std::string& name, 00249 const std::string& desc, 00250 bool req, 00251 T value, 00252 const std::string& typeDesc, 00253 CmdLineInterface& parser, 00254 Visitor* v = NULL ); 00255 00278 ValueArg( const std::string& flag, 00279 const std::string& name, 00280 const std::string& desc, 00281 bool req, 00282 T value, 00283 Constraint<T>* constraint, 00284 CmdLineInterface& parser, 00285 Visitor* v = NULL ); 00286 00308 ValueArg( const std::string& flag, 00309 const std::string& name, 00310 const std::string& desc, 00311 bool req, 00312 T value, 00313 Constraint<T>* constraint, 00314 Visitor* v = NULL ); 00315 00325 virtual bool processArg(int* i, std::vector<std::string>& args); 00326 00330 T& getValue() ; 00331 00336 virtual std::string shortID(const std::string& val = "val") const; 00337 00342 virtual std::string longID(const std::string& val = "val") const; 00343 00344 }; 00345 00346 00350 template<class T> 00351 ValueArg<T>::ValueArg(const std::string& flag, 00352 const std::string& name, 00353 const std::string& desc, 00354 bool req, 00355 T value, 00356 const std::string& typeDesc, 00357 Visitor* v) 00358 : Arg(flag, name, desc, req, true, v), 00359 _value( value ), 00360 _typeDesc( typeDesc ), 00361 _constraint( NULL ) 00362 { } 00363 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 CmdLineInterface& parser, 00372 Visitor* v) 00373 : Arg(flag, name, desc, req, true, v), 00374 _value( val ), 00375 _typeDesc( typeDesc ), 00376 _constraint( NULL ) 00377 { 00378 parser.add( this ); 00379 } 00380 00381 template<class T> 00382 ValueArg<T>::ValueArg(const std::string& flag, 00383 const std::string& name, 00384 const std::string& desc, 00385 bool req, 00386 T val, 00387 Constraint<T>* constraint, 00388 Visitor* v) 00389 : Arg(flag, name, desc, req, true, v), 00390 _value( val ), 00391 _typeDesc( constraint->shortID() ), 00392 _constraint( constraint ) 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 CmdLineInterface& parser, 00403 Visitor* v) 00404 : Arg(flag, name, desc, req, true, v), 00405 _value( val ), 00406 _typeDesc( constraint->shortID() ), 00407 _constraint( constraint ) 00408 { 00409 parser.add( this ); 00410 } 00411 00412 00416 template<class T> 00417 T& ValueArg<T>::getValue() { return _value; } 00418 00422 template<class T> 00423 bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args) 00424 { 00425 if ( _ignoreable && Arg::ignoreRest() ) 00426 return false; 00427 00428 if ( _hasBlanks( args[*i] ) ) 00429 return false; 00430 00431 std::string flag = args[*i]; 00432 00433 std::string value = ""; 00434 trimFlag( flag, value ); 00435 00436 if ( argMatches( flag ) ) 00437 { 00438 if ( _alreadySet ) 00439 throw( CmdLineParseException("Argument already set!", toString()) ); 00440 00441 if ( Arg::delimiter() != ' ' && value == "" ) 00442 throw( ArgParseException( 00443 "Couldn't find delimiter for this argument!", 00444 toString() ) ); 00445 00446 if ( value == "" ) 00447 { 00448 (*i)++; 00449 if ( static_cast<unsigned int>(*i) < args.size() ) 00450 _extractValue( args[*i] ); 00451 else 00452 throw( ArgParseException("Missing a value for this argument!", 00453 toString() ) ); 00454 } 00455 else 00456 _extractValue( value ); 00457 00458 _alreadySet = true; 00459 _checkWithVisitor(); 00460 return true; 00461 } 00462 else 00463 return false; 00464 } 00465 00469 template<class T> 00470 std::string ValueArg<T>::shortID(const std::string& val) const 00471 { 00472 std::string stop_warnings = val; // Only to stop annoying warning messages, I dont think it slows things down 00473 return Arg::shortID( _typeDesc ); 00474 } 00475 00479 template<class T> 00480 std::string ValueArg<T>::longID(const std::string& val) const 00481 { 00482 std::string stop_warnings = val; // Only to stop annoying warning messages, I dont think it slows things down 00483 return Arg::longID( _typeDesc ); 00484 } 00485 00486 template<class T> // Just to stop the warnings. 00487 void ValueArg<T>::_extractValue( const std::string& val ) 00488 { 00489 ValueArgHelper::ValueExtractor<T> ve(_value); 00490 00491 int err = ve.extractValue(val); 00492 00493 if ( err == ValueArgHelper::EXTRACT_FAILURE ) 00494 throw( ArgParseException("Couldn't read argument value from string '" + 00495 val + "'", toString() ) ); 00496 00497 if ( err == ValueArgHelper::EXTRACT_TOO_MANY ) 00498 throw( ArgParseException( 00499 "More than one valid value parsed from string '" + 00500 val + "'", toString() ) ); 00501 00502 if ( _constraint != NULL ) 00503 if ( ! _constraint->check( _value ) ) 00504 throw( CmdLineParseException( "Value '" + val + 00505 "' does not meet constraint: " + 00506 _constraint->description(), 00507 toString() ) ); 00508 } 00509 00510 }; // namespace ecl 00511 00512 #endif