Main MRPT website > C++ reference
MRPT logo
Arg.h
Go to the documentation of this file.
1 
2 /******************************************************************************
3  *
4  * file: Arg.h
5  *
6  * Copyright (c) 2003, Michael E. Smoot .
7  * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno .
8  * All rights reverved.
9  *
10  * See the file COPYING in the top directory of this distribution for
11  * more information.
12  *
13  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
14  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19  * DEALINGS IN THE SOFTWARE.
20  *
21  *****************************************************************************/
22 
23 
24 #ifndef TCLAP_ARGUMENT_H
25 #define TCLAP_ARGUMENT_H
26 
27 #include <string>
28 #include <vector>
29 #include <list>
30 #include <iostream>
31 
35 
36 namespace TCLAP {
37 
38 /**
39  * A virtual base class that defines the essential data for all arguments.
40  * This class, or one of its existing children, must be subclassed to do
41  * anything.
42  */
43 class Arg
44 {
45  private:
46 
47  /**
48  * Indicates whether the rest of the arguments should be ignored.
49  */
50  static bool& ignoreRestRef() { static bool ign = false; return ign; }
51 
52  /**
53  * The delimiter that separates an argument flag/name from the
54  * value.
55  */
56  static char& delimiterRef() { static char delim = ' '; return delim; }
57 
58  protected:
59 
60  /**
61  * The single char flag used to identify the argument.
62  * This value (preceded by a dash {-}), can be used to identify
63  * an argument on the command line. The _flag can be blank,
64  * in fact this is how unlabeled args work. Unlabeled args must
65  * override appropriate functions to get correct handling. Note
66  * that the _flag does NOT include the dash as part of the flag.
67  */
68  std::string _flag;
69 
70  /**
71  * A single work namd indentifying the argument.
72  * This value (preceded by two dashed {--}) can also be used
73  * to identify an argument on the command line. Note that the
74  * _name does NOT include the two dashes as part of the _name. The
75  * _name cannot be blank.
76  */
77  std::string _name;
78 
79  /**
80  * Description of the argument.
81  */
82  std::string _description;
83 
84  /**
85  * Indicating whether the argument is required.
86  */
87  bool _required;
88 
89  /**
90  * Label to be used in usage description. Normally set to
91  * "required", but can be changed when necessary.
92  */
93  std::string _requireLabel;
94 
95  /**
96  * Indicates whether a value is required for the argument.
97  * Note that the value may be required but the argument/value
98  * combination may not be, as specified by _required.
99  */
101 
102  /**
103  * Indicates whether the argument has been set.
104  * Indicates that a value on the command line has matched the
105  * name/flag of this argument and the values have been set accordingly.
106  */
108 
109  /**
110  * A pointer to a vistitor object.
111  * The visitor allows special handling to occur as soon as the
112  * argument is matched. This defaults to NULL and should not
113  * be used unless absolutely necessary.
114  */
116 
117  /**
118  * Whether this argument can be ignored, if desired.
119  */
121 
122  /**
123  * Indicates that the arg was set as part of an XOR and not on the
124  * command line.
125  */
126  bool _xorSet;
127 
129 
130  /**
131  * Performs the special handling described by the Vistitor.
132  */
133  void _checkWithVisitor() const;
134 
135  /**
136  * Primary constructor. YOU (yes you) should NEVER construct an Arg
137  * directly, this is a base class that is extended by various children
138  * that are meant to be used. Use SwitchArg, ValueArg, MultiArg,
139  * UnlabeledValueArg, or UnlabeledMultiArg instead.
140  *
141  * \param flag - The flag identifying the argument.
142  * \param name - The name identifying the argument.
143  * \param desc - The description of the argument, used in the usage.
144  * \param req - Whether the argument is required.
145  * \param valreq - Whether the a value is required for the argument.
146  * \param v - The visitor checked by the argument. Defaults to NULL.
147  */
148  Arg( const std::string& flag,
149  const std::string& name,
150  const std::string& desc,
151  bool req,
152  bool valreq,
153  Visitor* v = NULL );
154 
155  public:
156  /**
157  * Destructor.
158  */
159  virtual ~Arg();
160 
161  /**
162  * Adds this to the specified list of Args.
163  * \param argList - The list to add this to.
164  */
165  virtual void addToList( std::list<Arg*>& argList ) const;
166 
167  /**
168  * Begin ignoring arguments since the "--" argument was specified.
169  */
170  static void beginIgnoring() { ignoreRestRef() = true; }
171 
172  /**
173  * Whether to ignore the rest.
174  */
175  static bool ignoreRest() { return ignoreRestRef(); }
176 
177  /**
178  * The delimiter that separates an argument flag/name from the
179  * value.
180  */
181  static char delimiter() { return delimiterRef(); }
182 
183  /**
184  * The char used as a place holder when SwitchArgs are combined.
185  * Currently set to '*', which shouldn't cause many problems since
186  * *'s are expanded by most shells on the command line.
187  */
188  static const char blankChar() { return '*'; }
189 
190  /**
191  * The char that indicates the beginning of a flag. Currently '-'.
192  */
193  static const char flagStartChar() { return '-'; }
194 
195  /**
196  * The sting that indicates the beginning of a flag. Currently "-".
197  * Should be identical to flagStartChar.
198  */
199  static const std::string flagStartString() { return "-"; }
200 
201  /**
202  * The sting that indicates the beginning of a name. Currently "--".
203  * Should be flagStartChar twice.
204  */
205  static const std::string nameStartString() { return "--"; }
206 
207  /**
208  * The name used to identify the ignore rest argument.
209  */
210  static const std::string ignoreNameString() { return "ignore_rest"; }
211 
212  /**
213  * Sets the delimiter for all arguments.
214  * \param c - The character that delimits flags/names from values.
215  */
216  static void setDelimiter( char c ) { delimiterRef() = c; }
217 
218  /**
219  * Pure virtual method meant to handle the parsing and value assignment
220  * of the string on the command line.
221  * \param i - Pointer the the current argument in the list.
222  * \param args - Mutable list of strings. What is
223  * passed in from main.
224  */
225  virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
226 
227  /**
228  * Operator ==.
229  * Equality operator. Must be virtual to handle unlabeled args.
230  * \param a - The Arg to be compared to this.
231  */
232  virtual bool operator==(const Arg& a) const;
233 
234  /**
235  * Returns the argument flag.
236  */
237  const std::string& getFlag() const;
238 
239  /**
240  * Returns the argument name.
241  */
242  const std::string& getName() const;
243 
244  /**
245  * Returns the argument description.
246  */
247  std::string getDescription() const;
248 
249  /**
250  * Indicates whether the argument is required.
251  */
252  virtual bool isRequired() const;
253 
254  /**
255  * Sets _required to true. This is used by the XorHandler.
256  * You really have no reason to ever use it.
257  */
258  void forceRequired();
259 
260  /**
261  * Sets the _alreadySet value to true. This is used by the XorHandler.
262  * You really have no reason to ever use it.
263  */
264  void xorSet();
265 
266  /**
267  * Indicates whether a value must be specified for argument.
268  */
269  bool isValueRequired() const;
270 
271  /**
272  * Indicates whether the argument has already been set. Only true
273  * if the arg has been matched on the command line.
274  */
275  bool isSet() const;
276 
277  /**
278  * Indicates whether the argument can be ignored, if desired.
279  */
280  bool isIgnoreable() const;
281 
282  /**
283  * A method that tests whether a string matches this argument.
284  * This is generally called by the processArg() method. This
285  * method could be re-implemented by a child to change how
286  * arguments are specified on the command line.
287  * \param s - The string to be compared to the flag/name to determine
288  * whether the arg matches.
289  */
290  virtual bool argMatches( const std::string& s ) const;
291 
292  /**
293  * Returns a simple string representation of the argument.
294  * Primarily for debugging.
295  */
296  virtual std::string toString() const;
297 
298  /**
299  * Returns a short ID for the usage.
300  * \param valueId - The value used in the id.
301  */
302  virtual std::string shortID( const std::string& valueId = "val" ) const;
303 
304  /**
305  * Returns a long ID for the usage.
306  * \param valueId - The value used in the id.
307  */
308  virtual std::string longID( const std::string& valueId = "val" ) const;
309 
310  /**
311  * Trims a value off of the flag.
312  * \param flag - The string from which the flag and value will be
313  * trimmed. Contains the flag once the value has been trimmed.
314  * \param value - Where the value trimmed from the string will
315  * be stored.
316  */
317  virtual void trimFlag( std::string& flag, std::string& value ) const;
318 
319  /**
320  * Checks whether a given string has blank chars, indicating that
321  * it is a combined SwitchArg. If so, return true, otherwise return
322  * false.
323  * \param s - string to be checked.
324  */
325  bool _hasBlanks( const std::string& s ) const;
326 
327  /**
328  * Sets the requireLabel. Used by XorHandler. You shouldn't ever
329  * use this.
330  * \param s - Set the requireLabel to this value.
331  */
332  void setRequireLabel( const std::string& s );
333 
334  virtual bool allowMore();
335  virtual bool acceptsMultipleValues();
336 
337 };
338 
339 /**
340  * Typedef of an Arg list iterator.
341  */
343 
344 /**
345  * Typedef of an Arg vector iterator.
346  */
348 
349 /**
350  * Typedef of a Visitor list iterator.
351  */
353 
354 
355 //////////////////////////////////////////////////////////////////////
356 //BEGIN Arg.cpp
357 //////////////////////////////////////////////////////////////////////
358 
359 inline Arg::Arg(const std::string& flag,
360  const std::string& name,
361  const std::string& desc,
362  bool req,
363  bool valreq,
364  Visitor* v) :
365  _flag(flag),
366  _name(name),
367  _description(desc),
368  _required(req),
369  _requireLabel("required"),
370  _valueRequired(valreq),
371  _alreadySet(false),
372  _visitor( v ),
373  _ignoreable(true),
374  _xorSet(false),
375  _acceptsMultipleValues(false)
376 {
377  if ( _flag.length() > 1 )
379  "Argument flag can only be one character long", toString() ) );
380 
381  if ( _name != ignoreNameString() &&
382  ( _flag == Arg::flagStartString() ||
383  _flag == Arg::nameStartString() ||
384  _flag == " " ) )
385  throw(SpecificationException("Argument flag cannot be either '" +
386  Arg::flagStartString() + "' or '" +
387  Arg::nameStartString() + "' or a space.",
388  toString() ) );
389 
390  if ( /*( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) || */
391  ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) ||
392  ( _name.find( " ", 0 ) != std::string::npos ) )
393  throw(SpecificationException("Argument name cannot contain either '" +
394  Arg::flagStartString() + "' or '" +
395  Arg::nameStartString() + "' or space.",
396  toString() ) );
397 
398 }
399 
400 inline Arg::~Arg() { }
401 
402 inline std::string Arg::shortID( const std::string& valueId ) const
403 {
404  std::string id = "";
405 
406  if ( _flag != "" )
407  id = Arg::flagStartString() + _flag;
408  else
409  id = Arg::nameStartString() + _name;
410 
411  std::string delim = " ";
412  delim[0] = Arg::delimiter(); // ugly!!!
413 
414  if ( _valueRequired )
415  id += delim + "<" + valueId + ">";
416 
417  if ( !_required )
418  id = "[" + id + "]";
419 
420  return id;
421 }
422 
423 inline std::string Arg::longID( const std::string& valueId ) const
424 {
425  std::string id = "";
426 
427  if ( _flag != "" )
428  {
429  id += Arg::flagStartString() + _flag;
430 
431  if ( _valueRequired )
432  id += " <" + valueId + ">";
433 
434  id += ", ";
435  }
436 
437  id += Arg::nameStartString() + _name;
438 
439  if ( _valueRequired )
440  id += " <" + valueId + ">";
441 
442  return id;
443 
444 }
445 
446 inline bool Arg::operator==(const Arg& a) const
447 {
448  if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
449  return true;
450  else
451  return false;
452 }
453 
454 inline std::string Arg::getDescription() const
455 {
456  std::string desc = "";
457  if ( _required )
458  desc = "(" + _requireLabel + ") ";
459 
460 // if ( _valueRequired )
461 // desc += "(value required) ";
462 
463  desc += _description;
464  return desc;
465 }
466 
467 inline const std::string& Arg::getFlag() const { return _flag; }
468 
469 inline const std::string& Arg::getName() const { return _name; }
470 
471 inline bool Arg::isRequired() const { return _required; }
472 
473 inline bool Arg::isValueRequired() const { return _valueRequired; }
474 
475 inline bool Arg::isSet() const
476 {
477  if ( _alreadySet && !_xorSet )
478  return true;
479  else
480  return false;
481 }
482 
483 inline bool Arg::isIgnoreable() const { return _ignoreable; }
484 
485 inline void Arg::setRequireLabel( const std::string& s)
486 {
487  _requireLabel = s;
488 }
489 
490 inline bool Arg::argMatches( const std::string& argFlag ) const
491 {
492  if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
493  argFlag == Arg::nameStartString() + _name )
494  return true;
495  else
496  return false;
497 }
498 
499 inline std::string Arg::toString() const
500 {
501  std::string s = "";
502 
503  if ( _flag != "" )
504  s += Arg::flagStartString() + _flag + " ";
505 
506  s += "(" + Arg::nameStartString() + _name + ")";
507 
508  return s;
509 }
510 
511 inline void Arg::_checkWithVisitor() const
512 {
513  if ( _visitor != NULL )
514  _visitor->visit();
515 }
516 
517 /**
518  * Implementation of trimFlag.
519  */
520 inline void Arg::trimFlag(std::string& flag, std::string& value) const
521 {
522  int stop = 0;
523  for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
524  if ( flag[i] == Arg::delimiter() )
525  {
526  stop = i;
527  break;
528  }
529 
530  if ( stop > 1 )
531  {
532  value = flag.substr(stop+1);
533  flag = flag.substr(0,stop);
534  }
535 
536 }
537 
538 /**
539  * Implementation of _hasBlanks.
540  */
541 inline bool Arg::_hasBlanks( const std::string& s ) const
542 {
543  for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
544  if ( s[i] == Arg::blankChar() )
545  return true;
546 
547  return false;
548 }
549 
550 inline void Arg::forceRequired()
551 {
552  _required = true;
553 }
554 
555 inline void Arg::xorSet()
556 {
557  _alreadySet = true;
558  _xorSet = true;
559 }
560 
561 /**
562  * Overridden by Args that need to added to the end of the list.
563  */
564 inline void Arg::addToList( std::list<Arg*>& argList ) const
565 {
566  argList.push_front( const_cast<Arg*>(this) );
567 }
568 
569 inline bool Arg::allowMore()
570 {
571  return false;
572 }
573 
575 {
576  return _acceptsMultipleValues;
577 }
578 
579 //////////////////////////////////////////////////////////////////////
580 //END Arg.cpp
581 //////////////////////////////////////////////////////////////////////
582 
583 } //namespace TCLAP
584 
585 #endif
586 



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013