tclap  1.4.0
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 #ifndef TCLAP_ARG_H
26 #define TCLAP_ARG_H
27 
28 #ifdef HAVE_TCLAP_CONFIG_H
29 #include <tclap/TCLAPConfig.h>
30 #endif
31 
32 #include <tclap/ArgException.h>
33 #include <tclap/ArgTraits.h>
34 #include <tclap/CmdLineInterface.h>
35 #include <tclap/StandardTraits.h>
36 #include <tclap/Visitor.h>
37 #include <tclap/sstream.h>
38 
39 #include <cstdio>
40 #include <iomanip>
41 #include <iostream>
42 #include <list>
43 #include <string>
44 #include <vector>
45 
46 namespace TCLAP {
47 
53 class Arg {
54 private:
58  Arg(const Arg &rhs);
59 
63  Arg &operator=(const Arg &rhs);
64 
69  static char &delimiterRef() {
70  static char delim = ' ';
71  return delim;
72  }
73 
74 protected:
83  std::string _flag;
84 
92  std::string _name;
93 
97  std::string _description;
98 
102  const bool _required;
103 
108  std::string _requireLabel;
109 
116 
123 
126  std::string _setBy;
127 
135 
140 
142 
148 
152  void _checkWithVisitor() const;
153 
167  Arg(const std::string &flag, const std::string &name,
168  const std::string &desc, bool req, bool valreq, Visitor *v = NULL);
169 
170 public:
174  virtual ~Arg();
175 
180  virtual void addToList(std::list<Arg *> &argList) const;
181 
186  static char delimiter() { return delimiterRef(); }
187 
192  static char blankChar() { return '\a'; }
193 
198 #ifndef TCLAP_FLAGSTARTCHAR
199 #define TCLAP_FLAGSTARTCHAR '-'
200 #endif
201  static char flagStartChar() { return TCLAP_FLAGSTARTCHAR; }
202 
208 #ifndef TCLAP_FLAGSTARTSTRING
209 #define TCLAP_FLAGSTARTSTRING "-"
210 #endif
211  static const std::string flagStartString() { return TCLAP_FLAGSTARTSTRING; }
212 
217 #ifndef TCLAP_NAMESTARTSTRING
218 #define TCLAP_NAMESTARTSTRING "--"
219 #endif
220  static const std::string nameStartString() { return TCLAP_NAMESTARTSTRING; }
221 
225  static const std::string ignoreNameString() { return "ignore_rest"; }
226 
231  static void setDelimiter(char c) { delimiterRef() = c; }
232 
240  virtual bool processArg(int *i, std::vector<std::string> &args) = 0;
241 
247  virtual bool operator==(const Arg &a) const;
248 
252  const std::string &getFlag() const;
253 
257  const std::string &getName() const;
258 
262  std::string getDescription() const { return getDescription(_required); }
263 
270  std::string getDescription(bool required) const {
271  return (required ? "(" + _requireLabel + ") " : "") + _description;
272  }
273 
277  virtual bool isRequired() const;
278 
282  bool isValueRequired() const;
283 
288  bool isSet() const;
289 
293  const std::string &setBy() const { return _setBy; }
294 
298  bool isIgnoreable() const;
299 
308  virtual bool argMatches(const std::string &s) const;
309 
314  virtual std::string toString() const;
315 
320  virtual std::string shortID(const std::string &valueId = "val") const;
321 
326  virtual std::string longID(const std::string &valueId = "val") const;
327 
335  virtual void trimFlag(std::string &flag, std::string &value) const;
336 
343  bool _hasBlanks(const std::string &s) const;
344 
349  virtual bool allowMore();
350 
355  virtual bool acceptsMultipleValues();
356 
361  virtual void reset();
362 
367  virtual void hideFromHelp(bool hide = true) { _visibleInHelp = !hide; }
368 
372  virtual bool visibleInHelp() const { return _visibleInHelp; }
373 
374  virtual bool hasLabel() const { return true; }
375 };
376 
380 typedef std::list<Arg *>::const_iterator ArgListIterator;
381 
385 typedef std::vector<Arg *>::const_iterator ArgVectorIterator;
386 
390 typedef std::list<Visitor *>::const_iterator VisitorListIterator;
391 
392 /*
393  * Extract a value of type T from it's string representation contained
394  * in strVal. The ValueLike parameter used to select the correct
395  * specialization of ExtractValue depending on the value traits of T.
396  * ValueLike traits use operator>> to assign the value from strVal.
397  */
398 template <typename T>
399 void ExtractValue(T &destVal, const std::string &strVal, ValueLike vl) {
400  static_cast<void>(vl); // Avoid warning about unused vl
401  istringstream is(strVal.c_str());
402 
403  int valuesRead = 0;
404  while (is.good()) {
405  if (is.peek() != EOF)
406 #ifdef TCLAP_SETBASE_ZERO
407  is >> std::setbase(0) >> destVal;
408 #else
409  is >> destVal;
410 #endif
411  else
412  break;
413 
414  valuesRead++;
415  }
416 
417  if (is.fail())
418  throw(
419  ArgParseException("Couldn't read argument value "
420  "from string '" +
421  strVal + "'"));
422 
423  if (valuesRead > 1)
424  throw(
425  ArgParseException("More than one valid value parsed from "
426  "string '" +
427  strVal + "'"));
428 }
429 
430 /*
431  * Extract a value of type T from it's string representation contained
432  * in strVal. The ValueLike parameter used to select the correct
433  * specialization of ExtractValue depending on the value traits of T.
434  * StringLike uses assignment (operator=) to assign from strVal.
435  */
436 template <typename T>
437 void ExtractValue(T &destVal, const std::string &strVal, StringLike sl) {
438  static_cast<void>(sl); // Avoid warning about unused sl
439  SetString(destVal, strVal);
440 }
441 
443 // BEGIN Arg.cpp
445 
446 inline Arg::Arg(const std::string &flag, const std::string &name,
447  const std::string &desc, bool req, bool valreq, Visitor *v)
448  : _flag(flag),
449  _name(name),
450  _description(desc),
451  _required(req),
452  _requireLabel("required"),
453  _valueRequired(valreq),
454  _alreadySet(false),
455  _setBy(),
456  _visitor(v),
457  _ignoreable(true),
458  _acceptsMultipleValues(false),
459  _visibleInHelp(true) {
460  if (_flag.length() > 1)
462  "Argument flag can only be one character long", toString()));
463 
464  if (_name != ignoreNameString() &&
466  _flag == " "))
468  "Argument flag cannot be either '" + Arg::flagStartString() +
469  "' or '" + Arg::nameStartString() + "' or a space.",
470  toString()));
471 
472  if ((_name.substr(0, Arg::flagStartString().length()) ==
474  (_name.substr(0, Arg::nameStartString().length()) ==
476  (_name.find(" ", 0) != std::string::npos))
477  throw(SpecificationException("Argument name begin with either '" +
478  Arg::flagStartString() + "' or '" +
479  Arg::nameStartString() + "' or space.",
480  toString()));
481 }
482 
483 inline Arg::~Arg() {}
484 
485 inline std::string Arg::shortID(const std::string &valueId) const {
486  std::string id = "";
487 
488  if (_flag != "")
489  id = Arg::flagStartString() + _flag;
490  else
491  id = Arg::nameStartString() + _name;
492 
493  if (_valueRequired) id += std::string(1, Arg::delimiter()) + valueId;
494 
495  return id;
496 }
497 
498 inline std::string Arg::longID(const std::string &valueId) const {
499  std::string id = "";
500 
501  if (_flag != "") {
502  id += Arg::flagStartString() + _flag;
503 
504  if (_valueRequired) id += std::string(1, Arg::delimiter()) + valueId;
505 
506  id += ", ";
507  }
508 
509  id += Arg::nameStartString() + _name;
510 
511  if (_valueRequired) id += std::string(1, Arg::delimiter()) + valueId;
512 
513  return id;
514 }
515 
516 inline bool Arg::operator==(const Arg &a) const {
517  if ((_flag != "" && _flag == a._flag) || _name == a._name)
518  return true;
519  else
520  return false;
521 }
522 
523 inline const std::string &Arg::getFlag() const { return _flag; }
524 
525 inline const std::string &Arg::getName() const { return _name; }
526 
527 inline bool Arg::isRequired() const { return _required; }
528 
529 inline bool Arg::isValueRequired() const { return _valueRequired; }
530 
531 inline bool Arg::isSet() const { return _alreadySet; }
532 
533 inline bool Arg::isIgnoreable() const { return _ignoreable; }
534 
535 inline bool Arg::argMatches(const std::string &argFlag) const {
536  if ((argFlag == Arg::flagStartString() + _flag && _flag != "") ||
537  argFlag == Arg::nameStartString() + _name)
538  return true;
539  else
540  return false;
541 }
542 
543 inline std::string Arg::toString() const {
544  std::string s = "";
545 
546  if (_flag != "") s += Arg::flagStartString() + _flag + " ";
547 
548  s += "(" + Arg::nameStartString() + _name + ")";
549 
550  return s;
551 }
552 
553 inline void Arg::_checkWithVisitor() const {
554  if (_visitor != NULL) _visitor->visit();
555 }
556 
560 inline void Arg::trimFlag(std::string &flag, std::string &value) const {
561  int stop = 0;
562  for (int i = 0; static_cast<unsigned int>(i) < flag.length(); i++)
563  if (flag[i] == Arg::delimiter()) {
564  stop = i;
565  break;
566  }
567 
568  if (stop > 1) {
569  value = flag.substr(stop + 1);
570  flag = flag.substr(0, stop);
571  }
572 }
573 
577 inline bool Arg::_hasBlanks(const std::string &s) const {
578  for (int i = 1; static_cast<unsigned int>(i) < s.length(); i++)
579  if (s[i] == Arg::blankChar()) return true;
580 
581  return false;
582 }
583 
587 inline void Arg::addToList(std::list<Arg *> &argList) const {
588  argList.push_front(const_cast<Arg *>(this));
589 }
590 
591 inline bool Arg::allowMore() { return false; }
592 
594 
595 inline void Arg::reset() { _alreadySet = false; }
596 
598 // END Arg.cpp
600 
601 } // namespace TCLAP
602 
603 #endif // TCLAP_ARG_H
std::vector< Arg * >::const_iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition: Arg.h:385
virtual bool argMatches(const std::string &s) const
A method that tests whether a string matches this argument.
Definition: Arg.h:535
bool _alreadySet
Indicates whether the argument has been set.
Definition: Arg.h:122
bool _valueRequired
Indicates whether a value is required for the argument.
Definition: Arg.h:115
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:53
virtual void visit()=0
This method (to implemented by children) will be called when the visitor is visited.
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:587
A value like argument value type is a value that can be set using operator>>.
Definition: ArgTraits.h:39
static char flagStartChar()
Definition: Arg.h:201
virtual void reset()
Clears the Arg object and allows it to be reused by new command lines.
Definition: Arg.h:595
std::istringstream istringstream
Definition: sstream.h:37
bool isSet() const
Indicates whether the argument has already been set.
Definition: Arg.h:531
virtual bool hasLabel() const
Definition: Arg.h:374
Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
Definition: ArgException.h:150
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: Arg.h:498
static char delimiter()
The delimiter that separates an argument flag/name from the value.
Definition: Arg.h:186
virtual ~Arg()
Destructor.
Definition: Arg.h:483
virtual void hideFromHelp(bool hide=true)
Hide this argument from the help output (e.g., when specifying the –help flag or on error...
Definition: Arg.h:367
std::list< Visitor * >::const_iterator VisitorListIterator
Typedef of a Visitor list iterator.
Definition: Arg.h:390
#define TCLAP_FLAGSTARTCHAR
The char that indicates the beginning of a flag.
Definition: Arg.h:199
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:527
Visitor * _visitor
A pointer to a visitor object.
Definition: Arg.h:134
const bool _required
Indicating whether the argument is required.
Definition: Arg.h:102
virtual bool visibleInHelp() const
Returns true if this Arg is visible in the help output.
Definition: Arg.h:372
void _checkWithVisitor() const
Performs the special handling described by the Visitor.
Definition: Arg.h:553
static const std::string ignoreNameString()
The name used to identify the ignore rest argument.
Definition: Arg.h:225
static const std::string nameStartString()
Definition: Arg.h:220
#define TCLAP_NAMESTARTSTRING
The sting that indicates the beginning of a name.
Definition: Arg.h:218
A base class that defines the interface for visitors.
Definition: Visitor.h:32
const std::string & getName() const
Returns the argument name.
Definition: Arg.h:525
std::string _description
Description of the argument.
Definition: Arg.h:97
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition: Arg.h:485
virtual std::string toString() const
Returns a simple string representation of the argument.
Definition: Arg.h:543
bool isValueRequired() const
Indicates whether a value must be specified for argument.
Definition: Arg.h:529
virtual bool acceptsMultipleValues()
Use by output classes to determine whether an Arg accepts multiple values.
Definition: Arg.h:593
bool _ignoreable
Whether this argument can be ignored, if desired.
Definition: Arg.h:139
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...
virtual bool operator==(const Arg &a) const
Operator ==.
Definition: Arg.h:516
bool isIgnoreable() const
Indicates whether the argument can be ignored, if desired.
Definition: Arg.h:533
std::string getDescription() const
Returns the argument description.
Definition: Arg.h:262
const std::string & getFlag() const
Returns the argument flag.
Definition: Arg.h:523
void ExtractValue(T &destVal, const std::string &strVal, ValueLike vl)
Definition: Arg.h:399
bool _visibleInHelp
Indicates if the argument is visible in the help output (e.g., when specifying –help).
Definition: Arg.h:147
std::string _name
A single word namd identifying the argument.
Definition: Arg.h:92
std::string getDescription(bool required) const
Returns the argument description.
Definition: Arg.h:270
static char blankChar()
The char used as a place holder when SwitchArgs are combined.
Definition: Arg.h:192
std::string _flag
The single char flag used to identify the argument.
Definition: Arg.h:83
bool _acceptsMultipleValues
Definition: Arg.h:141
Thrown from within the child Arg classes when it fails to properly parse the argument it has been pas...
Definition: ArgException.h:110
std::list< Arg * >::const_iterator ArgListIterator
Typedef of an Arg list iterator.
Definition: Arg.h:380
Definition: Arg.h:46
virtual bool allowMore()
Used for MultiArgs to determine whether args can still be set.
Definition: Arg.h:591
const std::string & setBy() const
Returns the value specified to set this flag (like -a or –all).
Definition: Arg.h:293
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:577
#define TCLAP_FLAGSTARTSTRING
The sting that indicates the beginning of a flag.
Definition: Arg.h:209
std::string _setBy
Indicates the value specified to set this flag (like -a or –all).
Definition: Arg.h:126
std::string _requireLabel
Label to be used in usage description.
Definition: Arg.h:108
static const std::string flagStartString()
Definition: Arg.h:211
virtual void trimFlag(std::string &flag, std::string &value) const
Trims a value off of the flag.
Definition: Arg.h:560
static void setDelimiter(char c)
Sets the delimiter for all arguments.
Definition: Arg.h:231