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_MULTIPLE_ARGUMENT_H
00024 #define TCLAP_MULTIPLE_ARGUMENT_H
00025
00026 #include <string>
00027 #include <vector>
00028
00029 #include <mrpt/otherlibs/tclap/Arg.h>
00030 #include <mrpt/otherlibs/tclap/Constraint.h>
00031
00032
00033
00034
00035 #define HAVE_SSTREAM
00036
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 MultiArg;
00049
00050 namespace MULTI_ARG_HELPER {
00051
00052 enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY };
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 template<class T>
00064 class ValueExtractor
00065 {
00066 friend class MultiArg<T>;
00067
00068 private:
00069
00070
00071
00072
00073
00074 std::vector<T> &_values;
00075
00076
00077
00078
00079
00080 ValueExtractor(std::vector<T> &values) : _values(values) {}
00081
00082
00083
00084
00085
00086
00087 int extractValue( const std::string& val )
00088 {
00089 T temp;
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
00101 while ( is.good() )
00102 {
00103 if ( is.peek() != EOF )
00104 is >> temp;
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 _values.push_back(temp);
00118
00119 return 0;
00120 }
00121 };
00122
00123
00124
00125
00126
00127
00128 template<>
00129 class ValueExtractor<std::string>
00130 {
00131 friend class MultiArg<std::string>;
00132
00133 private:
00134
00135
00136
00137
00138
00139 std::vector<std::string> &_values;
00140
00141
00142
00143
00144
00145 ValueExtractor(std::vector<std::string> &values) : _values(values) {}
00146
00147
00148
00149
00150
00151
00152 int extractValue( const std::string& val )
00153 {
00154 _values.push_back( val );
00155 return 0;
00156 }
00157 };
00158
00159 }
00160
00161
00162
00163
00164
00165
00166 template<class T>
00167 class MultiArg : public Arg
00168 {
00169 protected:
00170
00171
00172
00173
00174 std::vector<T> _values;
00175
00176
00177
00178
00179 std::string _typeDesc;
00180
00181
00182
00183
00184 Constraint<T>* _constraint;
00185
00186
00187
00188
00189
00190
00191
00192 void _extractValue( const std::string& val );
00193
00194 bool _allowMore;
00195
00196 public:
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 MultiArg( const std::string& flag,
00216 const std::string& name,
00217 const std::string& desc,
00218 bool req,
00219 const std::string& typeDesc,
00220 Visitor* v = NULL);
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 MultiArg( const std::string& flag,
00241 const std::string& name,
00242 const std::string& desc,
00243 bool req,
00244 const std::string& typeDesc,
00245 CmdLineInterface& parser,
00246 Visitor* v = NULL );
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 MultiArg( const std::string& flag,
00264 const std::string& name,
00265 const std::string& desc,
00266 bool req,
00267 Constraint<T>* constraint,
00268 Visitor* v = NULL );
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 MultiArg( const std::string& flag,
00287 const std::string& name,
00288 const std::string& desc,
00289 bool req,
00290 Constraint<T>* constraint,
00291 CmdLineInterface& parser,
00292 Visitor* v = NULL );
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 virtual bool processArg(int* i, std::vector<std::string>& args);
00303
00304
00305
00306
00307
00308 const std::vector<T>& getValue();
00309
00310
00311
00312
00313
00314 virtual std::string shortID(const std::string& val="val") const;
00315
00316
00317
00318
00319
00320 virtual std::string longID(const std::string& val="val") const;
00321
00322
00323
00324
00325
00326 virtual bool isRequired() const;
00327
00328 virtual bool allowMore();
00329
00330 };
00331
00332 template<class T>
00333 MultiArg<T>::MultiArg(const std::string& flag,
00334 const std::string& name,
00335 const std::string& desc,
00336 bool req,
00337 const std::string& typeDesc,
00338 Visitor* v)
00339 : Arg( flag, name, desc, req, true, v ),
00340 _typeDesc( typeDesc ),
00341 _constraint( NULL ),
00342 _allowMore(false)
00343 {
00344 _acceptsMultipleValues = true;
00345 }
00346
00347 template<class T>
00348 MultiArg<T>::MultiArg(const std::string& flag,
00349 const std::string& name,
00350 const std::string& desc,
00351 bool req,
00352 const std::string& typeDesc,
00353 CmdLineInterface& parser,
00354 Visitor* v)
00355 : Arg( flag, name, desc, req, true, v ),
00356 _typeDesc( typeDesc ),
00357 _constraint( NULL ),
00358 _allowMore(false)
00359 {
00360 parser.add( this );
00361 _acceptsMultipleValues = true;
00362 }
00363
00364
00365
00366
00367 template<class T>
00368 MultiArg<T>::MultiArg(const std::string& flag,
00369 const std::string& name,
00370 const std::string& desc,
00371 bool req,
00372 Constraint<T>* constraint,
00373 Visitor* v)
00374 : Arg( flag, name, desc, req, true, v ),
00375 _typeDesc( constraint->shortID() ),
00376 _constraint( constraint ),
00377 _allowMore(false)
00378 {
00379 _acceptsMultipleValues = true;
00380 }
00381
00382 template<class T>
00383 MultiArg<T>::MultiArg(const std::string& flag,
00384 const std::string& name,
00385 const std::string& desc,
00386 bool req,
00387 Constraint<T>* constraint,
00388 CmdLineInterface& parser,
00389 Visitor* v)
00390 : Arg( flag, name, desc, req, true, v ),
00391 _typeDesc( constraint->shortID() ),
00392 _constraint( constraint ),
00393 _allowMore(false)
00394 {
00395 parser.add( this );
00396 _acceptsMultipleValues = true;
00397 }
00398
00399 template<class T>
00400 const std::vector<T>& MultiArg<T>::getValue() { return _values; }
00401
00402 template<class T>
00403 bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
00404 {
00405 if ( _ignoreable && Arg::ignoreRest() )
00406 return false;
00407
00408 if ( _hasBlanks( args[*i] ) )
00409 return false;
00410
00411 std::string flag = args[*i];
00412 std::string value = "";
00413
00414 trimFlag( flag, value );
00415
00416 if ( argMatches( flag ) )
00417 {
00418 if ( Arg::delimiter() != ' ' && value == "" )
00419 throw( ArgParseException(
00420 "Couldn't find delimiter for this argument!",
00421 toString() ) );
00422
00423
00424 if ( value == "" )
00425 {
00426 (*i)++;
00427 if ( static_cast<unsigned int>(*i) < args.size() )
00428 _extractValue( args[*i] );
00429 else
00430 throw( ArgParseException("Missing a value for this argument!",
00431 toString() ) );
00432 }
00433 else
00434 _extractValue( value );
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 _alreadySet = true;
00445 _checkWithVisitor();
00446
00447 return true;
00448 }
00449 else
00450 return false;
00451 }
00452
00453
00454
00455
00456 template<class T>
00457 std::string MultiArg<T>::shortID(const std::string& val) const
00458 {
00459 std::string id = Arg::shortID(_typeDesc) + " ... ";
00460
00461 return id;
00462 }
00463
00464
00465
00466
00467 template<class T>
00468 std::string MultiArg<T>::longID(const std::string& val) const
00469 {
00470 std::string id = Arg::longID(_typeDesc) + " (accepted multiple times)";
00471
00472 return id;
00473 }
00474
00475
00476
00477
00478
00479 template<class T>
00480 bool MultiArg<T>::isRequired() const
00481 {
00482 if ( _required )
00483 {
00484 if ( _values.size() > 1 )
00485 return false;
00486 else
00487 return true;
00488 }
00489 else
00490 return false;
00491
00492 }
00493
00494 template<class T>
00495 void MultiArg<T>::_extractValue( const std::string& val )
00496 {
00497 MULTI_ARG_HELPER::ValueExtractor<T> ve(_values);
00498
00499 int err = ve.extractValue(val);
00500
00501 if ( err == MULTI_ARG_HELPER::EXTRACT_FAILURE )
00502 throw( ArgParseException("Couldn't read argument value "
00503 "from string '" + val + "'", toString() ) );
00504
00505 if(err == MULTI_ARG_HELPER::EXTRACT_TOO_MANY)
00506 throw( ArgParseException("More than one valid value "
00507 "parsed from string '" + val + "'",
00508 toString() ) );
00509 if ( _constraint != NULL )
00510 if ( ! _constraint->check( _values.back() ) )
00511 throw( CmdLineParseException( "Value '" + val +
00512 "' does not meet constraint: " +
00513 _constraint->description(),
00514 toString() ) );
00515 }
00516
00517 template<class T>
00518 bool MultiArg<T>::allowMore()
00519 {
00520 bool am = _allowMore;
00521 _allowMore = true;
00522 return am;
00523 }
00524
00525 }
00526
00527 #endif