Go to the documentation of this file.00001
00011
00012
00013
00014
00015 #ifndef TCLAP_CMDLINE_H
00016 #define TCLAP_CMDLINE_H
00017
00018 #include "switch_arg.hpp"
00019 #include "multi_switch_arg.hpp"
00020 #include "unlabeled_value_arg.hpp"
00021 #include "unlabeled_multi_arg.hpp"
00022
00023 #include "xor_handler.hpp"
00024 #include "help_visitor.hpp"
00025 #include "version_visitor.hpp"
00026 #include "ignore_rest_visitor.hpp"
00027
00028 #include "cmd_line_output.hpp"
00029 #include "std_output.hpp"
00030
00031 #include "constraint.hpp"
00032 #include "values_constraint.hpp"
00033
00034 #include <string>
00035 #include <vector>
00036 #include <list>
00037 #include <iostream>
00038 #include <iomanip>
00039 #include <algorithm>
00040
00041 namespace ecl {
00042
00049 class CmdLine : public CmdLineInterface
00050 {
00051 protected:
00052
00057 std::list<Arg*> _argList;
00058
00062 std::string _progName;
00063
00067 std::string _message;
00068
00072 std::string _version;
00073
00079 int _numRequired;
00080
00085 char _delimiter;
00086
00090 XorHandler _xorHandler;
00091
00097 std::list<Arg*> _argDeleteOnExitList;
00098
00104 std::list<Visitor*> _visitorDeleteOnExitList;
00105
00109 CmdLineOutput* _output;
00110
00117 bool _emptyCombined(const std::string& s);
00118
00122 void deleteOnExit(Arg* ptr);
00123
00127 void deleteOnExit(Visitor* ptr);
00128
00129 private:
00130
00135 void _constructor();
00136
00141 bool _userSetOutput;
00142
00146 bool _helpAndVersion;
00147
00148 public:
00149
00162 CmdLine(const std::string& message,
00163 const char delimiter = ' ',
00164 const std::string& version = "none",
00165 bool helpAndVersion = true);
00166
00170 virtual ~CmdLine();
00171
00176 void add( Arg& a );
00177
00182 void add( Arg* a );
00183
00190 void xorAdd( Arg& a, Arg& b );
00191
00197 void xorAdd( std::vector<Arg*>& xors );
00198
00204 void parse(int argc, char** argv);
00205
00209 CmdLineOutput* getOutput();
00210
00214 void setOutput(CmdLineOutput* co);
00215
00219 std::string& getVersion();
00220
00224 std::string& getProgramName();
00225
00229 std::list<Arg*>& getArgList();
00230
00234 XorHandler& getXorHandler();
00235
00239 char getDelimiter();
00240
00244 std::string& getMessage();
00245
00249 bool hasHelpAndVersion();
00250 };
00251
00252
00254
00256
00257 inline CmdLine::CmdLine(const std::string& m,
00258 char delim,
00259 const std::string& v,
00260 bool help )
00261 : _progName("not_set_yet"),
00262 _message(m),
00263 _version(v),
00264 _numRequired(0),
00265 _delimiter(delim),
00266 _userSetOutput(false),
00267 _helpAndVersion(help)
00268 {
00269 _constructor();
00270 }
00271
00272 inline CmdLine::~CmdLine()
00273 {
00274 ArgListIterator argIter;
00275 VisitorListIterator visIter;
00276
00277 for( argIter = _argDeleteOnExitList.begin();
00278 argIter != _argDeleteOnExitList.end();
00279 ++argIter)
00280 delete *argIter;
00281
00282 for( visIter = _visitorDeleteOnExitList.begin();
00283 visIter != _visitorDeleteOnExitList.end();
00284 ++visIter)
00285 delete *visIter;
00286
00287 if ( !_userSetOutput )
00288 delete _output;
00289 }
00290
00291 inline void CmdLine::_constructor()
00292 {
00293 _output = new StdOutput;
00294
00295 Arg::setDelimiter( _delimiter );
00296
00297 Visitor* v;
00298
00299 if ( _helpAndVersion )
00300 {
00301 v = new HelpVisitor( this, &_output );
00302 SwitchArg* help = new SwitchArg("h","help",
00303 "Displays usage information and exits.",
00304 false, v);
00305 add( help );
00306 deleteOnExit(help);
00307 deleteOnExit(v);
00308
00309 v = new VersionVisitor( this, &_output );
00310 SwitchArg* vers = new SwitchArg("","version",
00311 "Displays version information and exits.",
00312 false, v);
00313 add( vers );
00314 deleteOnExit(vers);
00315 deleteOnExit(v);
00316 }
00317
00318 v = new IgnoreRestVisitor();
00319 SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
00320 Arg::ignoreNameString(),
00321 "Ignores the rest of the labeled arguments following this flag.",
00322 false, v);
00323 add( ignore );
00324 deleteOnExit(ignore);
00325 deleteOnExit(v);
00326 }
00327
00328 inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
00329 {
00330 _xorHandler.add( ors );
00331
00332 for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
00333 {
00334 (*it)->forceRequired();
00335 (*it)->setRequireLabel( "OR required" );
00336
00337 add( *it );
00338 }
00339 }
00340
00341 inline void CmdLine::xorAdd( Arg& a, Arg& b )
00342 {
00343 std::vector<Arg*> ors;
00344 ors.push_back( &a );
00345 ors.push_back( &b );
00346 xorAdd( ors );
00347 }
00348
00349 inline void CmdLine::add( Arg& a )
00350 {
00351 add( &a );
00352 }
00353
00354 inline void CmdLine::add( Arg* a )
00355 {
00356 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
00357 if ( *a == *(*it) )
00358 throw( SpecificationException(
00359 "Argument with same flag/name already exists!",
00360 a->longID() ) );
00361
00362 a->addToList( _argList );
00363
00364 if ( a->isRequired() )
00365 _numRequired++;
00366 }
00367
00368 inline void CmdLine::parse(int argc, char** argv)
00369 {
00370 try {
00371
00372 _progName = argv[0];
00373
00374
00375 std::vector<std::string> args;
00376 for (int i = 1; i < argc; i++)
00377 args.push_back(argv[i]);
00378
00379 int requiredCount = 0;
00380
00381 for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
00382 {
00383 bool matched = false;
00384 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
00385 {
00386 if ( (*it)->processArg( &i, args ) )
00387 {
00388 requiredCount += _xorHandler.check( *it );
00389 matched = true;
00390 break;
00391 }
00392 }
00393
00394
00395
00396 if ( !matched && _emptyCombined( args[i] ) )
00397 matched = true;
00398
00399 if ( !matched && !Arg::ignoreRest() )
00400 throw(CmdLineParseException("Couldn't find match for argument",
00401 args[i]));
00402 }
00403
00404 if ( requiredCount < _numRequired )
00405 throw(CmdLineParseException("One or more required arguments missing!"));
00406
00407 if ( requiredCount > _numRequired )
00408 throw(CmdLineParseException("Too many arguments!"));
00409
00410 } catch ( ArgException e ) { _output->failure(*this,e); exit(1); }
00411 }
00412
00413 inline bool CmdLine::_emptyCombined(const std::string& s)
00414 {
00415 if ( s[0] != Arg::flagStartChar() )
00416 return false;
00417
00418 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00419 if ( s[i] != Arg::blankChar() )
00420 return false;
00421
00422 return true;
00423 }
00424
00425 inline void CmdLine::deleteOnExit(Arg* ptr)
00426 {
00427 _argDeleteOnExitList.push_back(ptr);
00428 }
00429
00430 inline void CmdLine::deleteOnExit(Visitor* ptr)
00431 {
00432 _visitorDeleteOnExitList.push_back(ptr);
00433 }
00434
00435 inline CmdLineOutput* CmdLine::getOutput()
00436 {
00437 return _output;
00438 }
00439
00440 inline void CmdLine::setOutput(CmdLineOutput* co)
00441 {
00442 _userSetOutput = true;
00443 _output = co;
00444 }
00445
00446 inline std::string& CmdLine::getVersion()
00447 {
00448 return _version;
00449 }
00450
00451 inline std::string& CmdLine::getProgramName()
00452 {
00453 return _progName;
00454 }
00455
00456 inline std::list<Arg*>& CmdLine::getArgList()
00457 {
00458 return _argList;
00459 }
00460
00461 inline XorHandler& CmdLine::getXorHandler()
00462 {
00463 return _xorHandler;
00464 }
00465
00466 inline char CmdLine::getDelimiter()
00467 {
00468 return _delimiter;
00469 }
00470
00471 inline std::string& CmdLine::getMessage()
00472 {
00473 return _message;
00474 }
00475
00476 inline bool CmdLine::hasHelpAndVersion()
00477 {
00478 return _helpAndVersion;
00479 }
00480
00482
00484
00485 };
00486
00487 #endif