tclap  1.2.2
Arg.h
Go to the documentation of this file.
1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2 
3 /******************************************************************************
4  *
5  * file: Arg.h
6  *
7  * Copyright (c) 2003, Michael E. Smoot .
8  * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno .
9  * Copyright (c) 2017 Google Inc.
10  * All rights reserved.
11  *
12  * See the file COPYING in the top directory of this distribution for
13  * more information.
14  *
15  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  *****************************************************************************/
24 
25 
26 #ifndef TCLAP_ARGUMENT_H
27 #define TCLAP_ARGUMENT_H
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 #include <string>
34 #include <vector>
35 #include <list>
36 #include <iostream>
37 #include <iomanip>
38 #include <cstdio>
39 
40 #include <tclap/sstream.h>
41 
42 #if defined(HAVE_SSTREAM)
43 #include <sstream>
45 #elif defined(HAVE_STRSTREAM)
46 #include <strstream>
47 typedef std::istrstream istringstream;
48 #else
49 #error "Need a stringstream (sstream or strstream) to compile!"
50 #endif
51 
52 #include <tclap/ArgException.h>
53 #include <tclap/Visitor.h>
54 #include <tclap/CmdLineInterface.h>
55 #include <tclap/ArgTraits.h>
56 #include <tclap/StandardTraits.h>
57 
58 namespace TCLAP {
59 
65 class Arg
66 {
67  private:
71  Arg(const Arg& rhs);
72 
76  Arg& operator=(const Arg& rhs);
77 
81  static bool& ignoreRestRef() { static bool ign = false; return ign; }
82 
87  static char& delimiterRef() { static char delim = ' '; return delim; }
88 
89  protected:
90 
99  std::string _flag;
100 
108  std::string _name;
109 
113  std::string _description;
114 
118  bool _required;
119 
124  std::string _requireLabel;
125 
132 
139 
147 
152 
157  bool _xorSet;
158 
160 
164  void _checkWithVisitor() const;
165 
179  Arg( const std::string& flag,
180  const std::string& name,
181  const std::string& desc,
182  bool req,
183  bool valreq,
184  Visitor* v = NULL );
185 
186  public:
190  virtual ~Arg();
191 
196  virtual void addToList( std::list<Arg*>& argList ) const;
197 
201  static void beginIgnoring() { ignoreRestRef() = true; }
202 
206  static bool ignoreRest() { return ignoreRestRef(); }
207 
212  static char delimiter() { return delimiterRef(); }
213 
218  static char blankChar() { return (char)7; }
219 
224 #ifndef TCLAP_FLAGSTARTCHAR
225 #define TCLAP_FLAGSTARTCHAR '-'
226 #endif
227  static char flagStartChar() { return TCLAP_FLAGSTARTCHAR; }
228 
234 #ifndef TCLAP_FLAGSTARTSTRING
235 #define TCLAP_FLAGSTARTSTRING "-"
236 #endif
237  static const std::string flagStartString() { return TCLAP_FLAGSTARTSTRING; }
238 
243 #ifndef TCLAP_NAMESTARTSTRING
244 #define TCLAP_NAMESTARTSTRING "--"
245 #endif
246  static const std::string nameStartString() { return TCLAP_NAMESTARTSTRING; }
247 
251  static const std::string ignoreNameString() { return "ignore_rest"; }
252 
257  static void setDelimiter( char c ) { delimiterRef() = c; }
258 
266  virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
267 
273  virtual bool operator==(const Arg& a) const;
274 
278  const std::string& getFlag() const;
279 
283  const std::string& getName() const;
284 
288  std::string getDescription() const;
289 
293  virtual bool isRequired() const;
294 
299  void forceRequired();
300 
305  void xorSet();
306 
310  bool isValueRequired() const;
311 
316  bool isSet() const;
317 
321  bool isIgnoreable() const;
322 
331  virtual bool argMatches( const std::string& s ) const;
332 
337  virtual std::string toString() const;
338 
343  virtual std::string shortID( const std::string& valueId = "val" ) const;
344 
349  virtual std::string longID( const std::string& valueId = "val" ) const;
350 
358  virtual void trimFlag( std::string& flag, std::string& value ) const;
359 
366  bool _hasBlanks( const std::string& s ) const;
367 
373  void setRequireLabel( const std::string& s );
374 
379  virtual bool allowMore();
380 
385  virtual bool acceptsMultipleValues();
386 
391  virtual void reset();
392 };
393 
397 typedef std::list<Arg*>::iterator ArgListIterator;
398 
402 typedef std::vector<Arg*>::iterator ArgVectorIterator;
403 
407 typedef std::list<Visitor*>::iterator VisitorListIterator;
408 
409 /*
410  * Extract a value of type T from it's string representation contained
411  * in strVal. The ValueLike parameter used to select the correct
412  * specialization of ExtractValue depending on the value traits of T.
413  * ValueLike traits use operator>> to assign the value from strVal.
414  */
415 template<typename T> void
416 ExtractValue(T &destVal, const std::string& strVal, ValueLike vl)
417 {
418  static_cast<void>(vl); // Avoid warning about unused vl
419  istringstream is(strVal.c_str());
420 
421  int valuesRead = 0;
422  while ( is.good() ) {
423  if ( is.peek() != EOF )
424 #ifdef TCLAP_SETBASE_ZERO
425  is >> std::setbase(0) >> destVal;
426 #else
427  is >> destVal;
428 #endif
429  else
430  break;
431 
432  valuesRead++;
433  }
434 
435  if ( is.fail() )
436  throw( ArgParseException("Couldn't read argument value "
437  "from string '" + strVal + "'"));
438 
439 
440  if ( valuesRead > 1 )
441  throw( ArgParseException("More than one valid value parsed from "
442  "string '" + strVal + "'"));
443 
444 }
445 
446 /*
447  * Extract a value of type T from it's string representation contained
448  * in strVal. The ValueLike parameter used to select the correct
449  * specialization of ExtractValue depending on the value traits of T.
450  * StringLike uses assignment (operator=) to assign from strVal.
451  */
452 template<typename T> void
453 ExtractValue(T &destVal, const std::string& strVal, StringLike sl)
454 {
455  static_cast<void>(sl); // Avoid warning about unused sl
456  SetString(destVal, strVal);
457 }
458 
460 //BEGIN Arg.cpp
462 
463 inline Arg::Arg(const std::string& flag,
464  const std::string& name,
465  const std::string& desc,
466  bool req,
467  bool valreq,
468  Visitor* v) :
469  _flag(flag),
470  _name(name),
471  _description(desc),
472  _required(req),
473  _requireLabel("required"),
474  _valueRequired(valreq),
475  _alreadySet(false),
476  _visitor( v ),
477  _ignoreable(true),
478  _xorSet(false),
479  _acceptsMultipleValues(false)
480 {
481  if ( _flag.length() > 1 )
483  "Argument flag can only be one character long", toString() ) );
484 
485  if ( _name != ignoreNameString() &&
486  ( _flag == Arg::flagStartString() ||
488  _flag == " " ) )
489  throw(SpecificationException("Argument flag cannot be either '" +
490  Arg::flagStartString() + "' or '" +
491  Arg::nameStartString() + "' or a space.",
492  toString() ) );
493 
494  if ( ( _name.substr( 0, Arg::flagStartString().length() ) == Arg::flagStartString() ) ||
495  ( _name.substr( 0, Arg::nameStartString().length() ) == Arg::nameStartString() ) ||
496  ( _name.find( " ", 0 ) != std::string::npos ) )
497  throw(SpecificationException("Argument name begin with either '" +
498  Arg::flagStartString() + "' or '" +
499  Arg::nameStartString() + "' or space.",
500  toString() ) );
501 
502 }
503 
504 inline Arg::~Arg() { }
505 
506 inline std::string Arg::shortID( const std::string& valueId ) const
507 {
508  std::string id = "";
509 
510  if ( _flag != "" )
511  id = Arg::flagStartString() + _flag;
512  else
513  id = Arg::nameStartString() + _name;
514 
515  if ( _valueRequired )
516  id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
517 
518  if ( !_required )
519  id = "[" + id + "]";
520 
521  return id;
522 }
523 
524 inline std::string Arg::longID( const std::string& valueId ) const
525 {
526  std::string id = "";
527 
528  if ( _flag != "" )
529  {
530  id += Arg::flagStartString() + _flag;
531 
532  if ( _valueRequired )
533  id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
534 
535  id += ", ";
536  }
537 
538  id += Arg::nameStartString() + _name;
539 
540  if ( _valueRequired )
541  id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
542 
543  return id;
544 
545 }
546 
547 inline bool Arg::operator==(const Arg& a) const
548 {
549  if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
550  return true;
551  else
552  return false;
553 }
554 
555 inline std::string Arg::getDescription() const
556 {
557  std::string desc = "";
558  if ( _required )
559  desc = "(" + _requireLabel + ") ";
560 
561 // if ( _valueRequired )
562 // desc += "(value required) ";
563 
564  desc += _description;
565  return desc;
566 }
567 
568 inline const std::string& Arg::getFlag() const { return _flag; }
569 
570 inline const std::string& Arg::getName() const { return _name; }
571 
572 inline bool Arg::isRequired() const { return _required; }
573 
574 inline bool Arg::isValueRequired() const { return _valueRequired; }
575 
576 inline bool Arg::isSet() const
577 {
578  if ( _alreadySet && !_xorSet )
579  return true;
580  else
581  return false;
582 }
583 
584 inline bool Arg::isIgnoreable() const { return _ignoreable; }
585 
586 inline void Arg::setRequireLabel( const std::string& s)
587 {
588  _requireLabel = s;
589 }
590 
591 inline bool Arg::argMatches( const std::string& argFlag ) const
592 {
593  if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
594  argFlag == Arg::nameStartString() + _name )
595  return true;
596  else
597  return false;
598 }
599 
600 inline std::string Arg::toString() const
601 {
602  std::string s = "";
603 
604  if ( _flag != "" )
605  s += Arg::flagStartString() + _flag + " ";
606 
607  s += "(" + Arg::nameStartString() + _name + ")";
608 
609  return s;
610 }
611 
612 inline void Arg::_checkWithVisitor() const
613 {
614  if ( _visitor != NULL )
615  _visitor->visit();
616 }
617 
621 inline void Arg::trimFlag(std::string& flag, std::string& value) const
622 {
623  int stop = 0;
624  for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
625  if ( flag[i] == Arg::delimiter() )
626  {
627  stop = i;
628  break;
629  }
630 
631  if ( stop > 1 )
632  {
633  value = flag.substr(stop+1);
634  flag = flag.substr(0,stop);
635  }
636 
637 }
638 
642 inline bool Arg::_hasBlanks( const std::string& s ) const
643 {
644  for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
645  if ( s[i] == Arg::blankChar() )
646  return true;
647 
648  return false;
649 }
650 
651 inline void Arg::forceRequired()
652 {
653  _required = true;
654 }
655 
656 inline void Arg::xorSet()
657 {
658  _alreadySet = true;
659  _xorSet = true;
660 }
661 
665 inline void Arg::addToList( std::list<Arg*>& argList ) const
666 {
667  argList.push_front( const_cast<Arg*>(this) );
668 }
669 
670 inline bool Arg::allowMore()
671 {
672  return false;
673 }
674 
676 {
677  return _acceptsMultipleValues;
678 }
679 
680 inline void Arg::reset()
681 {
682  _xorSet = false;
683  _alreadySet = false;
684 }
685 
687 //END Arg.cpp
689 
690 } //namespace TCLAP
691 
692 #endif
693 
bool _alreadySet
Indicates whether the argument has been set.
Definition: Arg.h:138
bool _required
Indicating whether the argument is required.
Definition: Arg.h:118
bool _valueRequired
Indicates whether a value is required for the argument.
Definition: Arg.h:131
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:65
virtual void trimFlag(std::string &flag, std::string &value) const
Trims a value off of the flag.
Definition: Arg.h:621
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: Arg.h:524
bool isIgnoreable() const
Indicates whether the argument can be ignored, if desired.
Definition: Arg.h:584
bool _hasBlanks(const std::string &s) const
Checks whether a given string has blank chars, indicating that it is a combined SwitchArg.
Definition: Arg.h:642
std::string getDescription() const
Returns the argument description.
Definition: Arg.h:555
void xorSet()
Sets the _alreadySet value to true.
Definition: Arg.h:656
void SetString(T &dst, const std::string &src)
A value like argument value type is a value that can be set using operator>>.
Definition: ArgTraits.h:38
void setRequireLabel(const std::string &s)
Sets the requireLabel.
Definition: Arg.h:586
static char flagStartChar()
Definition: Arg.h:227
virtual void addToList(std::list< Arg * > &argList) const
Adds this to the specified list of Args.
Definition: Arg.h:665
void _checkWithVisitor() const
Performs the special handling described by the Visitor.
Definition: Arg.h:612
virtual void reset()
Clears the Arg object and allows it to be reused by new command lines.
Definition: Arg.h:680
bool _xorSet
Indicates that the arg was set as part of an XOR and not on the command line.
Definition: Arg.h:157
std::istringstream istringstream
Definition: sstream.h:37
const std::string & getName() const
Returns the argument name.
Definition: Arg.h:570
Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
Definition: ArgException.h:167
static char delimiter()
The delimiter that separates an argument flag/name from the value.
Definition: Arg.h:212
bool isValueRequired() const
Indicates whether a value must be specified for argument.
Definition: Arg.h:574
virtual ~Arg()
Destructor.
Definition: Arg.h:504
std::list< Visitor * >::iterator VisitorListIterator
Typedef of a Visitor list iterator.
Definition: Arg.h:407
#define TCLAP_FLAGSTARTCHAR
The char that indicates the beginning of a flag.
Definition: Arg.h:225
A string like argument value type is a value that can be set using operator=(string).
Definition: ArgTraits.h:48
const std::string & getFlag() const
Returns the argument flag.
Definition: Arg.h:568
Visitor * _visitor
A pointer to a visitor object.
Definition: Arg.h:146
bool isSet() const
Indicates whether the argument has already been set.
Definition: Arg.h:576
static const std::string ignoreNameString()
The name used to identify the ignore rest argument.
Definition: Arg.h:251
static const std::string nameStartString()
Definition: Arg.h:246
#define TCLAP_NAMESTARTSTRING
The sting that indicates the beginning of a name.
Definition: Arg.h:244
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition: Arg.h:506
A base class that defines the interface for visitors.
Definition: Visitor.h:31
virtual bool operator==(const Arg &a) const
Operator ==.
Definition: Arg.h:547
std::string _description
Description of the argument.
Definition: Arg.h:113
std::list< Arg * >::iterator ArgListIterator
Typedef of an Arg list iterator.
Definition: Arg.h:397
virtual bool acceptsMultipleValues()
Use by output classes to determine whether an Arg accepts multiple values.
Definition: Arg.h:675
bool _ignoreable
Whether this argument can be ignored, if desired.
Definition: Arg.h:151
std::vector< Arg * >::iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition: Arg.h:402
virtual bool processArg(int *i, std::vector< std::string > &args)=0
Pure virtual method meant to handle the parsing and value assignment of the string on the command lin...
static void beginIgnoring()
Begin ignoring arguments since the "--" argument was specified.
Definition: Arg.h:201
static bool ignoreRest()
Whether to ignore the rest.
Definition: Arg.h:206
void ExtractValue(T &destVal, const std::string &strVal, ValueLike vl)
Definition: Arg.h:416
virtual bool argMatches(const std::string &s) const
A method that tests whether a string matches this argument.
Definition: Arg.h:591
virtual void visit()
Does nothing.
Definition: Visitor.h:48
std::string _name
A single word namd identifying the argument.
Definition: Arg.h:108
static char blankChar()
The char used as a place holder when SwitchArgs are combined.
Definition: Arg.h:218
std::string _flag
The single char flag used to identify the argument.
Definition: Arg.h:99
bool _acceptsMultipleValues
Definition: Arg.h:159
Thrown from within the child Arg classes when it fails to properly parse the argument it has been pas...
Definition: ArgException.h:121
void forceRequired()
Sets _required to true.
Definition: Arg.h:651
Definition: Arg.h:58
virtual bool allowMore()
Used for MultiArgs and XorHandler to determine whether args can still be set.
Definition: Arg.h:670
virtual std::string toString() const
Returns a simple string representation of the argument.
Definition: Arg.h:600
#define TCLAP_FLAGSTARTSTRING
The sting that indicates the beginning of a flag.
Definition: Arg.h:235
std::string _requireLabel
Label to be used in usage description.
Definition: Arg.h:124
static const std::string flagStartString()
Definition: Arg.h:237
static void setDelimiter(char c)
Sets the delimiter for all arguments.
Definition: Arg.h:257
virtual bool isRequired() const
Indicates whether the argument is required.
Definition: Arg.h:572