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 <tclap/SwitchArg.h>
00027 #include <tclap/MultiSwitchArg.h>
00028 #include <tclap/UnlabeledValueArg.h>
00029 #include <tclap/UnlabeledMultiArg.h>
00030
00031 #include <tclap/XorHandler.h>
00032 #include <tclap/HelpVisitor.h>
00033 #include <tclap/VersionVisitor.h>
00034 #include <tclap/IgnoreRestVisitor.h>
00035
00036 #include <tclap/CmdLineOutput.h>
00037 #include <tclap/StdOutput.h>
00038
00039 #include <tclap/Constraint.h>
00040 #include <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
00055 class CmdLine : public CmdLineInterface
00056 {
00057 protected:
00058
00063 std::list<Arg*> _argList;
00064
00068 std::string _progName;
00069
00073 std::string _message;
00074
00078 std::string _version;
00079
00085 int _numRequired;
00086
00091 char _delimiter;
00092
00096 XorHandler _xorHandler;
00097
00103 std::list<Arg*> _argDeleteOnExitList;
00104
00110 std::list<Visitor*> _visitorDeleteOnExitList;
00111
00115 CmdLineOutput* _output;
00116
00123 bool _emptyCombined(const std::string& s);
00124
00128 void deleteOnExit(Arg* ptr);
00129
00133 void deleteOnExit(Visitor* ptr);
00134
00135 private:
00136
00141 void _constructor();
00142
00147 bool _userSetOutput;
00148
00152 bool _helpAndVersion;
00153
00154 public:
00155
00168 CmdLine(const std::string& message,
00169 const char delimiter = ' ',
00170 const std::string& version = "none",
00171 bool helpAndVersion = true);
00172
00176 virtual ~CmdLine();
00177
00182 void add( Arg& a );
00183
00188 void add( Arg* a );
00189
00196 void xorAdd( Arg& a, Arg& b );
00197
00203 void xorAdd( std::vector<Arg*>& xors );
00204
00210 void parse(int argc, char** argv);
00211
00215 CmdLineOutput* getOutput();
00216
00220 void setOutput(CmdLineOutput* co);
00221
00225 std::string& getVersion();
00226
00230 std::string& getProgramName();
00231
00235 std::list<Arg*>& getArgList();
00236
00240 XorHandler& getXorHandler();
00241
00245 char getDelimiter();
00246
00250 std::string& getMessage();
00251
00255 bool hasHelpAndVersion();
00256 };
00257
00258
00260
00262
00263 inline CmdLine::CmdLine(const std::string& m,
00264 char delim,
00265 const std::string& v,
00266 bool help )
00267 : _progName("not_set_yet"),
00268 _message(m),
00269 _version(v),
00270 _numRequired(0),
00271 _delimiter(delim),
00272 _userSetOutput(false),
00273 _helpAndVersion(help)
00274 {
00275 _constructor();
00276 }
00277
00278 inline CmdLine::~CmdLine()
00279 {
00280 ArgListIterator argIter;
00281 VisitorListIterator visIter;
00282
00283 for( argIter = _argDeleteOnExitList.begin();
00284 argIter != _argDeleteOnExitList.end();
00285 ++argIter)
00286 delete *argIter;
00287
00288 for( visIter = _visitorDeleteOnExitList.begin();
00289 visIter != _visitorDeleteOnExitList.end();
00290 ++visIter)
00291 delete *visIter;
00292
00293 if ( !_userSetOutput )
00294 delete _output;
00295 }
00296
00297 inline void CmdLine::_constructor()
00298 {
00299 _output = new StdOutput;
00300
00301 Arg::setDelimiter( _delimiter );
00302
00303 Visitor* v;
00304
00305 if ( _helpAndVersion )
00306 {
00307 v = new HelpVisitor( this, &_output );
00308 SwitchArg* help = new SwitchArg("h","help",
00309 "Displays usage information and exits.",
00310 false, v);
00311 add( help );
00312 deleteOnExit(help);
00313 deleteOnExit(v);
00314
00315 v = new VersionVisitor( this, &_output );
00316 SwitchArg* vers = new SwitchArg("","version",
00317 "Displays version information and exits.",
00318 false, v);
00319 add( vers );
00320 deleteOnExit(vers);
00321 deleteOnExit(v);
00322 }
00323
00324 v = new IgnoreRestVisitor();
00325 SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
00326 Arg::ignoreNameString(),
00327 "Ignores the rest of the labeled arguments following this flag.",
00328 false, v);
00329 add( ignore );
00330 deleteOnExit(ignore);
00331 deleteOnExit(v);
00332 }
00333
00334 inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
00335 {
00336 _xorHandler.add( ors );
00337
00338 for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
00339 {
00340 (*it)->forceRequired();
00341 (*it)->setRequireLabel( "OR required" );
00342
00343 add( *it );
00344 }
00345 }
00346
00347 inline void CmdLine::xorAdd( Arg& a, Arg& b )
00348 {
00349 std::vector<Arg*> ors;
00350 ors.push_back( &a );
00351 ors.push_back( &b );
00352 xorAdd( ors );
00353 }
00354
00355 inline void CmdLine::add( Arg& a )
00356 {
00357 add( &a );
00358 }
00359
00360 inline void CmdLine::add( Arg* a )
00361 {
00362 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
00363 if ( *a == *(*it) )
00364 throw( SpecificationException(
00365 "Argument with same flag/name already exists!",
00366 a->longID() ) );
00367
00368 a->addToList( _argList );
00369
00370 if ( a->isRequired() )
00371 _numRequired++;
00372 }
00373
00374 inline void CmdLine::parse(int argc, char** argv)
00375 {
00376 try {
00377
00378 _progName = argv[0];
00379
00380
00381 std::vector<std::string> args;
00382 for (int i = 1; i < argc; i++)
00383 args.push_back(argv[i]);
00384
00385 int requiredCount = 0;
00386
00387 for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
00388 {
00389 bool matched = false;
00390 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
00391 {
00392 if ( (*it)->processArg( &i, args ) )
00393 {
00394 requiredCount += _xorHandler.check( *it );
00395 matched = true;
00396 break;
00397 }
00398 }
00399
00400
00401
00402 if ( !matched && _emptyCombined( args[i] ) )
00403 matched = true;
00404
00405 if ( !matched && !Arg::ignoreRest() )
00406 throw(CmdLineParseException("Couldn't find match for argument",
00407 args[i]));
00408 }
00409
00410 if ( requiredCount < _numRequired )
00411 throw(CmdLineParseException("One or more required arguments missing!"));
00412
00413 if ( requiredCount > _numRequired )
00414 throw(CmdLineParseException("Too many arguments!"));
00415
00416 } catch ( ArgException e ) { _output->failure(*this,e); exit(1); }
00417 }
00418
00419 inline bool CmdLine::_emptyCombined(const std::string& s)
00420 {
00421 if ( s[0] != Arg::flagStartChar() )
00422 return false;
00423
00424 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00425 if ( s[i] != Arg::blankChar() )
00426 return false;
00427
00428 return true;
00429 }
00430
00431 inline void CmdLine::deleteOnExit(Arg* ptr)
00432 {
00433 _argDeleteOnExitList.push_back(ptr);
00434 }
00435
00436 inline void CmdLine::deleteOnExit(Visitor* ptr)
00437 {
00438 _visitorDeleteOnExitList.push_back(ptr);
00439 }
00440
00441 inline CmdLineOutput* CmdLine::getOutput()
00442 {
00443 return _output;
00444 }
00445
00446 inline void CmdLine::setOutput(CmdLineOutput* co)
00447 {
00448 _userSetOutput = true;
00449 _output = co;
00450 }
00451
00452 inline std::string& CmdLine::getVersion()
00453 {
00454 return _version;
00455 }
00456
00457 inline std::string& CmdLine::getProgramName()
00458 {
00459 return _progName;
00460 }
00461
00462 inline std::list<Arg*>& CmdLine::getArgList()
00463 {
00464 return _argList;
00465 }
00466
00467 inline XorHandler& CmdLine::getXorHandler()
00468 {
00469 return _xorHandler;
00470 }
00471
00472 inline char CmdLine::getDelimiter()
00473 {
00474 return _delimiter;
00475 }
00476
00477 inline std::string& CmdLine::getMessage()
00478 {
00479 return _message;
00480 }
00481
00482 inline bool CmdLine::hasHelpAndVersion()
00483 {
00484 return _helpAndVersion;
00485 }
00486
00488
00490
00491
00492
00493 }
00494 #endif