tclap 1.2.5
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>
31
32#include <tclap/XorHandler.h>
33#include <tclap/HelpVisitor.h>
36
37#include <tclap/CmdLineOutput.h>
38#include <tclap/StdOutput.h>
39
40#include <tclap/Constraint.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
51namespace TCLAP {
52
53template<typename T> void DelPtr(T ptr)
54{
55 delete ptr;
56}
57
58template<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
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
141
148 bool _emptyCombined(const std::string& s);
149
153 void deleteOnExit(Arg* ptr);
154
158 void deleteOnExit(Visitor* ptr);
159
160private:
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
335inline 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),
346 _xorHandler(XorHandler()),
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
369inline 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
406inline 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
418inline 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
426inline void CmdLine::add( Arg& a )
427{
428 add( &a );
429}
430
431inline void CmdLine::add( Arg* a )
432{
433 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
434 if ( *a == *(*it) )
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
446inline 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
457inline 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
530inline 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
569inline 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
592inline std::string& CmdLine::getVersion()
593{
594 return _version;
595}
596
597inline std::string& CmdLine::getProgramName()
598{
599 return _progName;
600}
601
602inline std::list<Arg*>& CmdLine::getArgList()
603{
604 return _argList;
605}
606
608{
609 return _xorHandler;
610}
611
613{
614 return _delimiter;
615}
616
617inline std::string& CmdLine::getMessage()
618{
619 return _message;
620}
621
623{
624 return _helpAndVersion;
625}
626
627inline void CmdLine::setExceptionHandling(const bool state)
628{
629 _handleExceptions = state;
630}
631
633{
634 return _handleExceptions;
635}
636
637inline void CmdLine::reset()
638{
639 for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ )
640 (*it)->reset();
641
642 _progName.clear();
643}
644
645inline void CmdLine::ignoreUnmatched(const bool ignore)
646{
647 _ignoreUnmatched = ignore;
648}
649
651//End CmdLine.cpp
653
654
655
656} //namespace TCLAP
657#endif
A simple class that defines and argument exception.
A virtual base class that defines the essential data for all arguments.
Definition Arg.h:56
static char blankChar()
The char used as a place holder when SwitchArgs are combined.
Definition Arg.h:208
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition Arg.h:514
static bool ignoreRest()
Whether to ignore the rest.
Definition Arg.h:196
static const std::string ignoreNameString()
The name used to identify the ignore rest argument.
Definition Arg.h:241
static char flagStartChar()
Definition Arg.h:217
virtual void addToList(std::list< Arg * > &argList) const
Adds this to the specified list of Args.
Definition Arg.h:655
static void setDelimiter(char c)
Sets the delimiter for all arguments.
Definition Arg.h:247
virtual bool isRequired() const
Indicates whether the argument is required.
Definition Arg.h:562
static const std::string flagStartString()
Definition Arg.h:227
The base class that manages the command line definition and passes along the parsing to the appropria...
The interface that any output object must implement.
virtual void failure(CmdLineInterface &c, ArgException &e)=0
Generates some sort of output for a failure.
Thrown from CmdLine when the arguments on the command line are not properly specified,...
The base class that manages the command line definition and passes along the parsing to the appropria...
Definition CmdLine.h:71
bool _emptyCombined(const std::string &s)
Checks whether a name/flag string matches entirely matches the Arg::blankChar.
Definition CmdLine.h:530
void reset()
Allows the CmdLine object to be reused.
Definition CmdLine.h:637
int _numRequired
The number of arguments that are required to be present on the command line.
Definition CmdLine.h:100
std::string _version
The version to be displayed with the –version switch.
Definition CmdLine.h:93
XorHandler _xorHandler
The handler that manages xoring lists of args.
Definition CmdLine.h:111
bool _handleExceptions
Should CmdLine handle parsing exceptions internally?
Definition CmdLine.h:135
std::list< Arg * > & getArgList()
Returns the argList.
Definition CmdLine.h:602
std::string _message
A message used to describe the program.
Definition CmdLine.h:88
char getDelimiter()
Returns the delimiter string.
Definition CmdLine.h:612
void deleteOnExit(Arg *ptr)
Perform a delete ptr; operation on ptr when this object is deleted.
Definition CmdLine.h:569
void setOutput(CmdLineOutput *co)
Definition CmdLine.h:584
std::string & getProgramName()
Returns the program name string.
Definition CmdLine.h:597
std::list< Arg * > _argList
The list of arguments that will be tested against the command line.
Definition CmdLine.h:78
CmdLineOutput * _output
Object that handles all output for the CmdLine.
Definition CmdLine.h:130
bool hasHelpAndVersion()
Indicates whether or not the help and version switches were created automatically.
Definition CmdLine.h:622
char _delimiter
The character that is used to separate the argument flag/name from the value.
Definition CmdLine.h:106
void ignoreUnmatched(const bool ignore)
Allows unmatched args to be ignored.
Definition CmdLine.h:645
void missingArgsException()
Throws an exception listing the missing args.
Definition CmdLine.h:542
std::list< Visitor * > _visitorDeleteOnExitList
A list of Visitors to be explicitly deleted when the destructor is called.
Definition CmdLine.h:125
XorHandler & getXorHandler()
Returns the XorHandler.
Definition CmdLine.h:607
std::string & getVersion()
Returns the version string.
Definition CmdLine.h:592
virtual ~CmdLine()
Deletes any resources allocated by a CmdLine object.
Definition CmdLine.h:358
std::string _progName
The name of the program.
Definition CmdLine.h:83
std::string & getMessage()
Returns the message string.
Definition CmdLine.h:617
void add(Arg &a)
Adds an argument to the list of arguments to be parsed.
Definition CmdLine.h:426
void setExceptionHandling(const bool state)
Disables or enables CmdLine's internal parsing exception handling.
Definition CmdLine.h:627
bool getExceptionHandling() const
Returns the current state of the internal exception handling.
Definition CmdLine.h:632
void parse(int argc, const char *const *argv)
Parses the command line.
Definition CmdLine.h:446
CmdLineOutput * getOutput()
Returns the CmdLineOutput object.
Definition CmdLine.h:579
std::list< Arg * > _argDeleteOnExitList
A list of Args to be explicitly deleted when the destructor is called.
Definition CmdLine.h:118
void xorAdd(Arg &a, Arg &b)
Add two Args that will be xor'd.
Definition CmdLine.h:418
Thrown when TCLAP thinks the program should exit.
int getExitStatus() const
A Visitor object that calls the usage method of the given CmdLineOutput object for the specified CmdL...
Definition HelpVisitor.h:38
Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
A class that isolates any output from the CmdLine object so that it may be easily modified.
Definition StdOutput.h:45
A simple switch argument.
Definition SwitchArg.h:42
A Visitor that will call the version method of the given CmdLineOutput for the specified CmdLine obje...
A base class that defines the interface for visitors.
Definition Visitor.h:35
This class handles lists of Arg's that are to be XOR'd on the command line.
Definition XorHandler.h:41
int check(const Arg *a)
Checks whether the specified Arg is in one of the xor lists and if it does match one,...
Definition XorHandler.h:102
void add(const std::vector< Arg * > &ors)
Add a list of Arg*'s that will be xor'd together.
Definition XorHandler.h:97
Definition Arg.h:48
std::vector< Arg * >::const_iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition Arg.h:392
void DelPtr(T ptr)
Definition CmdLine.h:53
std::list< Arg * >::const_iterator ArgListIterator
Typedef of an Arg list iterator.
Definition Arg.h:387
void ClearContainer(C &c)
Definition CmdLine.h:58