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
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 }
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 }
00571
00572 #endif