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 #include <tclap/ArgException.h>
43 #include <tclap/Visitor.h>
44 #include <tclap/CmdLineInterface.h>
45 #include <tclap/ArgTraits.h>
46 #include <tclap/StandardTraits.h>
47 
48 namespace TCLAP {
49 
55 class Arg
56 {
57  private:
61  Arg(const Arg& rhs);
62 
66  Arg& operator=(const Arg& rhs);
67 
71  static bool& ignoreRestRef() { static bool ign = false; return ign; }
72 
77  static char& delimiterRef() { static char delim = ' '; return delim; }
78 
79  protected:
80 
89  std::string _flag;
90 
98  std::string _name;
99 
103  std::string _description;
104 
108  bool _required;
109 
114  std::string _requireLabel;
115 
122 
129 
137 
142 
147  bool _xorSet;
148 
150 
154  void _checkWithVisitor() const;
155 
169  Arg( const std::string& flag,
170  const std::string& name,
171  const std::string& desc,
172  bool req,
173  bool valreq,
174  Visitor* v = NULL );
175 
176  public:
180  virtual ~Arg();
181 
186  virtual void addToList( std::list<Arg*>& argList ) const;
187 
191  static void beginIgnoring() { ignoreRestRef() = true; }
192 
196  static bool ignoreRest() { return ignoreRestRef(); }
197 
202  static char delimiter() { return delimiterRef(); }
203 
208  static char blankChar() { return (char)7; }
209 
214 #ifndef TCLAP_FLAGSTARTCHAR
215 #define TCLAP_FLAGSTARTCHAR '-'
216 #endif
217  static char flagStartChar() { return TCLAP_FLAGSTARTCHAR; }
218 
224 #ifndef TCLAP_FLAGSTARTSTRING
225 #define TCLAP_FLAGSTARTSTRING "-"
226 #endif
227  static const std::string flagStartString() { return TCLAP_FLAGSTARTSTRING; }
228 
233 #ifndef TCLAP_NAMESTARTSTRING
234 #define TCLAP_NAMESTARTSTRING "--"
235 #endif
236  static const std::string nameStartString() { return TCLAP_NAMESTARTSTRING; }
237 
241  static const std::string ignoreNameString() { return "ignore_rest"; }
242 
247  static void setDelimiter( char c ) { delimiterRef() = c; }
248 
256  virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
257 
263  virtual bool operator==(const Arg& a) const;
264 
268  const std::string& getFlag() const;
269 
273  const std::string& getName() const;
274 
278  std::string getDescription() const;
279 
283  virtual bool isRequired() const;
284 
289  void forceRequired();
290 
295  void xorSet();
296 
300  bool isValueRequired() const;
301 
306  bool isSet() const;
307 
311  bool isIgnoreable() const;
312 
321  virtual bool argMatches( const std::string& s ) const;
322 
327  virtual std::string toString() const;
328 
333  virtual std::string shortID( const std::string& valueId = "val" ) const;
334 
339  virtual std::string longID( const std::string& valueId = "val" ) const;
340 
348  virtual void trimFlag( std::string& flag, std::string& value ) const;
349 
356  bool _hasBlanks( const std::string& s ) const;
357 
363  void setRequireLabel( const std::string& s );
364 
369  virtual bool allowMore();
370 
375  virtual bool acceptsMultipleValues();
376 
381  virtual void reset();
382 };
383 
387 typedef std::list<Arg*>::const_iterator ArgListIterator;
388 
392 typedef std::vector<Arg*>::const_iterator ArgVectorIterator;
393 
397 typedef std::list<Visitor*>::const_iterator VisitorListIterator;
398 
399 /*
400  * Extract a value of type T from it's string representation contained
401  * in strVal. The ValueLike parameter used to select the correct
402  * specialization of ExtractValue depending on the value traits of T.
403  * ValueLike traits use operator>> to assign the value from strVal.
404  */
405 template<typename T> void
406 ExtractValue(T &destVal, const std::string& strVal, ValueLike vl)
407 {
408  static_cast<void>(vl); // Avoid warning about unused vl
409  istringstream is(strVal.c_str());
410 
411  int valuesRead = 0;
412  while ( is.good() ) {
413  if ( is.peek() != EOF )
414 #ifdef TCLAP_SETBASE_ZERO
415  is >> std::setbase(0) >> destVal;
416 #else
417  is >> destVal;
418 #endif
419  else
420  break;
421 
422  valuesRead++;
423  }
424 
425  if ( is.fail() )
426  throw( ArgParseException("Couldn't read argument value "
427  "from string '" + strVal + "'"));
428 
429 
430  if ( valuesRead > 1 )
431  throw( ArgParseException("More than one valid value parsed from "
432  "string '" + strVal + "'"));
433 
434 }
435 
436 /*
437  * Extract a value of type T from it's string representation contained
438  * in strVal. The ValueLike parameter used to select the correct
439  * specialization of ExtractValue depending on the value traits of T.
440  * StringLike uses assignment (operator=) to assign from strVal.
441  */
442 template<typename T> void
443 ExtractValue(T &destVal, const std::string& strVal, StringLike sl)
444 {
445  static_cast<void>(sl); // Avoid warning about unused sl
446  SetString(destVal, strVal);
447 }
448 
450 //BEGIN Arg.cpp
452 
453 inline Arg::Arg(const std::string& flag,
454  const std::string& name,
455  const std::string& desc,
456  bool req,
457  bool valreq,
458  Visitor* v) :
459  _flag(flag),
460  _name(name),
461  _description(desc),
462  _required(req),
463  _requireLabel("required"),
464  _valueRequired(valreq),
465  _alreadySet(false),
466  _visitor( v ),
467  _ignoreable(true),
468  _xorSet(false),
470 {
471  if ( _flag.length() > 1 )
473  "Argument flag can only be one character long", toString() ) );
474 
475  if ( _name != ignoreNameString() &&
476  ( _flag == Arg::flagStartString() ||
478  _flag == " " ) )
479  throw(SpecificationException("Argument flag cannot be either '" +
480  Arg::flagStartString() + "' or '" +
481  Arg::nameStartString() + "' or a space.",
482  toString() ) );
483 
484  if ( ( _name.substr( 0, Arg::flagStartString().length() ) == Arg::flagStartString() ) ||
485  ( _name.substr( 0, Arg::nameStartString().length() ) == Arg::nameStartString() ) ||
486  ( _name.find( " ", 0 ) != std::string::npos ) )
487  throw(SpecificationException("Argument name begin with either '" +
488  Arg::flagStartString() + "' or '" +
489  Arg::nameStartString() + "' or space.",
490  toString() ) );
491 
492 }
493 
494 inline Arg::~Arg() { }
495 
496 inline std::string Arg::shortID( const std::string& valueId ) const
497 {
498  std::string id = "";
499 
500  if ( _flag != "" )
501  id = Arg::flagStartString() + _flag;
502  else
503  id = Arg::nameStartString() + _name;
504 
505  if ( _valueRequired )
506  id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
507 
508  if ( !_required )
509  id = "[" + id + "]";
510 
511  return id;
512 }
513 
514 inline std::string Arg::longID( const std::string& valueId ) const
515 {
516  std::string id = "";
517 
518  if ( _flag != "" )
519  {
520  id += Arg::flagStartString() + _flag;
521 
522  if ( _valueRequired )
523  id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
524 
525  id += ", ";
526  }
527 
528  id += Arg::nameStartString() + _name;
529 
530  if ( _valueRequired )
531  id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
532 
533  return id;
534 
535 }
536 
537 inline bool Arg::operator==(const Arg& a) const
538 {
539  if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
540  return true;
541  else
542  return false;
543 }
544 
545 inline std::string Arg::getDescription() const
546 {
547  std::string desc = "";
548  if ( _required )
549  desc = "(" + _requireLabel + ") ";
550 
551 // if ( _valueRequired )
552 // desc += "(value required) ";
553 
554  desc += _description;
555  return desc;
556 }
557 
558 inline const std::string& Arg::getFlag() const { return _flag; }
559 
560 inline const std::string& Arg::getName() const { return _name; }
561 
562 inline bool Arg::isRequired() const { return _required; }
563 
564 inline bool Arg::isValueRequired() const { return _valueRequired; }
565 
566 inline bool Arg::isSet() const
567 {
568  if ( _alreadySet && !_xorSet )
569  return true;
570  else
571  return false;
572 }
573 
574 inline bool Arg::isIgnoreable() const { return _ignoreable; }
575 
576 inline void Arg::setRequireLabel( const std::string& s)
577 {
578  _requireLabel = s;
579 }
580 
581 inline bool Arg::argMatches( const std::string& argFlag ) const
582 {
583  if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
584  argFlag == Arg::nameStartString() + _name )
585  return true;
586  else
587  return false;
588 }
589 
590 inline std::string Arg::toString() const
591 {
592  std::string s = "";
593 
594  if ( _flag != "" )
595  s += Arg::flagStartString() + _flag + " ";
596 
597  s += "(" + Arg::nameStartString() + _name + ")";
598 
599  return s;
600 }
601 
602 inline void Arg::_checkWithVisitor() const
603 {
604  if ( _visitor != NULL )
605  _visitor->visit();
606 }
607 
611 inline void Arg::trimFlag(std::string& flag, std::string& value) const
612 {
613  int stop = 0;
614  for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
615  if ( flag[i] == Arg::delimiter() )
616  {
617  stop = i;
618  break;
619  }
620 
621  if ( stop > 1 )
622  {
623  value = flag.substr(stop+1);
624  flag = flag.substr(0,stop);
625  }
626 
627 }
628 
632 inline bool Arg::_hasBlanks( const std::string& s ) const
633 {
634  for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
635  if ( s[i] == Arg::blankChar() )
636  return true;
637 
638  return false;
639 }
640 
641 inline void Arg::forceRequired()
642 {
643  _required = true;
644 }
645 
646 inline void Arg::xorSet()
647 {
648  _alreadySet = true;
649  _xorSet = true;
650 }
651 
655 inline void Arg::addToList( std::list<Arg*>& argList ) const
656 {
657  argList.push_front( const_cast<Arg*>(this) );
658 }
659 
660 inline bool Arg::allowMore()
661 {
662  return false;
663 }
664 
666 {
667  return _acceptsMultipleValues;
668 }
669 
670 inline void Arg::reset()
671 {
672  _xorSet = false;
673  _alreadySet = false;
674 }
675 
677 //END Arg.cpp
679 
680 } //namespace TCLAP
681 
682 #endif
683 
virtual bool argMatches(const std::string &s) const
A method that tests whether a string matches this argument.
Definition: Arg.h:581
bool _alreadySet
Indicates whether the argument has been set.
Definition: Arg.h:128
bool _required
Indicating whether the argument is required.
Definition: Arg.h:108
bool _valueRequired
Indicates whether a value is required for the argument.
Definition: Arg.h:121
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:55
virtual void visit()=0
This method (to implemented by children) will be called when the visitor is visited.
void xorSet()
Sets the _alreadySet value to true.
Definition: Arg.h:646
void SetString(T &dst, const std::string &src)
virtual void addToList(std::list< Arg *> &argList) const
Adds this to the specified list of Args.
Definition: Arg.h:655
A value like argument value type is a value that can be set using operator>>.
Definition: ArgTraits.h:39
void setRequireLabel(const std::string &s)
Sets the requireLabel.
Definition: Arg.h:576
static char flagStartChar()
Definition: Arg.h:217
virtual void reset()
Clears the Arg object and allows it to be reused by new command lines.
Definition: Arg.h:670
bool _xorSet
Indicates that the arg was set as part of an XOR and not on the command line.
Definition: Arg.h:147
std::istringstream istringstream
Definition: sstream.h:37
bool isSet() const
Indicates whether the argument has already been set.
Definition: Arg.h:566
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
static char delimiter()
The delimiter that separates an argument flag/name from the value.
Definition: Arg.h:202
virtual ~Arg()
Destructor.
Definition: Arg.h:494
std::list< Visitor * >::const_iterator VisitorListIterator
Typedef of a Visitor list iterator.
Definition: Arg.h:397
#define TCLAP_FLAGSTARTCHAR
The char that indicates the beginning of a flag.
Definition: Arg.h:215
A string like argument value type is a value that can be set using operator=(string).
Definition: ArgTraits.h:49
virtual bool isRequired() const
Indicates whether the argument is required.
Definition: Arg.h:562
Visitor * _visitor
A pointer to a visitor object.
Definition: Arg.h:136
void _checkWithVisitor() const
Performs the special handling described by the Visitor.
Definition: Arg.h:602
static const std::string ignoreNameString()
The name used to identify the ignore rest argument.
Definition: Arg.h:241
static const std::string nameStartString()
Definition: Arg.h:236
#define TCLAP_NAMESTARTSTRING
The sting that indicates the beginning of a name.
Definition: Arg.h:234
std::vector< Arg * >::const_iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition: Arg.h:392
A base class that defines the interface for visitors.
Definition: Visitor.h:34
const std::string & getName() const
Returns the argument name.
Definition: Arg.h:560
std::string _description
Description of the argument.
Definition: Arg.h:103
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition: Arg.h:496
virtual std::string toString() const
Returns a simple string representation of the argument.
Definition: Arg.h:590
bool isValueRequired() const
Indicates whether a value must be specified for argument.
Definition: Arg.h:564
virtual bool acceptsMultipleValues()
Use by output classes to determine whether an Arg accepts multiple values.
Definition: Arg.h:665
bool _ignoreable
Whether this argument can be ignored, if desired.
Definition: Arg.h:141
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:191
virtual bool operator==(const Arg &a) const
Operator ==.
Definition: Arg.h:537
static bool ignoreRest()
Whether to ignore the rest.
Definition: Arg.h:196
bool isIgnoreable() const
Indicates whether the argument can be ignored, if desired.
Definition: Arg.h:574
std::string getDescription() const
Returns the argument description.
Definition: Arg.h:545
const std::string & getFlag() const
Returns the argument flag.
Definition: Arg.h:558
void ExtractValue(T &destVal, const std::string &strVal, ValueLike vl)
Definition: Arg.h:406
std::list< Arg * >::const_iterator ArgListIterator
Typedef of an Arg list iterator.
Definition: Arg.h:387
std::string _name
A single word namd identifying the argument.
Definition: Arg.h:98
static char blankChar()
The char used as a place holder when SwitchArgs are combined.
Definition: Arg.h:208
std::string _flag
The single char flag used to identify the argument.
Definition: Arg.h:89
bool _acceptsMultipleValues
Definition: Arg.h:149
Thrown from within the child Arg classes when it fails to properly parse the argument it has been pas...
Definition: ArgException.h:122
void forceRequired()
Sets _required to true.
Definition: Arg.h:641
Definition: Arg.h:48
virtual bool allowMore()
Used for MultiArgs and XorHandler to determine whether args can still be set.
Definition: Arg.h:660
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:632
#define TCLAP_FLAGSTARTSTRING
The sting that indicates the beginning of a flag.
Definition: Arg.h:225
std::string _requireLabel
Label to be used in usage description.
Definition: Arg.h:114
static const std::string flagStartString()
Definition: Arg.h:227
virtual void trimFlag(std::string &flag, std::string &value) const
Trims a value off of the flag.
Definition: Arg.h:611
static void setDelimiter(char c)
Sets the delimiter for all arguments.
Definition: Arg.h:247