$search
00001 00011 /***************************************************************************** 00012 ** Ifdefs 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 //Begin CmdLine.cpp 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 // this step is necessary so that we have easy access to mutable strings. 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 // checks to see if the argument is an empty combined switch ... 00395 // and if so, then we've actually matched it 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 //End CmdLine.cpp 00484 00485 }; // namespace ecl 00486 00487 #endif