00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 }
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 }
00523
00524 #endif