tclap  1.2.2
CmdLine.h
Go to the documentation of this file.
1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2 
3 /******************************************************************************
4  *
5  * file: CmdLine.h
6  *
7  * Copyright (c) 2003, Michael E. Smoot .
8  * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
9  * All rights reserved.
10  *
11  * See the file COPYING in the top directory of this distribution for
12  * more information.
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  *****************************************************************************/
23 
24 #ifndef TCLAP_CMDLINE_H
25 #define TCLAP_CMDLINE_H
26 
27 #include <tclap/SwitchArg.h>
28 #include <tclap/MultiSwitchArg.h>
31 
32 #include <tclap/XorHandler.h>
33 #include <tclap/HelpVisitor.h>
34 #include <tclap/VersionVisitor.h>
36 
37 #include <tclap/CmdLineOutput.h>
38 #include <tclap/StdOutput.h>
39 
40 #include <tclap/Constraint.h>
41 #include <tclap/ValuesConstraint.h>
42 
43 #include <string>
44 #include <vector>
45 #include <list>
46 #include <iostream>
47 #include <iomanip>
48 #include <algorithm>
49 #include <stdlib.h> // Needed for exit(), which isn't defined in some envs.
50 
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 
65 
70 class CmdLine : public CmdLineInterface
71 {
72  protected:
73 
78  std::list<Arg*> _argList;
79 
83  std::string _progName;
84 
88  std::string _message;
89 
93  std::string _version;
94 
101 
107 
112 
118  std::list<Arg*> _argDeleteOnExitList;
119 
125  std::list<Visitor*> _visitorDeleteOnExitList;
126 
131 
136 
140  void missingArgsException();
141 
148  bool _emptyCombined(const std::string& s);
149 
153  void deleteOnExit(Arg* ptr);
154 
158  void deleteOnExit(Visitor* ptr);
159 
160 private:
161 
165  CmdLine(const CmdLine& rhs);
166  CmdLine& operator=(const CmdLine& rhs);
167 
172  void _constructor();
173 
174 
179  bool _userSetOutput;
180 
184  bool _helpAndVersion;
185 
189  bool _ignoreUnmatched;
190 
191  public:
192 
205  CmdLine(const std::string& message,
206  const char delimiter = ' ',
207  const std::string& version = "none",
208  bool helpAndVersion = true);
209 
213  virtual ~CmdLine();
214 
219  void add( Arg& a );
220 
225  void add( Arg* a );
226 
233  void xorAdd( Arg& a, Arg& b );
234 
240  void xorAdd( const std::vector<Arg*>& xors );
241 
247  void parse(int argc, const char * const * argv);
248 
254  void parse(std::vector<std::string>& args);
255 
260 
264  void setOutput(CmdLineOutput* co);
265 
269  std::string& getVersion();
270 
274  std::string& getProgramName();
275 
279  std::list<Arg*>& getArgList();
280 
285 
289  char getDelimiter();
290 
294  std::string& getMessage();
295 
299  bool hasHelpAndVersion();
300 
306  void setExceptionHandling(const bool state);
307 
314  bool getExceptionHandling() const;
315 
319  void reset();
320 
327  void ignoreUnmatched(const bool ignore);
328 };
329 
330 
332 //Begin CmdLine.cpp
334 
335 inline CmdLine::CmdLine(const std::string& m,
336  char delim,
337  const std::string& v,
338  bool help )
339  :
340  _argList(std::list<Arg*>()),
341  _progName("not_set_yet"),
342  _message(m),
343  _version(v),
344  _numRequired(0),
345  _delimiter(delim),
347  _argDeleteOnExitList(std::list<Arg*>()),
348  _visitorDeleteOnExitList(std::list<Visitor*>()),
349  _output(0),
350  _handleExceptions(true),
351  _userSetOutput(false),
352  _helpAndVersion(help),
353  _ignoreUnmatched(false)
354 {
355  _constructor();
356 }
357 
359 {
362 
363  if ( !_userSetOutput ) {
364  delete _output;
365  _output = 0;
366  }
367 }
368 
369 inline void CmdLine::_constructor()
370 {
371  _output = new StdOutput;
372 
374 
375  Visitor* v;
376 
377  if ( _helpAndVersion )
378  {
379  v = new HelpVisitor( this, &_output );
380  SwitchArg* help = new SwitchArg("h","help",
381  "Displays usage information and exits.",
382  false, v);
383  add( help );
384  deleteOnExit(help);
385  deleteOnExit(v);
386 
387  v = new VersionVisitor( this, &_output );
388  SwitchArg* vers = new SwitchArg("","version",
389  "Displays version information and exits.",
390  false, v);
391  add( vers );
392  deleteOnExit(vers);
393  deleteOnExit(v);
394  }
395 
396  v = new IgnoreRestVisitor();
397  SwitchArg* ignore = new SwitchArg(Arg::flagStartString(),
399  "Ignores the rest of the labeled arguments following this flag.",
400  false, v);
401  add( ignore );
402  deleteOnExit(ignore);
403  deleteOnExit(v);
404 }
405 
406 inline void CmdLine::xorAdd( const std::vector<Arg*>& ors )
407 {
408  _xorHandler.add( ors );
409 
410  for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
411  {
412  (*it)->forceRequired();
413  (*it)->setRequireLabel( "OR required" );
414  add( *it );
415  }
416 }
417 
418 inline void CmdLine::xorAdd( Arg& a, Arg& b )
419 {
420  std::vector<Arg*> ors;
421  ors.push_back( &a );
422  ors.push_back( &b );
423  xorAdd( ors );
424 }
425 
426 inline void CmdLine::add( Arg& a )
427 {
428  add( &a );
429 }
430 
431 inline void CmdLine::add( Arg* a )
432 {
433  for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
434  if ( *a == *(*it) )
435  throw( SpecificationException(
436  "Argument with same flag/name already exists!",
437  a->longID() ) );
438 
439  a->addToList( _argList );
440 
441  if ( a->isRequired() )
442  _numRequired++;
443 }
444 
445 
446 inline void CmdLine::parse(int argc, const char * const * argv)
447 {
448  // this step is necessary so that we have easy access to
449  // mutable strings.
450  std::vector<std::string> args;
451  for (int i = 0; i < argc; i++)
452  args.push_back(argv[i]);
453 
454  parse(args);
455 }
456 
457 inline void CmdLine::parse(std::vector<std::string>& args)
458 {
459  bool shouldExit = false;
460  int estat = 0;
461  try {
462  if (args.empty()) {
463  // https://sourceforge.net/p/tclap/bugs/30/
464  throw CmdLineParseException("The args vector must not be empty, "
465  "the first entry should contain the "
466  "program's name.");
467  }
468 
469  _progName = args.front();
470  args.erase(args.begin());
471 
472  int requiredCount = 0;
473 
474  for (int i = 0; static_cast<unsigned int>(i) < args.size(); i++)
475  {
476  bool matched = false;
477  for (ArgListIterator it = _argList.begin();
478  it != _argList.end(); it++) {
479  if ( (*it)->processArg( &i, args ) )
480  {
481  requiredCount += _xorHandler.check( *it );
482  matched = true;
483  break;
484  }
485  }
486 
487  // checks to see if the argument is an empty combined
488  // switch and if so, then we've actually matched it
489  if ( !matched && _emptyCombined( args[i] ) )
490  matched = true;
491 
492  if ( !matched && !Arg::ignoreRest() && !_ignoreUnmatched)
493  throw(CmdLineParseException("Couldn't find match "
494  "for argument",
495  args[i]));
496  }
497 
498  if ( requiredCount < _numRequired )
500 
501  if ( requiredCount > _numRequired )
502  throw(CmdLineParseException("Too many arguments!"));
503 
504  } catch ( ArgException& e ) {
505  // If we're not handling the exceptions, rethrow.
506  if ( !_handleExceptions) {
507  throw;
508  }
509 
510  try {
511  _output->failure(*this,e);
512  } catch ( ExitException &ee ) {
513  estat = ee.getExitStatus();
514  shouldExit = true;
515  }
516  } catch (ExitException &ee) {
517  // If we're not handling the exceptions, rethrow.
518  if ( !_handleExceptions) {
519  throw;
520  }
521 
522  estat = ee.getExitStatus();
523  shouldExit = true;
524  }
525 
526  if (shouldExit)
527  exit(estat);
528 }
529 
530 inline bool CmdLine::_emptyCombined(const std::string& s)
531 {
532  if ( s.length() > 0 && s[0] != Arg::flagStartChar() )
533  return false;
534 
535  for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
536  if ( s[i] != Arg::blankChar() )
537  return false;
538 
539  return true;
540 }
541 
543 {
544  int count = 0;
545 
546  std::string missingArgList;
547  for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
548  {
549  if ( (*it)->isRequired() && !(*it)->isSet() )
550  {
551  missingArgList += (*it)->getName();
552  missingArgList += ", ";
553  count++;
554  }
555  }
556  missingArgList = missingArgList.substr(0,missingArgList.length()-2);
557 
558  std::string msg;
559  if ( count > 1 )
560  msg = "Required arguments missing: ";
561  else
562  msg = "Required argument missing: ";
563 
564  msg += missingArgList;
565 
566  throw(CmdLineParseException(msg));
567 }
568 
569 inline void CmdLine::deleteOnExit(Arg* ptr)
570 {
571  _argDeleteOnExitList.push_back(ptr);
572 }
573 
575 {
576  _visitorDeleteOnExitList.push_back(ptr);
577 }
578 
580 {
581  return _output;
582 }
583 
585 {
586  if ( !_userSetOutput )
587  delete _output;
588  _userSetOutput = true;
589  _output = co;
590 }
591 
592 inline std::string& CmdLine::getVersion()
593 {
594  return _version;
595 }
596 
597 inline std::string& CmdLine::getProgramName()
598 {
599  return _progName;
600 }
601 
602 inline std::list<Arg*>& CmdLine::getArgList()
603 {
604  return _argList;
605 }
606 
608 {
609  return _xorHandler;
610 }
611 
613 {
614  return _delimiter;
615 }
616 
617 inline std::string& CmdLine::getMessage()
618 {
619  return _message;
620 }
621 
623 {
624  return _helpAndVersion;
625 }
626 
627 inline void CmdLine::setExceptionHandling(const bool state)
628 {
629  _handleExceptions = state;
630 }
631 
632 inline bool CmdLine::getExceptionHandling() const
633 {
634  return _handleExceptions;
635 }
636 
637 inline void CmdLine::reset()
638 {
639  for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
640  (*it)->reset();
641 
642  _progName.clear();
643 }
644 
645 inline void CmdLine::ignoreUnmatched(const bool ignore)
646 {
647  _ignoreUnmatched = ignore;
648 }
649 
651 //End CmdLine.cpp
653 
654 
655 
656 } //namespace TCLAP
657 #endif
std::list< Visitor * > _visitorDeleteOnExitList
A list of Visitors to be explicitly deleted when the destructor is called.
Definition: CmdLine.h:125
CmdLineOutput * _output
Object that handles all output for the CmdLine.
Definition: CmdLine.h:130
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:55
std::string _message
A message used to describe the program.
Definition: CmdLine.h:88
void xorAdd(Arg &a, Arg &b)
Add two Args that will be xor&#39;d.
Definition: CmdLine.h:418
std::list< Arg * > _argList
The list of arguments that will be tested against the command line.
Definition: CmdLine.h:78
A simple class that defines and argument exception.
Definition: ArgException.h:37
virtual void failure(CmdLineInterface &c, ArgException &e)=0
Generates some sort of output for a failure.
virtual void addToList(std::list< Arg *> &argList) const
Adds this to the specified list of Args.
Definition: Arg.h:655
std::string _progName
The name of the program.
Definition: CmdLine.h:83
Thrown from CmdLine when the arguments on the command line are not properly specified, e.g.
Definition: ArgException.h:144
static char flagStartChar()
Definition: Arg.h:217
void DelPtr(T ptr)
Definition: CmdLine.h:53
std::string & getProgramName()
Returns the program name string.
Definition: CmdLine.h:597
std::string _version
The version to be displayed with the –version switch.
Definition: CmdLine.h:93
Thrown when TCLAP thinks the program should exit.
Definition: ArgException.h:200
A simple switch argument.
Definition: SwitchArg.h:41
void deleteOnExit(Arg *ptr)
Perform a delete ptr; operation on ptr when this object is deleted.
Definition: CmdLine.h:569
Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
Definition: ArgException.h:168
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: Arg.h:514
void reset()
Allows the CmdLine object to be reused.
Definition: CmdLine.h:637
int check(const Arg *a)
Checks whether the specified Arg is in one of the xor lists and if it does match one, returns the size of the xor list that the Arg matched.
Definition: XorHandler.h:102
virtual bool isRequired() const
Indicates whether the argument is required.
Definition: Arg.h:562
char _delimiter
The character that is used to separate the argument flag/name from the value.
Definition: CmdLine.h:106
A Visitor that will call the version method of the given CmdLineOutput for the specified CmdLine obje...
static const std::string ignoreNameString()
The name used to identify the ignore rest argument.
Definition: Arg.h:241
std::vector< Arg * >::const_iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition: Arg.h:392
int _numRequired
The number of arguments that are required to be present on the command line.
Definition: CmdLine.h:100
virtual ~CmdLine()
Deletes any resources allocated by a CmdLine object.
Definition: CmdLine.h:358
std::list< Arg * > _argDeleteOnExitList
A list of Args to be explicitly deleted when the destructor is called.
Definition: CmdLine.h:118
bool _emptyCombined(const std::string &s)
Checks whether a name/flag string matches entirely matches the Arg::blankChar.
Definition: CmdLine.h:530
A base class that defines the interface for visitors.
Definition: Visitor.h:34
bool getExceptionHandling() const
Returns the current state of the internal exception handling.
Definition: CmdLine.h:632
void add(const std::vector< Arg *> &ors)
Add a list of Arg*&#39;s that will be xor&#39;d together.
Definition: XorHandler.h:97
The base class that manages the command line definition and passes along the parsing to the appropria...
CmdLineOutput * getOutput()
Returns the CmdLineOutput object.
Definition: CmdLine.h:579
void setExceptionHandling(const bool state)
Disables or enables CmdLine&#39;s internal parsing exception handling.
Definition: CmdLine.h:627
A class that isolates any output from the CmdLine object so that it may be easily modified...
Definition: StdOutput.h:44
std::string & getMessage()
Returns the message string.
Definition: CmdLine.h:617
A Visitor object that calls the usage method of the given CmdLineOutput object for the specified CmdL...
Definition: HelpVisitor.h:37
void parse(int argc, const char *const *argv)
Parses the command line.
Definition: CmdLine.h:446
static bool ignoreRest()
Whether to ignore the rest.
Definition: Arg.h:196
A Visitor that tells the CmdLine to begin ignoring arguments after this one is parsed.
void ignoreUnmatched(const bool ignore)
Allows unmatched args to be ignored.
Definition: CmdLine.h:645
bool hasHelpAndVersion()
Indicates whether or not the help and version switches were created automatically.
Definition: CmdLine.h:622
XorHandler _xorHandler
The handler that manages xoring lists of args.
Definition: CmdLine.h:111
std::list< Arg * >::const_iterator ArgListIterator
Typedef of an Arg list iterator.
Definition: Arg.h:387
int getExitStatus() const
Definition: ArgException.h:204
std::string & getVersion()
Returns the version string.
Definition: CmdLine.h:592
void add(Arg &a)
Adds an argument to the list of arguments to be parsed.
Definition: CmdLine.h:426
void setOutput(CmdLineOutput *co)
Definition: CmdLine.h:584
static char blankChar()
The char used as a place holder when SwitchArgs are combined.
Definition: Arg.h:208
char getDelimiter()
Returns the delimiter string.
Definition: CmdLine.h:612
std::list< Arg * > & getArgList()
Returns the argList.
Definition: CmdLine.h:602
Definition: Arg.h:48
The base class that manages the command line definition and passes along the parsing to the appropria...
Definition: CmdLine.h:70
void missingArgsException()
Throws an exception listing the missing args.
Definition: CmdLine.h:542
XorHandler & getXorHandler()
Returns the XorHandler.
Definition: CmdLine.h:607
bool _handleExceptions
Should CmdLine handle parsing exceptions internally?
Definition: CmdLine.h:135
static const std::string flagStartString()
Definition: Arg.h:227
This class handles lists of Arg&#39;s that are to be XOR&#39;d on the command line.
Definition: XorHandler.h:40
void ClearContainer(C &c)
Definition: CmdLine.h:58
static void setDelimiter(char c)
Sets the delimiter for all arguments.
Definition: Arg.h:247
The interface that any output object must implement.
Definition: CmdLineOutput.h:44