00001
00011
00012
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 }
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;
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;
00483 return Arg::longID( _typeDesc );
00484 }
00485
00486 template<class T>
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 };
00511
00512 #endif