Changeset 1515 for trunk/third_party/tclap/CmdLine.h
- Timestamp:
- 24/08/10 11:23:06 (21 months ago)
- File:
-
- 1 edited
-
trunk/third_party/tclap/CmdLine.h (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/third_party/tclap/CmdLine.h
r857 r1515 1 2 /****************************************************************************** 3 * 1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- 2 3 /****************************************************************************** 4 * 4 5 * file: CmdLine.h 5 * 6 * 6 7 * Copyright (c) 2003, Michael E. Smoot . 7 8 * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. 8 9 * All rights reverved. 9 * 10 * 10 11 * See the file COPYING in the top directory of this distribution for 11 12 * more information. 12 * 13 * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 14 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 * DEALINGS IN THE SOFTWARE. 20 * 21 *****************************************************************************/ 13 * 14 * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 * 22 *****************************************************************************/ 22 23 23 24 #ifndef TCLAP_CMDLINE_H … … 25 26 26 27 #include <tclap/SwitchArg.h> 28 #include <tclap/MultiSwitchArg.h> 27 29 #include <tclap/UnlabeledValueArg.h> 28 30 #include <tclap/UnlabeledMultiArg.h> … … 35 37 #include <tclap/CmdLineOutput.h> 36 38 #include <tclap/StdOutput.h> 39 40 #include <tclap/Constraint.h> 41 #include <tclap/ValuesConstraint.h> 37 42 38 43 #include <string> … … 42 47 #include <iomanip> 43 48 #include <algorithm> 49 #include <stdlib.h> // Needed for exit(), which isn't defined in some envs. 44 50 45 51 namespace TCLAP { 52 53 template<typename T> void DelPtr(T ptr) 54 { 55 delete ptr; 56 } 57 58 template<typename C> void ClearContainer(C &c) 59 { 60 typedef typename C::value_type value_type; 61 std::for_each(c.begin(), c.end(), DelPtr<value_type>); 62 c.clear(); 63 } 64 46 65 47 66 /** … … 75 94 76 95 /** 77 * The number of arguments that are required to be present on 78 * the command line. This is set dynamically, based on the 96 * The number of arguments that are required to be present on 97 * the command line. This is set dynamically, based on the 79 98 * Args added to the CmdLine object. 80 99 */ … … 82 101 83 102 /** 84 * The character that is used to separate the argument flag/name 103 * The character that is used to separate the argument flag/name 85 104 * from the value. Defaults to ' ' (space). 86 105 */ … … 110 129 */ 111 130 CmdLineOutput* _output; 131 132 /** 133 * Should CmdLine handle parsing exceptions internally? 134 */ 135 bool _handleExceptions; 136 137 /** 138 * Throws an exception listing the missing args. 139 */ 140 void missingArgsException(); 112 141 113 142 /** … … 119 148 bool _emptyCombined(const std::string& s); 120 149 121 private: 122 123 /** 124 * Encapsulates the code common to the constructors (which is all 125 * of it). 150 /** 151 * Perform a delete ptr; operation on ptr when this object is deleted. 152 */ 153 void deleteOnExit(Arg* ptr); 154 155 /** 156 * Perform a delete ptr; operation on ptr when this object is deleted. 157 */ 158 void deleteOnExit(Visitor* ptr); 159 160 private: 161 162 /** 163 * Encapsulates the code common to the constructors 164 * (which is all of it). 126 165 */ 127 166 void _constructor(); 128 167 129 /**130 * Perform a delete ptr; operation on ptr when this object is deleted.131 */132 void deleteOnExit(Arg* ptr);133 134 /**135 * Perform a delete ptr; operation on ptr when this object is deleted.136 */137 void deleteOnExit(Visitor* ptr);138 168 139 169 /** … … 143 173 bool _userSetOutput; 144 174 175 /** 176 * Whether or not to automatically create help and version switches. 177 */ 178 bool _helpAndVersion; 179 145 180 public: 146 147 /**148 * Command line constructor. DEPRECATED!!! This is here to maintain149 * backwards compatibility with earlier releases. Note that the150 * program name will be overwritten with argv[0]. The delimiter151 * used is ' ' (as before).152 * \param name - The program name - will be overwritten with argv[0].153 * \param message - The message to be used in the usage output.154 * \param version - The version number to be used in the155 * --version switch.156 */157 CmdLine(const std::string& name,158 const std::string& message,159 const std::string& version = "none" );160 181 161 182 /** … … 168 189 * \param version - The version number to be used in the 169 190 * --version switch. 170 */ 171 CmdLine(const std::string& message, 191 * \param helpAndVersion - Whether or not to create the Help and 192 * Version switches. Defaults to true. 193 */ 194 CmdLine(const std::string& message, 172 195 const char delimiter = ' ', 173 const std::string& version = "none" ); 174 196 const std::string& version = "none", 197 bool helpAndVersion = true); 198 175 199 /** 176 200 * Deletes any resources allocated by a CmdLine object. … … 180 204 /** 181 205 * Adds an argument to the list of arguments to be parsed. 182 * \param a - Argument to be added. 206 * \param a - Argument to be added. 183 207 */ 184 208 void add( Arg& a ); … … 186 210 /** 187 211 * An alternative add. Functionally identical. 188 * \param a - Argument to be added. 212 * \param a - Argument to be added. 189 213 */ 190 214 void add( Arg* a ); … … 193 217 * Add two Args that will be xor'd. If this method is used, add does 194 218 * not need to be called. 195 * \param a - Argument to be added and xor'd. 196 * \param b - Argument to be added and xor'd. 219 * \param a - Argument to be added and xor'd. 220 * \param b - Argument to be added and xor'd. 197 221 */ 198 222 void xorAdd( Arg& a, Arg& b ); 199 223 200 224 /** 201 * Add a list of Args that will be xor'd. If this method is used, 225 * Add a list of Args that will be xor'd. If this method is used, 202 226 * add does not need to be called. 203 * \param xors - List of Args to be added and xor'd. 227 * \param xors - List of Args to be added and xor'd. 204 228 */ 205 229 void xorAdd( std::vector<Arg*>& xors ); … … 210 234 * \param argv - Array of arguments. 211 235 */ 212 void parse(int argc, char** argv); 236 void parse(int argc, const char * const * argv); 237 238 /** 239 * Parses the command line. 240 * \param args - A vector of strings representing the args. 241 * args[0] is still the program name. 242 */ 243 void parse(std::vector<std::string>& args); 213 244 214 245 /** … … 251 282 */ 252 283 std::string& getMessage(); 284 285 /** 286 * 287 */ 288 bool hasHelpAndVersion(); 289 290 /** 291 * Disables or enables CmdLine's internal parsing exception handling. 292 * 293 * @param state Should CmdLine handle parsing exceptions internally? 294 */ 295 void setExceptionHandling(const bool state); 296 297 /** 298 * Returns the current state of the internal exception handling. 299 * 300 * @retval true Parsing exceptions are handled internally. 301 * @retval false Parsing exceptions are propagated to the caller. 302 */ 303 bool getExceptionHandling() const; 304 305 /** 306 * Allows the CmdLine object to be reused. 307 */ 308 void reset(); 309 253 310 }; 254 311 … … 258 315 /////////////////////////////////////////////////////////////////////////////// 259 316 260 inline CmdLine::CmdLine(const std::string& n, 261 const std::string& m, 262 const std::string& v ) 263 : _progName(n), 264 _message(m), 265 _version(v), 266 _numRequired(0), 267 _delimiter(' '), 268 _userSetOutput(false) 269 { 270 _constructor(); 271 } 272 273 inline CmdLine::CmdLine(const std::string& m, 274 char delim, 275 const std::string& v ) 317 inline CmdLine::CmdLine(const std::string& m, 318 char delim, 319 const std::string& v, 320 bool help ) 276 321 : _progName("not_set_yet"), 277 322 _message(m), … … 279 324 _numRequired(0), 280 325 _delimiter(delim), 281 _userSetOutput(false) 326 _handleExceptions(true), 327 _userSetOutput(false), 328 _helpAndVersion(help) 282 329 { 283 330 _constructor(); … … 286 333 inline CmdLine::~CmdLine() 287 334 { 288 ArgListIterator argIter; 289 VisitorListIterator visIter; 290 291 for( argIter = _argDeleteOnExitList.begin(); 292 argIter != _argDeleteOnExitList.end(); 293 ++argIter) 294 delete *argIter; 295 296 for( visIter = _visitorDeleteOnExitList.begin(); 297 visIter != _visitorDeleteOnExitList.end(); 298 ++visIter) 299 delete *visIter; 300 301 if ( !_userSetOutput ) 335 ClearContainer(_argDeleteOnExitList); 336 ClearContainer(_visitorDeleteOnExitList); 337 338 if ( !_userSetOutput ) { 302 339 delete _output; 340 _output = 0; 341 } 303 342 } 304 343 305 344 inline void CmdLine::_constructor() 306 { 345 { 307 346 _output = new StdOutput; 308 347 309 Visitor *v;310 311 348 Arg::setDelimiter( _delimiter ); 312 349 313 v = new HelpVisitor( this, &_output ); 314 SwitchArg* help = new SwitchArg("h","help", 315 "Displays usage information and exits.", 350 Visitor* v; 351 352 if ( _helpAndVersion ) 353 { 354 v = new HelpVisitor( this, &_output ); 355 SwitchArg* help = new SwitchArg("h","help", 356 "Displays usage information and exits.", 357 false, v); 358 add( help ); 359 deleteOnExit(help); 360 deleteOnExit(v); 361 362 v = new VersionVisitor( this, &_output ); 363 SwitchArg* vers = new SwitchArg("","version", 364 "Displays version information and exits.", 316 365 false, v); 317 add( help ); 318 deleteOnExit(help); 319 deleteOnExit(v); 320 321 v = new VersionVisitor( this, &_output ); 322 SwitchArg* vers = new SwitchArg("v","version", 323 "Displays version information and exits.", 324 false, v); 325 add( vers ); 326 deleteOnExit(vers); 327 deleteOnExit(v); 366 add( vers ); 367 deleteOnExit(vers); 368 deleteOnExit(v); 369 } 328 370 329 371 v = new IgnoreRestVisitor(); 330 SwitchArg* ignore = new SwitchArg(Arg::flagStartString(), 372 SwitchArg* ignore = new SwitchArg(Arg::flagStartString(), 331 373 Arg::ignoreNameString(), 332 374 "Ignores the rest of the labeled arguments following this flag.", … … 350 392 } 351 393 352 inline void CmdLine::xorAdd( Arg& a, Arg& b ) 394 inline void CmdLine::xorAdd( Arg& a, Arg& b ) 353 395 { 354 396 std::vector<Arg*> ors; … … 358 400 } 359 401 360 inline void CmdLine::add( Arg& a ) 361 { 402 inline void CmdLine::add( Arg& a ) 403 { 362 404 add( &a ); 363 405 } 364 406 365 inline void CmdLine::add( Arg* a ) 366 { 367 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) 368 if ( *a == *(*it) ) 369 throw( SpecificationException( 370 "Argument with same flag/name already exists!", 407 inline void CmdLine::add( Arg* a ) 408 { 409 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) 410 if ( *a == *(*it) ) 411 throw( SpecificationException( 412 "Argument with same flag/name already exists!", 371 413 a->longID() ) ); 372 414 373 415 a->addToList( _argList ); 374 416 375 if ( a->isRequired() ) 376 _numRequired++; 377 } 378 379 inline void CmdLine::parse(int argc, char** argv) 380 { 417 if ( a->isRequired() ) 418 _numRequired++; 419 } 420 421 422 inline void CmdLine::parse(int argc, const char * const * argv) 423 { 424 // this step is necessary so that we have easy access to 425 // mutable strings. 426 std::vector<std::string> args; 427 for (int i = 0; i < argc; i++) 428 args.push_back(argv[i]); 429 430 parse(args); 431 } 432 433 inline void CmdLine::parse(std::vector<std::string>& args) 434 { 435 bool shouldExit = false; 436 int estat = 0; 437 381 438 try { 382 383 _progName = argv[0]; 384 385 // this step is necessary so that we have easy access to mutable strings. 386 std::vector<std::string> args; 387 for (int i = 1; i < argc; i++) 388 args.push_back(argv[i]); 389 390 int requiredCount = 0; 391 392 for (int i = 0; (unsigned int)i < args.size(); i++) 393 { 394 bool matched = false; 395 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++) 396 { 397 if ( (*it)->processArg( &i, args ) ) 398 { 399 requiredCount += _xorHandler.check( *it ); 439 _progName = args.front(); 440 args.erase(args.begin()); 441 442 int requiredCount = 0; 443 444 for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++) { 445 bool matched = false; 446 for (ArgListIterator it = _argList.begin(); 447 it != _argList.end(); it++) { 448 if ( (*it)->processArg( &i, args ) ) 449 { 450 requiredCount += _xorHandler.check( *it ); 451 matched = true; 452 break; 453 } 454 } 455 456 // checks to see if the argument is an empty combined 457 // switch and if so, then we've actually matched it 458 if ( !matched && _emptyCombined( args[i] ) ) 400 459 matched = true; 401 break; 402 } 403 } 404 405 // checks to see if the argument is an empty combined switch ... 406 // and if so, then we've actually matched it 407 if ( !matched && _emptyCombined( args[i] ) ) 408 matched = true; 409 410 if ( !matched && !Arg::ignoreRest() ) 411 throw(CmdLineParseException("Couldn't find match for argument", 412 args[i])); 413 } 414 415 if ( requiredCount < _numRequired ) 416 throw(CmdLineParseException("One or more required arguments missing!")); 417 418 if ( requiredCount > _numRequired ) 419 throw(CmdLineParseException("Too many arguments!")); 420 421 } catch ( ArgException e ) { _output->failure(*this,e); exit(1); } 460 461 if ( !matched && !Arg::ignoreRest() ) 462 throw(CmdLineParseException("Couldn't find match " 463 "for argument", 464 args[i])); 465 } 466 467 if ( requiredCount < _numRequired ) 468 missingArgsException(); 469 470 if ( requiredCount > _numRequired ) 471 throw(CmdLineParseException("Too many arguments!")); 472 473 } catch ( ArgException& e ) { 474 // If we're not handling the exceptions, rethrow. 475 if ( !_handleExceptions) { 476 throw; 477 } 478 479 try { 480 _output->failure(*this,e); 481 } catch ( ExitException &ee ) { 482 estat = ee.getExitStatus(); 483 shouldExit = true; 484 } 485 } catch (ExitException &ee) { 486 // If we're not handling the exceptions, rethrow. 487 if ( !_handleExceptions) { 488 throw; 489 } 490 491 estat = ee.getExitStatus(); 492 shouldExit = true; 493 } 494 495 if (shouldExit) 496 exit(estat); 422 497 } 423 498 424 499 inline bool CmdLine::_emptyCombined(const std::string& s) 425 500 { 426 if ( s [0] != Arg::flagStartChar() )501 if ( s.length() > 0 && s[0] != Arg::flagStartChar() ) 427 502 return false; 428 503 429 for ( int i = 1; (unsigned int)i< s.length(); i++ )504 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ ) 430 505 if ( s[i] != Arg::blankChar() ) 431 506 return false; … … 434 509 } 435 510 511 inline void CmdLine::missingArgsException() 512 { 513 int count = 0; 514 515 std::string missingArgList; 516 for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++) 517 { 518 if ( (*it)->isRequired() && !(*it)->isSet() ) 519 { 520 missingArgList += (*it)->getName(); 521 missingArgList += ", "; 522 count++; 523 } 524 } 525 missingArgList = missingArgList.substr(0,missingArgList.length()-2); 526 527 std::string msg; 528 if ( count > 1 ) 529 msg = "Required arguments missing: "; 530 else 531 msg = "Required argument missing: "; 532 533 msg += missingArgList; 534 535 throw(CmdLineParseException(msg)); 536 } 537 436 538 inline void CmdLine::deleteOnExit(Arg* ptr) 437 539 { … … 483 585 { 484 586 return _message; 587 } 588 589 inline bool CmdLine::hasHelpAndVersion() 590 { 591 return _helpAndVersion; 592 } 593 594 inline void CmdLine::setExceptionHandling(const bool state) 595 { 596 _handleExceptions = state; 597 } 598 599 inline bool CmdLine::getExceptionHandling() const 600 { 601 return _handleExceptions; 602 } 603 604 inline void CmdLine::reset() 605 { 606 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) 607 { 608 (*it)->reset(); 609 } 610 611 _progName.clear(); 485 612 } 486 613 … … 492 619 493 620 } //namespace TCLAP 494 #endif 621 #endif
Note: See TracChangeset
for help on using the changeset viewer.
