1
/******************************************************************************
5
* Copyright (c) 2003, Michael E. Smoot .
6
* Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
9
* See the file COPYING in the top directory of this distribution for
12
* THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
13
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18
* DEALINGS IN THE SOFTWARE.
20
*****************************************************************************/
23
#ifndef TCLAP_VALUE_ARGUMENT_H
24
#define TCLAP_VALUE_ARGUMENT_H
29
#include <tclap/Arg.h>
30
#include <tclap/Constraint.h>
38
#if defined(HAVE_SSTREAM)
40
#elif defined(HAVE_STRSTREAM)
43
#error "Need a stringstream (sstream or strstream) to compile!"
48
template<class T> class ValueArg;
50
namespace VALUE_ARG_HELPER {
52
enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY };
55
* This class is used to extract a value from an argument.
56
* It is used because we need a special implementation to
57
* deal with std::string and making a specialiced function
58
* puts it in the T segment, thus generating link errors.
59
* Having a specialiced class makes the symbols weak.
60
* This is not pretty but I don't know how to make it
63
template<class T> class ValueExtractor
68
friend class ValueArg<T>;
73
* Reference to the value where the result of the extraction will
80
* \param value - Where the value extracted will be put.
82
ValueExtractor(T &value) : _value(value) { }
85
* Method that will attempt to parse the input stream for a value
87
* \param val - Where the value parsed will be put.
89
int extractValue( const std::string& val )
92
#if defined(HAVE_SSTREAM)
93
std::istringstream is(val);
94
#elif defined(HAVE_STRSTREAM)
95
std::istrstream is(val.c_str());
97
#error "Need a stringstream (sstream or strstream) to compile!"
103
if ( ! (is >> _value ))
110
return EXTRACT_FAILURE;
112
if ( valuesRead > 1 )
113
return EXTRACT_TOO_MANY;
120
* Specialization for string. This is necessary because istringstream
121
* operator>> is not able to ignore spaces... meaning -x "X Y" will only
122
* read 'X'... and thus the specialization.
124
template<> class ValueExtractor<std::string>
129
friend class ValueArg<std::string>;
134
* Reference to the value where the result of the extraction will
141
* \param value - Where the value extracted will be put.
143
ValueExtractor(std::string &value) : _value(value) {}
146
* Method that will attempt to parse the input stream for a value
147
* of type std::string.
148
* \param val - Where the string parsed will be put.
150
int extractValue( const std::string& val )
157
} //namespace VALUE_ARG_HELPER
160
* The basic labeled argument that parses a value.
161
* This is a template class, which means the type T defines the type
162
* that a given object will attempt to parse when the flag/name is matched
163
* on the command line. While there is nothing stopping you from creating
164
* an unflagged ValueArg, it is unwise and would cause significant problems.
165
* Instead use an UnlabeledValueArg.
168
class ValueArg : public Arg
173
* The value parsed from the command line.
174
* Can be of any type, as long as the >> operator for the type
180
* A human readable description of the type to be parsed.
181
* This is a hack, plain and simple. Ideally we would use RTTI to
182
* return the name of type T, but until there is some sort of
183
* consistent support for human readable names, we are left to our
186
std::string _typeDesc;
189
* A Constraint this Arg must conform to.
191
Constraint<T>* _constraint;
194
* Extracts the value from the string.
195
* Attempts to parse string as type T, if this fails an exception
197
* \param val - value to be parsed.
199
void _extractValue( const std::string& val );
204
* Labeled ValueArg constructor.
205
* You could conceivably call this constructor with a blank flag,
206
* but that would make you a bad person. It would also cause
207
* an exception to be thrown. If you want an unlabeled argument,
208
* use the other constructor.
209
* \param flag - The one character flag that identifies this
210
* argument on the command line.
211
* \param name - A one word name for the argument. Can be
212
* used as a long flag on the command line.
213
* \param desc - A description of what the argument is for or
215
* \param req - Whether the argument is required on the command
217
* \param value - The default value assigned to this argument if it
218
* is not present on the command line.
219
* \param typeDesc - A short, human readable description of the
220
* type that this object expects. This is used in the generation
221
* of the USAGE statement. The goal is to be helpful to the end user
223
* \param v - An optional visitor. You probably should not
224
* use this unless you have a very good reason.
226
ValueArg( const std::string& flag,
227
const std::string& name,
228
const std::string& desc,
231
const std::string& typeDesc,
236
* Labeled ValueArg constructor.
237
* You could conceivably call this constructor with a blank flag,
238
* but that would make you a bad person. It would also cause
239
* an exception to be thrown. If you want an unlabeled argument,
240
* use the other constructor.
241
* \param flag - The one character flag that identifies this
242
* argument on the command line.
243
* \param name - A one word name for the argument. Can be
244
* used as a long flag on the command line.
245
* \param desc - A description of what the argument is for or
247
* \param req - Whether the argument is required on the command
249
* \param value - The default value assigned to this argument if it
250
* is not present on the command line.
251
* \param typeDesc - A short, human readable description of the
252
* type that this object expects. This is used in the generation
253
* of the USAGE statement. The goal is to be helpful to the end user
255
* \param parser - A CmdLine parser object to add this Arg to
256
* \param v - An optional visitor. You probably should not
257
* use this unless you have a very good reason.
259
ValueArg( const std::string& flag,
260
const std::string& name,
261
const std::string& desc,
264
const std::string& typeDesc,
265
CmdLineInterface& parser,
269
* Labeled ValueArg constructor.
270
* You could conceivably call this constructor with a blank flag,
271
* but that would make you a bad person. It would also cause
272
* an exception to be thrown. If you want an unlabeled argument,
273
* use the other constructor.
274
* \param flag - The one character flag that identifies this
275
* argument on the command line.
276
* \param name - A one word name for the argument. Can be
277
* used as a long flag on the command line.
278
* \param desc - A description of what the argument is for or
280
* \param req - Whether the argument is required on the command
282
* \param value - The default value assigned to this argument if it
283
* is not present on the command line.
284
* \param constraint - A pointer to a Constraint object used
285
* to constrain this Arg.
286
* \param parser - A CmdLine parser object to add this Arg to.
287
* \param v - An optional visitor. You probably should not
288
* use this unless you have a very good reason.
290
ValueArg( const std::string& flag,
291
const std::string& name,
292
const std::string& desc,
295
Constraint<T>* constraint,
296
CmdLineInterface& parser,
300
* Labeled ValueArg constructor.
301
* You could conceivably call this constructor with a blank flag,
302
* but that would make you a bad person. It would also cause
303
* an exception to be thrown. If you want an unlabeled argument,
304
* use the other constructor.
305
* \param flag - The one character flag that identifies this
306
* argument on the command line.
307
* \param name - A one word name for the argument. Can be
308
* used as a long flag on the command line.
309
* \param desc - A description of what the argument is for or
311
* \param req - Whether the argument is required on the command
313
* \param value - The default value assigned to this argument if it
314
* is not present on the command line.
315
* \param constraint - A pointer to a Constraint object used
316
* to constrain this Arg.
317
* \param v - An optional visitor. You probably should not
318
* use this unless you have a very good reason.
320
ValueArg( const std::string& flag,
321
const std::string& name,
322
const std::string& desc,
325
Constraint<T>* constraint,
329
* Handles the processing of the argument.
330
* This re-implements the Arg version of this method to set the
331
* _value of the argument appropriately. It knows the difference
332
* between labeled and unlabeled.
333
* \param i - Pointer the the current argument in the list.
334
* \param args - Mutable list of strings. Passed
337
virtual bool processArg(int* i, std::vector<std::string>& args);
340
* Returns the value of the argument.
345
* Specialization of shortID.
346
* \param val - value to be used.
348
virtual std::string shortID(const std::string& val = "val") const;
351
* Specialization of longID.
352
* \param val - value to be used.
354
virtual std::string longID(const std::string& val = "val") const;
360
* Constructor implementation.
363
ValueArg<T>::ValueArg(const std::string& flag,
364
const std::string& name,
365
const std::string& desc,
368
const std::string& typeDesc,
370
: Arg(flag, name, desc, req, true, v),
372
_typeDesc( typeDesc ),
377
ValueArg<T>::ValueArg(const std::string& flag,
378
const std::string& name,
379
const std::string& desc,
382
const std::string& typeDesc,
383
CmdLineInterface& parser,
385
: Arg(flag, name, desc, req, true, v),
387
_typeDesc( typeDesc ),
394
ValueArg<T>::ValueArg(const std::string& flag,
395
const std::string& name,
396
const std::string& desc,
399
Constraint<T>* constraint,
401
: Arg(flag, name, desc, req, true, v),
403
_typeDesc( constraint->shortID() ),
404
_constraint( constraint )
408
ValueArg<T>::ValueArg(const std::string& flag,
409
const std::string& name,
410
const std::string& desc,
413
Constraint<T>* constraint,
414
CmdLineInterface& parser,
416
: Arg(flag, name, desc, req, true, v),
418
_typeDesc( constraint->shortID() ),
419
_constraint( constraint )
426
* Implementation of getValue().
429
T& ValueArg<T>::getValue() { return _value; }
432
* Implementation of processArg().
435
bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
437
if ( _ignoreable && Arg::ignoreRest() )
440
if ( _hasBlanks( args[*i] ) )
443
std::string flag = args[*i];
445
std::string value = "";
446
trimFlag( flag, value );
448
if ( argMatches( flag ) )
451
throw( CmdLineParseException("Argument already set!", toString()) );
453
if ( Arg::delimiter() != ' ' && value == "" )
454
throw( ArgParseException(
455
"Couldn't find delimiter for this argument!",
461
if ( static_cast<unsigned int>(*i) < args.size() )
462
_extractValue( args[*i] );
464
throw( ArgParseException("Missing a value for this argument!",
468
_extractValue( value );
479
* Implementation of shortID.
482
std::string ValueArg<T>::shortID(const std::string& val) const
484
return Arg::shortID( _typeDesc );
488
* Implementation of longID.
491
std::string ValueArg<T>::longID(const std::string& val) const
493
return Arg::longID( _typeDesc );
497
void ValueArg<T>::_extractValue( const std::string& val )
499
VALUE_ARG_HELPER::ValueExtractor<T> ve(_value);
501
int err = ve.extractValue(val);
503
if ( err == VALUE_ARG_HELPER::EXTRACT_FAILURE )
504
throw( ArgParseException("Couldn't read argument value from string '" +
505
val + "'", toString() ) );
507
if ( err == VALUE_ARG_HELPER::EXTRACT_TOO_MANY )
508
throw( ArgParseException(
509
"More than one valid value parsed from string '" +
510
val + "'", toString() ) );
512
if ( _constraint != NULL )
513
if ( ! _constraint->check( _value ) )
514
throw( CmdLineParseException( "Value '" + val +
515
"' does not meet constraint: " +
516
_constraint->description(),