Go to the documentation of this file.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_CMDLINE_H
00024 #define TCLAP_CMDLINE_H
00025
00026 #include <mrpt/otherlibs/tclap/SwitchArg.h>
00027 #include <mrpt/otherlibs/tclap/MultiSwitchArg.h>
00028 #include <mrpt/otherlibs/tclap/UnlabeledValueArg.h>
00029 #include <mrpt/otherlibs/tclap/UnlabeledMultiArg.h>
00030
00031 #include <mrpt/otherlibs/tclap/XorHandler.h>
00032 #include <mrpt/otherlibs/tclap/HelpVisitor.h>
00033 #include <mrpt/otherlibs/tclap/VersionVisitor.h>
00034 #include <mrpt/otherlibs/tclap/IgnoreRestVisitor.h>
00035
00036 #include <mrpt/otherlibs/tclap/CmdLineOutput.h>
00037 #include <mrpt/otherlibs/tclap/StdOutput.h>
00038
00039 #include <mrpt/otherlibs/tclap/Constraint.h>
00040 #include <mrpt/otherlibs/tclap/ValuesConstraint.h>
00041
00042 #include <string>
00043 #include <vector>
00044 #include <list>
00045 #include <iostream>
00046 #include <iomanip>
00047 #include <algorithm>
00048
00049 namespace TCLAP {
00050
00051
00052
00053
00054
00055 class CmdLine : public CmdLineInterface
00056 {
00057 protected:
00058
00059
00060
00061
00062
00063 std::list<Arg*> _argList;
00064
00065
00066
00067
00068 std::string _progName;
00069
00070
00071
00072
00073 std::string _message;
00074
00075
00076
00077
00078 std::string _version;
00079
00080
00081
00082
00083
00084
00085 int _numRequired;
00086
00087
00088
00089
00090
00091 char _delimiter;
00092
00093
00094
00095
00096 XorHandler _xorHandler;
00097
00098
00099
00100
00101
00102
00103 std::list<Arg*> _argDeleteOnExitList;
00104
00105
00106
00107
00108
00109
00110 std::list<Visitor*> _visitorDeleteOnExitList;
00111
00112
00113
00114
00115 CmdLineOutput* _output;
00116
00117
00118
00119
00120
00121
00122
00123 bool _emptyCombined(const std::string& s);
00124
00125
00126
00127
00128 void deleteOnExit(Arg* ptr);
00129
00130
00131
00132
00133 void deleteOnExit(Visitor* ptr);
00134
00135 private:
00136
00137
00138
00139
00140
00141 void _constructor();
00142
00143
00144
00145
00146
00147 bool _userSetOutput;
00148
00149
00150
00151
00152 bool _helpAndVersion;
00153
00154 public:
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 CmdLine(const std::string& message,
00169 const char delimiter = ' ',
00170 const std::string& version = "none",
00171 bool helpAndVersion = true);
00172
00173
00174
00175
00176 virtual ~CmdLine();
00177
00178
00179
00180
00181
00182 void add( Arg& a );
00183
00184
00185
00186
00187
00188 void add( Arg* a );
00189
00190
00191
00192
00193
00194
00195
00196 void xorAdd( Arg& a, Arg& b );
00197
00198
00199
00200
00201
00202
00203 void xorAdd( std::vector<Arg*>& xors );
00204
00205
00206
00207
00208
00209
00210
00211 bool parse(int argc, char** argv);
00212
00213
00214
00215
00216 CmdLineOutput* getOutput();
00217
00218
00219
00220
00221 void setOutput(CmdLineOutput* co);
00222
00223
00224
00225
00226 std::string& getVersion();
00227
00228
00229
00230
00231 std::string& getProgramName();
00232
00233
00234
00235
00236 std::list<Arg*>& getArgList();
00237
00238
00239
00240
00241 XorHandler& getXorHandler();
00242
00243
00244
00245
00246 char getDelimiter();
00247
00248
00249
00250
00251 std::string& getMessage();
00252
00253
00254
00255
00256 bool hasHelpAndVersion();
00257 };
00258
00259
00260
00261
00262
00263
00264 inline CmdLine::CmdLine(const std::string& m,
00265 char delim,
00266 const std::string& v,
00267 bool help )
00268 : _progName("not_set_yet"),
00269 _message(m),
00270 _version(v),
00271 _numRequired(0),
00272 _delimiter(delim),
00273 _userSetOutput(false),
00274 _helpAndVersion(help)
00275 {
00276 _constructor();
00277 }
00278
00279 inline CmdLine::~CmdLine()
00280 {
00281 ArgListIterator argIter;
00282 VisitorListIterator visIter;
00283
00284 for( argIter = _argDeleteOnExitList.begin();
00285 argIter != _argDeleteOnExitList.end();
00286 ++argIter)
00287 delete *argIter;
00288
00289 for( visIter = _visitorDeleteOnExitList.begin();
00290 visIter != _visitorDeleteOnExitList.end();
00291 ++visIter)
00292 delete *visIter;
00293
00294 if ( !_userSetOutput )
00295 delete _output;
00296 }
00297
00298 inline void CmdLine::_constructor()
00299 {
00300 _output = new StdOutput;
00301
00302 Arg::setDelimiter( _delimiter );
00303
00304 Visitor* v;
00305
00306 if ( _helpAndVersion )
00307 {
00308 v = new HelpVisitor( this, &_output );
00309 SwitchArg* help = new SwitchArg("h","help",
00310 "Displays usage information and exits.",
00311 false, v);
00312 add( help );
00313 deleteOnExit(help);
00314 deleteOnExit(v);
00315
00316 v = new VersionVisitor( this, &_output );
00317 SwitchArg* vers = new SwitchArg("","version",
00318 "Displays version information and exits.",
00319 false, v);
00320 add( vers );
00321 deleteOnExit(vers);
00322 deleteOnExit(v);
00323 }
00324
00325 v = new IgnoreRestVisitor();
00326 SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
00327 Arg::ignoreNameString(),
00328 "Ignores the rest of the labeled arguments following this flag.",
00329 false, v);
00330 add( ignore );
00331 deleteOnExit(ignore);
00332 deleteOnExit(v);
00333 }
00334
00335 inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
00336 {
00337 _xorHandler.add( ors );
00338
00339 for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
00340 {
00341 (*it)->forceRequired();
00342 (*it)->setRequireLabel( "OR required" );
00343
00344 add( *it );
00345 }
00346 }
00347
00348 inline void CmdLine::xorAdd( Arg& a, Arg& b )
00349 {
00350 std::vector<Arg*> ors;
00351 ors.push_back( &a );
00352 ors.push_back( &b );
00353 xorAdd( ors );
00354 }
00355
00356 inline void CmdLine::add( Arg& a )
00357 {
00358 add( &a );
00359 }
00360
00361 inline void CmdLine::add( Arg* a )
00362 {
00363 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
00364 if ( *a == *(*it) )
00365 throw( SpecificationException(
00366 "Argument with same flag/name already exists!",
00367 a->longID() ) );
00368
00369 a->addToList( _argList );
00370
00371 if ( a->isRequired() )
00372 _numRequired++;
00373 }
00374
00375 inline bool CmdLine::parse(int argc, char** argv)
00376 {
00377 try {
00378
00379 _progName = argv[0];
00380
00381
00382 std::vector<std::string> args;
00383 for (int i = 1; i < argc; i++)
00384 args.push_back(argv[i]);
00385
00386 int requiredCount = 0;
00387
00388 for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
00389 {
00390 bool matched = false;
00391 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
00392 {
00393 if ( (*it)->processArg( &i, args ) )
00394 {
00395 requiredCount += _xorHandler.check( *it );
00396 matched = true;
00397 break;
00398 }
00399 }
00400
00401
00402
00403 if ( !matched && _emptyCombined( args[i] ) )
00404 matched = true;
00405
00406 if ( !matched && !Arg::ignoreRest() )
00407 throw(CmdLineParseException("Couldn't find match for argument",
00408 args[i]));
00409 }
00410
00411 if ( requiredCount < _numRequired )
00412 throw(CmdLineParseException("One or more required arguments missing!"));
00413
00414 if ( requiredCount > _numRequired )
00415 throw(CmdLineParseException("Too many arguments!"));
00416
00417 return true;
00418
00419 }
00420 catch ( ActionDoneException e )
00421 {
00422 return false;
00423 }
00424 catch ( ArgException e )
00425 {
00426 _output->failure(*this,e);
00427 return false;
00428 }
00429 }
00430
00431 inline bool CmdLine::_emptyCombined(const std::string& s)
00432 {
00433 if ( s[0] != Arg::flagStartChar() )
00434 return false;
00435
00436 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00437 if ( s[i] != Arg::blankChar() )
00438 return false;
00439
00440 return true;
00441 }
00442
00443 inline void CmdLine::deleteOnExit(Arg* ptr)
00444 {
00445 _argDeleteOnExitList.push_back(ptr);
00446 }
00447
00448 inline void CmdLine::deleteOnExit(Visitor* ptr)
00449 {
00450 _visitorDeleteOnExitList.push_back(ptr);
00451 }
00452
00453 inline CmdLineOutput* CmdLine::getOutput()
00454 {
00455 return _output;
00456 }
00457
00458 inline void CmdLine::setOutput(CmdLineOutput* co)
00459 {
00460 _userSetOutput = true;
00461 _output = co;
00462 }
00463
00464 inline std::string& CmdLine::getVersion()
00465 {
00466 return _version;
00467 }
00468
00469 inline std::string& CmdLine::getProgramName()
00470 {
00471 return _progName;
00472 }
00473
00474 inline std::list<Arg*>& CmdLine::getArgList()
00475 {
00476 return _argList;
00477 }
00478
00479 inline XorHandler& CmdLine::getXorHandler()
00480 {
00481 return _xorHandler;
00482 }
00483
00484 inline char CmdLine::getDelimiter()
00485 {
00486 return _delimiter;
00487 }
00488
00489 inline std::string& CmdLine::getMessage()
00490 {
00491 return _message;
00492 }
00493
00494 inline bool CmdLine::hasHelpAndVersion()
00495 {
00496 return _helpAndVersion;
00497 }
00498
00499
00500
00501
00502
00503
00504
00505 }
00506 #endif