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 <string>
00027 #include <vector>
00028 #include <list>
00029 #include <iostream>
00030 #include <iomanip>
00031 #include <algorithm>
00032
00033 #include <tclap/SwitchArg.h>
00034 #include <tclap/MultiSwitchArg.h>
00035 #include <tclap/UnlabeledValueArg.h>
00036 #include <tclap/UnlabeledMultiArg.h>
00037
00038 #include <tclap/XorHandler.h>
00039 #include <tclap/HelpVisitor.h>
00040 #include <tclap/VersionVisitor.h>
00041 #include <tclap/IgnoreRestVisitor.h>
00042
00043 #include <tclap/CmdLineOutput.h>
00044 #include <tclap/StdOutput.h>
00045
00046 #include <tclap/Constraint.h>
00047 #include <tclap/ValuesConstraint.h>
00048
00049 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00050
00051 namespace TCLAP {
00052
00063 class CmdLine : public CmdLineInterface
00064 {
00065 protected:
00066
00071 std::list<Arg*> _argList;
00072
00076 std::string _progName;
00077
00081 std::string _message;
00082
00086 std::string _version;
00087
00093 int _numRequired;
00094
00099 char _delimiter;
00100
00104 XorHandler _xorHandler;
00105
00111 std::list<Arg*> _argDeleteOnExitList;
00112
00118 std::list<Visitor*> _visitorDeleteOnExitList;
00119
00123 CmdLineOutput* _output;
00124
00131 bool _emptyCombined(const std::string& s);
00132
00136 void deleteOnExit(Arg* ptr);
00137
00141 void deleteOnExit(Visitor* ptr);
00142
00143 private:
00144
00149 void _constructor();
00150
00155 bool _userSetOutput;
00156
00160 bool _helpAndVersion;
00161
00162 public:
00163
00176 CmdLine(const std::string& message,
00177 const char delimiter = ' ',
00178 const std::string& version = "none",
00179 bool helpAndVersion = true);
00180
00184 virtual ~CmdLine();
00185
00190 void add( Arg& a );
00191
00196 void add( Arg* a );
00197
00204 void xorAdd( Arg& a, Arg& b );
00205
00211 void xorAdd( std::vector<Arg*>& xors );
00212
00218 void parse(int argc, char** argv);
00219
00223 CmdLineOutput* getOutput();
00224
00228 void setOutput(CmdLineOutput* co);
00229
00233 std::string& getVersion();
00234
00238 std::string& getProgramName();
00239
00243 std::list<Arg*>& getArgList();
00244
00248 XorHandler& getXorHandler();
00249
00253 char getDelimiter();
00254
00258 std::string& getMessage();
00259
00263 bool hasHelpAndVersion();
00264 };
00265
00266
00268
00270
00271 inline CmdLine::CmdLine(const std::string& m,
00272 char delim,
00273 const std::string& v,
00274 bool help )
00275 : _progName("not_set_yet"),
00276 _message(m),
00277 _version(v),
00278 _numRequired(0),
00279 _delimiter(delim),
00280 _userSetOutput(false),
00281 _helpAndVersion(help)
00282 {
00283 _constructor();
00284 }
00285
00286 inline CmdLine::~CmdLine()
00287 {
00288 ArgListIterator argIter;
00289 VisitorListIterator visIter;
00290
00291 for( argIter = _argDeleteOnExitList.begin();
00292 argIter != _argDeleteOnExitList.end();
00293 ++argIter)
00294 delete *argIter;
00295
00296 for( visIter = _visitorDeleteOnExitList.begin();
00297 visIter != _visitorDeleteOnExitList.end();
00298 ++visIter)
00299 delete *visIter;
00300
00301 if ( !_userSetOutput )
00302 delete _output;
00303 }
00304
00305 inline void CmdLine::_constructor()
00306 {
00307 _output = new StdOutput;
00308 Arg::setDelimiter( _delimiter );
00309 Visitor* v;
00310
00311 if ( _helpAndVersion )
00312 {
00313 v = new HelpVisitor( this, &_output );
00314 SwitchArg* help = new SwitchArg("h","help",
00315 "Displays usage information and exits.",
00316 false, v);
00317 add( help );
00318 deleteOnExit(help);
00319 deleteOnExit(v);
00320
00321 v = new VersionVisitor( this, &_output );
00322 SwitchArg* vers = new SwitchArg("","version",
00323 "Displays version information and exits.",
00324 false, v);
00325 add( vers );
00326 deleteOnExit(vers);
00327 deleteOnExit(v);
00328 }
00329
00330 v = new IgnoreRestVisitor();
00331 SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
00332 Arg::ignoreNameString(),
00333 "Ignores the rest of the labeled arguments following this flag.",
00334 false, v);
00335 add( ignore );
00336 deleteOnExit(ignore);
00337 deleteOnExit(v);
00338 }
00339
00340 inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
00341 {
00342 _xorHandler.add( ors );
00343
00344 for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
00345 {
00346 (*it)->forceRequired();
00347 (*it)->setRequireLabel( "OR required" );
00348
00349 add( *it );
00350 }
00351 }
00352
00353 inline void CmdLine::xorAdd( Arg& a, Arg& b )
00354 {
00355 std::vector<Arg*> ors;
00356 ors.push_back( &a );
00357 ors.push_back( &b );
00358 xorAdd( ors );
00359 }
00360
00361 inline void CmdLine::add( Arg& a )
00362 {
00363 add( &a );
00364 }
00365
00366 inline void CmdLine::add( Arg* a )
00367 {
00368 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
00369 if ( *a == *(*it) )
00370 throw( SpecificationException(
00371 "Argument with same flag/name already exists!",
00372 a->longID() ) );
00373
00374 a->addToList( _argList );
00375
00376 if ( a->isRequired() )
00377 _numRequired++;
00378 }
00379
00380 inline void CmdLine::parse(int argc, char** argv)
00381 {
00382 try {
00383
00384 _progName = argv[0];
00385
00386
00387 std::vector<std::string> args;
00388 int i;
00389 for ( i = 1; i < argc; i++)
00390 args.push_back(argv[i]);
00391
00392 int requiredCount = 0;
00393
00394 for ( i = 0; static_cast<unsigned int>(i) < args.size(); i++)
00395 {
00396 bool matched = false;
00397 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
00398 {
00399 if ( (*it)->processArg( &i, args ) )
00400 {
00401 requiredCount += _xorHandler.check( *it );
00402 matched = true;
00403 break;
00404 }
00405 }
00406
00407
00408
00409 if ( !matched && _emptyCombined( args[i] ) )
00410 matched = true;
00411
00412 if ( !matched && !Arg::ignoreRest() )
00413 throw(CmdLineParseException("Couldn't find match for argument",
00414 args[i]));
00415 }
00416
00417 if ( requiredCount < _numRequired )
00418 throw(CmdLineParseException("One or more required arguments missing!"));
00419
00420 if ( requiredCount > _numRequired )
00421 throw(CmdLineParseException("Too many arguments!"));
00422
00423 } catch ( ArgException e ) { _output->failure(*this,e); exit(1); }
00424 }
00425
00426 inline bool CmdLine::_emptyCombined(const std::string& s)
00427 {
00428 if ( s[0] != Arg::flagStartChar() )
00429 return false;
00430
00431 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00432 if ( s[i] != Arg::blankChar() )
00433 return false;
00434
00435 return true;
00436 }
00437
00438 inline void CmdLine::deleteOnExit(Arg* ptr)
00439 {
00440 _argDeleteOnExitList.push_back(ptr);
00441 }
00442
00443 inline void CmdLine::deleteOnExit(Visitor* ptr)
00444 {
00445 _visitorDeleteOnExitList.push_back(ptr);
00446 }
00447
00448 inline CmdLineOutput* CmdLine::getOutput()
00449 {
00450 return _output;
00451 }
00452
00453 inline void CmdLine::setOutput(CmdLineOutput* co)
00454 {
00455 _userSetOutput = true;
00456 _output = co;
00457 }
00458
00459 inline std::string& CmdLine::getVersion()
00460 {
00461 return _version;
00462 }
00463
00464 inline std::string& CmdLine::getProgramName()
00465 {
00466 return _progName;
00467 }
00468
00469 inline std::list<Arg*>& CmdLine::getArgList()
00470 {
00471 return _argList;
00472 }
00473
00474 inline XorHandler& CmdLine::getXorHandler()
00475 {
00476 return _xorHandler;
00477 }
00478
00479 inline char CmdLine::getDelimiter()
00480 {
00481 return _delimiter;
00482 }
00483
00484 inline std::string& CmdLine::getMessage()
00485 {
00486 return _message;
00487 }
00488
00489 inline bool CmdLine::hasHelpAndVersion()
00490 {
00491 return _helpAndVersion;
00492 }
00493
00495
00497
00498
00499
00500 }
00501 #endif
00502
00503
00504 #endif