Main MRPT website > C++ reference for MRPT 1.4.0
MultiArg.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2016, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 
11 #ifndef TCLAP_MULTIPLE_ARGUMENT_H
12 #define TCLAP_MULTIPLE_ARGUMENT_H
13 
14 #include <string>
15 #include <vector>
16 #include <cstdio> // EOF
17 
20 
21 //#ifdef HAVE_CONFIG_H
22 //#include <config.h>
23 //#else
24 #define HAVE_SSTREAM
25 //#endif
26 
27 #if defined(HAVE_SSTREAM)
28 #include <sstream>
29 #elif defined(HAVE_STRSTREAM)
30 #include <strstream>
31 #else
32 #error "Need a stringstream (sstream or strstream) to compile!"
33 #endif
34 
35 namespace TCLAP {
36 
37 template<class T> class MultiArg;
38 
39 namespace MULTI_ARG_HELPER {
40 
42 
43 /**
44  * This class is used to extract a value from an argument.
45  * It is used because we need a special implementation to
46  * deal with std::string and making a specialiced function
47  * puts it in the T segment, thus generating link errors.
48  * Having a specialiced class makes the symbols weak.
49  * This is not pretty but I don't know how to make it
50  * work any other way.
51  */
52 template<class T>
54 {
55  friend class MultiArg<T>;
56 
57  private:
58 
59  /**
60  * Reference to the vector of values where the result of the
61  * extraction will be put.
62  */
63  std::vector<T> &_values;
64 
65  /**
66  * Constructor.
67  * \param values - Where the values extracted will be put.
68  */
69  ValueExtractor(std::vector<T> &values) : _values(values) {}
70 
71  /**
72  * Method that will attempt to parse the input stream for values
73  * of type T.
74  * \param val - Where the values parsed will be put.
75  */
76  int extractValue( const std::string& val )
77  {
78  T temp;
79 
80 #if defined(HAVE_SSTREAM)
81  std::istringstream is(val);
82 #elif defined(HAVE_STRSTREAM)
83  std::istrstream is(val.c_str());
84 #else
85 #error "Need a stringstream (sstream or strstream) to compile!"
86 #endif
87 
88  int valuesRead = 0;
89 
90  while ( is.good() )
91  {
92  if ( is.peek() != EOF )
93  is >> temp;
94  else
95  break;
96 
97  valuesRead++;
98  }
99 
100  if ( is.fail() )
101  return EXTRACT_FAILURE;
102 
103  if ( valuesRead > 1 )
104  return EXTRACT_TOO_MANY;
105 
106  _values.push_back(temp);
107 
108  return 0;
109  }
110 };
111 
112 /**
113  * Specialization for string. This is necessary because istringstream
114  * operator>> is not able to ignore spaces... meaning -x "X Y" will only
115  * read 'X'... and thus the specialization.
116  */
117 template<>
118 class ValueExtractor<std::string>
119 {
120  friend class MultiArg<std::string>;
121 
122  private:
123 
124  /**
125  * Reference to the vector of strings where the result of the
126  * extraction will be put.
127  */
128  std::vector<std::string> &_values;
129 
130  /**
131  * Constructor.
132  * \param values - Where the strings extracted will be put.
133  */
134  ValueExtractor(std::vector<std::string> &values) : _values(values) {}
135 
136  /**
137  * Method that will attempt to parse the input stream for values
138  * of type std::string.
139  * \param val - Where the values parsed will be put.
140  */
141  int extractValue( const std::string& val )
142  {
143  _values.push_back( val );
144  return 0;
145  }
146 };
147 
148 } //namespace MULTI_ARG_HELPER
149 
150 /**
151  * An argument that allows multiple values of type T to be specified. Very
152  * similar to a ValueArg, except a vector of values will be returned
153  * instead of just one.
154  */
155 template<class T>
156 class MultiArg : public Arg
157 {
158  protected:
159 
160  /**
161  * The list of values parsed from the CmdLine.
162  */
163  std::vector<T> _values;
164 
165  /**
166  * The description of type T to be used in the usage.
167  */
168  std::string _typeDesc;
169 
170  /**
171  * A list of constraint on this Arg.
172  */
174 
175  /**
176  * Extracts the value from the string.
177  * Attempts to parse string as type T, if this fails an exception
178  * is thrown.
179  * \param val - The string to be read.
180  */
181  void _extractValue( const std::string& val );
182 
184 
185  public:
186 
187  /**
188  * Constructor.
189  * \param flag - The one character flag that identifies this
190  * argument on the command line.
191  * \param name - A one word name for the argument. Can be
192  * used as a long flag on the command line.
193  * \param desc - A description of what the argument is for or
194  * does.
195  * \param req - Whether the argument is required on the command
196  * line.
197  * \param typeDesc - A short, human readable description of the
198  * type that this object expects. This is used in the generation
199  * of the USAGE statement. The goal is to be helpful to the end user
200  * of the program.
201  * \param v - An optional visitor. You probably should not
202  * use this unless you have a very good reason.
203  */
204  MultiArg( const std::string& flag,
205  const std::string& name,
206  const std::string& desc,
207  bool req,
208  const std::string& typeDesc,
209  Visitor* v = NULL);
210 
211  /**
212  * Constructor.
213  * \param flag - The one character flag that identifies this
214  * argument on the command line.
215  * \param name - A one word name for the argument. Can be
216  * used as a long flag on the command line.
217  * \param desc - A description of what the argument is for or
218  * does.
219  * \param req - Whether the argument is required on the command
220  * line.
221  * \param typeDesc - A short, human readable description of the
222  * type that this object expects. This is used in the generation
223  * of the USAGE statement. The goal is to be helpful to the end user
224  * of the program.
225  * \param parser - A CmdLine parser object to add this Arg to
226  * \param v - An optional visitor. You probably should not
227  * use this unless you have a very good reason.
228  */
229  MultiArg( const std::string& flag,
230  const std::string& name,
231  const std::string& desc,
232  bool req,
233  const std::string& typeDesc,
234  CmdLineInterface& parser,
235  Visitor* v = NULL );
236 
237  /**
238  * Constructor.
239  * \param flag - The one character flag that identifies this
240  * argument on the command line.
241  * \param name - A one word name for the argument. Can be
242  * used as a long flag on the command line.
243  * \param desc - A description of what the argument is for or
244  * does.
245  * \param req - Whether the argument is required on the command
246  * line.
247  * \param constraint - A pointer to a Constraint object used
248  * to constrain this Arg.
249  * \param v - An optional visitor. You probably should not
250  * use this unless you have a very good reason.
251  */
252  MultiArg( const std::string& flag,
253  const std::string& name,
254  const std::string& desc,
255  bool req,
256  Constraint<T>* constraint,
257  Visitor* v = NULL );
258 
259  /**
260  * Constructor.
261  * \param flag - The one character flag that identifies this
262  * argument on the command line.
263  * \param name - A one word name for the argument. Can be
264  * used as a long flag on the command line.
265  * \param desc - A description of what the argument is for or
266  * does.
267  * \param req - Whether the argument is required on the command
268  * line.
269  * \param constraint - A pointer to a Constraint object used
270  * to constrain this Arg.
271  * \param parser - A CmdLine parser object to add this Arg to
272  * \param v - An optional visitor. You probably should not
273  * use this unless you have a very good reason.
274  */
275  MultiArg( const std::string& flag,
276  const std::string& name,
277  const std::string& desc,
278  bool req,
279  Constraint<T>* constraint,
280  CmdLineInterface& parser,
281  Visitor* v = NULL );
282 
283  /**
284  * Handles the processing of the argument.
285  * This re-implements the Arg version of this method to set the
286  * _value of the argument appropriately. It knows the difference
287  * between labeled and unlabeled.
288  * \param i - Pointer the the current argument in the list.
289  * \param args - Mutable list of strings. Passed from main().
290  */
291  virtual bool processArg(int* i, std::vector<std::string>& args);
292 
293  /**
294  * Returns a vector of type T containing the values parsed from
295  * the command line.
296  */
297  const std::vector<T>& getValue();
298 
299  /**
300  * Returns the a short id string. Used in the usage.
301  * \param val - value to be used.
302  */
303  virtual std::string shortID(const std::string& val="val") const;
304 
305  /**
306  * Returns the a long id string. Used in the usage.
307  * \param val - value to be used.
308  */
309  virtual std::string longID(const std::string& val="val") const;
310 
311  /**
312  * Once we've matched the first value, then the arg is no longer
313  * required.
314  */
315  virtual bool isRequired() const;
316 
317  virtual bool allowMore();
318 
319 };
320 
321 template<class T>
322 MultiArg<T>::MultiArg(const std::string& flag,
323  const std::string& name,
324  const std::string& desc,
325  bool req,
326  const std::string& typeDesc,
327  Visitor* v)
328 : Arg( flag, name, desc, req, true, v ),
329  _typeDesc( typeDesc ),
330  _constraint( NULL ),
331  _allowMore(false)
332 {
333  _acceptsMultipleValues = true;
334 }
335 
336 template<class T>
337 MultiArg<T>::MultiArg(const std::string& flag,
338  const std::string& name,
339  const std::string& desc,
340  bool req,
341  const std::string& typeDesc,
342  CmdLineInterface& parser,
343  Visitor* v)
344 : Arg( flag, name, desc, req, true, v ),
345  _typeDesc( typeDesc ),
346  _constraint( NULL ),
347  _allowMore(false)
348 {
349  parser.add( this );
350  _acceptsMultipleValues = true;
351 }
352 
353 /**
354  *
355  */
356 template<class T>
357 MultiArg<T>::MultiArg(const std::string& flag,
358  const std::string& name,
359  const std::string& desc,
360  bool req,
361  Constraint<T>* constraint,
362  Visitor* v)
363 : Arg( flag, name, desc, req, true, v ),
364  _typeDesc( constraint->shortID() ),
365  _constraint( constraint ),
366  _allowMore(false)
367 {
368  _acceptsMultipleValues = true;
369 }
370 
371 template<class T>
372 MultiArg<T>::MultiArg(const std::string& flag,
373  const std::string& name,
374  const std::string& desc,
375  bool req,
376  Constraint<T>* constraint,
377  CmdLineInterface& parser,
378  Visitor* v)
379 : Arg( flag, name, desc, req, true, v ),
380  _typeDesc( constraint->shortID() ),
381  _constraint( constraint ),
382  _allowMore(false)
383 {
384  parser.add( this );
385  _acceptsMultipleValues = true;
386 }
387 
388 template<class T>
389 const std::vector<T>& MultiArg<T>::getValue() { return _values; }
390 
391 template<class T>
392 bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
393 {
394  if ( _ignoreable && Arg::ignoreRest() )
395  return false;
396 
397  if ( _hasBlanks( args[*i] ) )
398  return false;
399 
400  std::string flag = args[*i];
401  std::string value = "";
402 
403  trimFlag( flag, value );
404 
405  if ( argMatches( flag ) )
406  {
407  if ( Arg::delimiter() != ' ' && value == "" )
408  throw( ArgParseException(
409  "Couldn't find delimiter for this argument!",
410  toString() ) );
411 
412  // always take the first one, regardless of start string
413  if ( value == "" )
414  {
415  (*i)++;
416  if ( static_cast<unsigned int>(*i) < args.size() )
417  _extractValue( args[*i] );
418  else
419  throw( ArgParseException("Missing a value for this argument!",
420  toString() ) );
421  }
422  else
423  _extractValue( value );
424 
425  /*
426  // continuing taking the args until we hit one with a start string
427  while ( (unsigned int)(*i)+1 < args.size() &&
428  args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
429  args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
430  _extractValue( args[++(*i)] );
431  */
432 
433  _alreadySet = true;
435 
436  return true;
437  }
438  else
439  return false;
440 }
441 
442 /**
443  *
444  */
445 template<class T>
446 std::string MultiArg<T>::shortID(const std::string& val) const
447 {
448  std::string id = Arg::shortID(_typeDesc) + " ... ";
449 
450  return id;
451 }
452 
453 /**
454  *
455  */
456 template<class T>
457 std::string MultiArg<T>::longID(const std::string& val) const
458 {
459  std::string id = Arg::longID(_typeDesc) + " (accepted multiple times)";
460 
461  return id;
462 }
463 
464 /**
465  * Once we've matched the first value, then the arg is no longer
466  * required.
467  */
468 template<class T>
470 {
471  if ( _required )
472  {
473  if ( _values.size() > 1 )
474  return false;
475  else
476  return true;
477  }
478  else
479  return false;
480 
481 }
482 
483 template<class T>
484 void MultiArg<T>::_extractValue( const std::string& val )
485 {
487 
488  int err = ve.extractValue(val);
489 
491  throw( ArgParseException("Couldn't read argument value "
492  "from string '" + val + "'", toString() ) );
493 
495  throw( ArgParseException("More than one valid value "
496  "parsed from string '" + val + "'",
497  toString() ) );
498  if ( _constraint != NULL )
499  if ( ! _constraint->check( _values.back() ) )
500  throw( CmdLineParseException( "Value '" + val +
501  "' does not meet constraint: " +
502  _constraint->description(),
503  toString() ) );
504 }
505 
506 template<class T>
508 {
509  bool am = _allowMore;
510  _allowMore = true;
511  return am;
512 }
513 
514 } // namespace TCLAP
515 
516 #endif
bool _acceptsMultipleValues
Definition: Arg.h:136
MultiArg(const std::string &flag, const std::string &name, const std::string &desc, bool req, const std::string &typeDesc, Visitor *v=NULL)
Constructor.
Definition: MultiArg.h:322
virtual std::string longID(const std::string &val="val") const
Returns the a long id string.
Definition: MultiArg.h:457
virtual std::string toString() const
Returns a simple string representation of the argument.
Definition: Arg.h:507
This class is used to extract a value from an argument.
Definition: MultiArg.h:53
virtual bool allowMore()
Definition: MultiArg.h:507
int extractValue(const std::string &val)
Method that will attempt to parse the input stream for values of type T.
Definition: MultiArg.h:76
An argument that allows multiple values of type T to be specified.
Definition: MultiArg.h:37
STL namespace.
std::vector< T > & _values
Reference to the vector of values where the result of the extraction will be put. ...
Definition: MultiArg.h:63
const std::vector< T > & getValue()
Returns a vector of type T containing the values parsed from the command line.
Definition: MultiArg.h:389
std::vector< T > _values
The list of values parsed from the CmdLine.
Definition: MultiArg.h:163
Definition: Arg.h:44
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:51
virtual void add(Arg &a)=0
Adds an argument to the list of arguments to be parsed.
virtual bool processArg(int *i, std::vector< std::string > &args)
Handles the processing of the argument.
Definition: MultiArg.h:392
void _checkWithVisitor() const
Performs the special handling described by the Vistitor.
Definition: Arg.h:519
static char delimiter()
The delimiter that separates an argument flag/name from the value.
Definition: Arg.h:189
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition: Arg.h:410
int extractValue(const std::string &val)
Method that will attempt to parse the input stream for values of type std::string.
Definition: MultiArg.h:141
bool _alreadySet
Indicates whether the argument has been set.
Definition: Arg.h:115
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:549
Thrown from CmdLine when the arguments on the command line are not properly specified, e.g.
Definition: ArgException.h:151
ValueExtractor(std::vector< T > &values)
Constructor.
Definition: MultiArg.h:69
virtual void trimFlag(std::string &flag, std::string &value) const
Trims a value off of the flag.
Definition: Arg.h:528
A base class that defines the interface for visitors.
Definition: Visitor.h:39
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: Arg.h:431
std::string _typeDesc
The description of type T to be used in the usage.
Definition: MultiArg.h:168
Thrown from within the child Arg classes when it fails to properly parse the argument it has been pas...
Definition: ArgException.h:129
bool _ignoreable
Whether this argument can be ignored, if desired.
Definition: Arg.h:128
Constraint< T > * _constraint
A list of constraint on this Arg.
Definition: MultiArg.h:173
void _extractValue(const std::string &val)
Extracts the value from the string.
Definition: MultiArg.h:484
virtual bool argMatches(const std::string &s) const
A method that tests whether a string matches this argument.
Definition: Arg.h:498
virtual std::string shortID(const std::string &val="val") const
Returns the a short id string.
Definition: MultiArg.h:446
static bool ignoreRest()
Whether to ignore the rest.
Definition: Arg.h:183
virtual bool isRequired() const
Once we&#39;ve matched the first value, then the arg is no longer required.
Definition: MultiArg.h:469
bool _required
Indicating whether the argument is required.
Definition: Arg.h:95
The interface that defines the interaction between the Arg and Constraint.
Definition: Constraint.h:46
The base class that manages the command line definition and passes along the parsing to the appropria...



Page generated by Doxygen 1.8.11 for MRPT 1.4.0 SVN: at Sun Aug 14 23:58:29 UTC 2016