~ubuntu-branches/ubuntu/trusty/hugin/trusty-proposed

« back to all changes in this revision

Viewing changes to src/foreign/tclap/ValueArg.h

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Metzler
  • Date: 2011-01-06 14:28:24 UTC
  • mfrom: (1.1.9 upstream) (0.1.21 experimental)
  • Revision ID: james.westby@ubuntu.com-20110106142824-zn9lxylg5z44dynn
* Drop Cyril Brulebois from Uploaders. Thank you very much for your work.
* Bump package version. (rc3 was re-released as 2010.4.0).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************** 
 
2
 * 
 
3
 *  file:  ValueArg.h
 
4
 * 
 
5
 *  Copyright (c) 2003, Michael E. Smoot .
 
6
 *  Copyright (c) 2004, Michael E. Smoot, Daniel Aarno.
 
7
 *  All rights reverved.
 
8
 * 
 
9
 *  See the file COPYING in the top directory of this distribution for
 
10
 *  more information.
 
11
 *  
 
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.  
 
19
 *  
 
20
 *****************************************************************************/ 
 
21
 
 
22
 
 
23
#ifndef TCLAP_VALUE_ARGUMENT_H
 
24
#define TCLAP_VALUE_ARGUMENT_H
 
25
 
 
26
#include <string>
 
27
#include <vector>
 
28
 
 
29
#include <tclap/Arg.h>
 
30
#include <tclap/Constraint.h>
 
31
 
 
32
#ifdef HAVE_CONFIG_H
 
33
#include <config.h>
 
34
#else
 
35
#define HAVE_SSTREAM
 
36
#endif
 
37
 
 
38
#if defined(HAVE_SSTREAM)
 
39
#include <sstream>
 
40
#elif defined(HAVE_STRSTREAM)
 
41
#include <strstream>
 
42
#else
 
43
#error "Need a stringstream (sstream or strstream) to compile!"
 
44
#endif
 
45
 
 
46
namespace TCLAP {
 
47
 
 
48
template<class T> class ValueArg;
 
49
 
 
50
namespace VALUE_ARG_HELPER {
 
51
 
 
52
enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY };
 
53
 
 
54
/**
 
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
 
61
 * work any other way.
 
62
 */
 
63
template<class T> class ValueExtractor 
 
64
{
 
65
        /**
 
66
         *
 
67
         */
 
68
        friend class ValueArg<T>;
 
69
 
 
70
        private:
 
71
 
 
72
                /**
 
73
                 * Reference to the value where the result of the extraction will 
 
74
                 * be put.
 
75
                 */
 
76
        T &_value;
 
77
 
 
78
                /**
 
79
                 * Constructor.
 
80
                 * \param value - Where the value extracted will be put.
 
81
                 */
 
82
        ValueExtractor(T &value) : _value(value) { }
 
83
 
 
84
                /**
 
85
                 * Method that will attempt to parse the input stream for a value
 
86
                 * of type T.
 
87
                 * \param val - Where the value parsed will be put.
 
88
                 */
 
89
        int extractValue( const std::string& val ) 
 
90
                {
 
91
 
 
92
#if defined(HAVE_SSTREAM)
 
93
                        std::istringstream is(val);
 
94
#elif defined(HAVE_STRSTREAM)
 
95
                        std::istrstream is(val.c_str());
 
96
#else
 
97
#error "Need a stringstream (sstream or strstream) to compile!"
 
98
#endif
 
99
 
 
100
            int valuesRead = 0;
 
101
            while ( is.good() ) 
 
102
                        {
 
103
                            if ( ! (is >> _value )) 
 
104
                    break;
 
105
        
 
106
                valuesRead++;
 
107
            }
 
108
      
 
109
            if ( is.fail() ) 
 
110
                return EXTRACT_FAILURE;
 
111
 
 
112
            if ( valuesRead > 1 )
 
113
                return EXTRACT_TOO_MANY;
 
114
 
 
115
            return 0;
 
116
        }
 
117
};
 
118
 
 
119
/**
 
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.
 
123
 */
 
124
template<> class ValueExtractor<std::string> 
 
125
{
 
126
        /**
 
127
         *
 
128
         */
 
129
    friend class ValueArg<std::string>;
 
130
 
 
131
    private:
 
132
        
 
133
                /**
 
134
                 * Reference to the value where the result of the extraction will 
 
135
                 * be put.
 
136
                 */
 
137
        std::string &_value;
 
138
 
 
139
                /**
 
140
                 * Constructor.
 
141
                 * \param value - Where the value extracted will be put.
 
142
                 */
 
143
        ValueExtractor(std::string &value) : _value(value) {}
 
144
 
 
145
                /**
 
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.
 
149
                 */
 
150
        int extractValue( const std::string& val ) 
 
151
                {
 
152
            _value = val;
 
153
            return 0;
 
154
        }
 
155
};
 
156
 
 
157
} //namespace VALUE_ARG_HELPER 
 
158
 
 
159
/**
 
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.
 
166
 */
 
167
template<class T>
 
168
class ValueArg : public Arg 
 
169
{
 
170
    protected:
 
171
 
 
172
        /**
 
173
         * The value parsed from the command line.
 
174
         * Can be of any type, as long as the >> operator for the type
 
175
         * is defined.
 
176
         */
 
177
        T _value;
 
178
 
 
179
        /**
 
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
 
184
         * own devices.
 
185
         */
 
186
        std::string _typeDesc;
 
187
 
 
188
        /**
 
189
         * A Constraint this Arg must conform to. 
 
190
         */
 
191
        Constraint<T>* _constraint;
 
192
 
 
193
        /**
 
194
         * Extracts the value from the string.
 
195
         * Attempts to parse string as type T, if this fails an exception
 
196
         * is thrown.
 
197
         * \param val - value to be parsed. 
 
198
         */
 
199
        void _extractValue( const std::string& val );
 
200
 
 
201
        public:
 
202
 
 
203
        /**
 
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
 
214
         * does.
 
215
         * \param req - Whether the argument is required on the command
 
216
         * line.
 
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
 
222
         * of the program.
 
223
         * \param v - An optional visitor.  You probably should not
 
224
         * use this unless you have a very good reason.
 
225
         */
 
226
        ValueArg( const std::string& flag, 
 
227
                  const std::string& name, 
 
228
                  const std::string& desc, 
 
229
                  bool req, 
 
230
                  T value,
 
231
                  const std::string& typeDesc,
 
232
                  Visitor* v = NULL);
 
233
                                 
 
234
                                 
 
235
        /**
 
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
 
246
         * does.
 
247
         * \param req - Whether the argument is required on the command
 
248
         * line.
 
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
 
254
         * of the program.
 
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.
 
258
         */
 
259
        ValueArg( const std::string& flag, 
 
260
                  const std::string& name, 
 
261
                  const std::string& desc, 
 
262
                  bool req, 
 
263
                  T value,
 
264
                  const std::string& typeDesc,
 
265
                  CmdLineInterface& parser,
 
266
                  Visitor* v = NULL );
 
267
 
 
268
        /**
 
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
 
279
         * does.
 
280
         * \param req - Whether the argument is required on the command
 
281
         * line.
 
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.
 
289
         */
 
290
        ValueArg( const std::string& flag, 
 
291
                  const std::string& name, 
 
292
                  const std::string& desc, 
 
293
                  bool req, 
 
294
                  T value,
 
295
                  Constraint<T>* constraint,
 
296
                  CmdLineInterface& parser,
 
297
                  Visitor* v = NULL );
 
298
          
 
299
        /**
 
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
 
310
         * does.
 
311
         * \param req - Whether the argument is required on the command
 
312
         * line.
 
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.
 
319
         */
 
320
        ValueArg( const std::string& flag, 
 
321
                  const std::string& name, 
 
322
                  const std::string& desc, 
 
323
                  bool req, 
 
324
                  T value,
 
325
                  Constraint<T>* constraint,
 
326
                  Visitor* v = NULL );
 
327
 
 
328
        /**
 
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 
 
335
         * in from main().
 
336
         */
 
337
        virtual bool processArg(int* i, std::vector<std::string>& args); 
 
338
 
 
339
        /**
 
340
         * Returns the value of the argument.
 
341
         */
 
342
        T& getValue() ;
 
343
 
 
344
        /**
 
345
         * Specialization of shortID.
 
346
         * \param val - value to be used.
 
347
         */
 
348
        virtual std::string shortID(const std::string& val = "val") const;
 
349
 
 
350
        /**
 
351
         * Specialization of longID.
 
352
         * \param val - value to be used.
 
353
         */
 
354
        virtual std::string longID(const std::string& val = "val") const;
 
355
 
 
356
};
 
357
 
 
358
 
 
359
/**
 
360
 * Constructor implementation.
 
361
 */
 
362
template<class T>
 
363
ValueArg<T>::ValueArg(const std::string& flag, 
 
364
                      const std::string& name, 
 
365
                      const std::string& desc, 
 
366
                      bool req, 
 
367
                      T val,
 
368
                      const std::string& typeDesc,
 
369
                      Visitor* v)
 
370
: Arg(flag, name, desc, req, true, v),
 
371
  _value( val ),
 
372
  _typeDesc( typeDesc ),
 
373
  _constraint( NULL )
 
374
{ }
 
375
 
 
376
template<class T>
 
377
ValueArg<T>::ValueArg(const std::string& flag, 
 
378
                      const std::string& name, 
 
379
                      const std::string& desc, 
 
380
                      bool req, 
 
381
                      T val,
 
382
                      const std::string& typeDesc,
 
383
                      CmdLineInterface& parser,
 
384
                      Visitor* v)
 
385
: Arg(flag, name, desc, req, true, v),
 
386
  _value( val ),
 
387
  _typeDesc( typeDesc ),
 
388
  _constraint( NULL )
 
389
 
390
    parser.add( this );
 
391
}
 
392
 
 
393
template<class T>
 
394
ValueArg<T>::ValueArg(const std::string& flag, 
 
395
                      const std::string& name, 
 
396
                      const std::string& desc, 
 
397
                      bool req, 
 
398
                      T val,
 
399
                      Constraint<T>* constraint,
 
400
                      Visitor* v)
 
401
: Arg(flag, name, desc, req, true, v),
 
402
  _value( val ),
 
403
  _typeDesc( constraint->shortID() ),
 
404
  _constraint( constraint )
 
405
{ }
 
406
 
 
407
template<class T>
 
408
ValueArg<T>::ValueArg(const std::string& flag, 
 
409
                      const std::string& name, 
 
410
                      const std::string& desc, 
 
411
                      bool req, 
 
412
                      T val,
 
413
                      Constraint<T>* constraint,
 
414
                      CmdLineInterface& parser,
 
415
                      Visitor* v)
 
416
: Arg(flag, name, desc, req, true, v),
 
417
  _value( val ),
 
418
  _typeDesc( constraint->shortID() ),
 
419
  _constraint( constraint )
 
420
 
421
    parser.add( this );
 
422
}
 
423
 
 
424
 
 
425
/**
 
426
 * Implementation of getValue().
 
427
 */
 
428
template<class T>
 
429
T& ValueArg<T>::getValue() { return _value; }
 
430
 
 
431
/**
 
432
 * Implementation of processArg().
 
433
 */
 
434
template<class T>
 
435
bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
 
436
{
 
437
    if ( _ignoreable && Arg::ignoreRest() )
 
438
                return false;
 
439
 
 
440
    if ( _hasBlanks( args[*i] ) )
 
441
                return false;
 
442
 
 
443
    std::string flag = args[*i];
 
444
 
 
445
    std::string value = "";
 
446
    trimFlag( flag, value );
 
447
 
 
448
    if ( argMatches( flag ) )
 
449
    {
 
450
        if ( _alreadySet )
 
451
                        throw( CmdLineParseException("Argument already set!", toString()) );
 
452
 
 
453
        if ( Arg::delimiter() != ' ' && value == "" )
 
454
                        throw( ArgParseException( 
 
455
                                                        "Couldn't find delimiter for this argument!",
 
456
                             toString() ) );
 
457
 
 
458
        if ( value == "" )
 
459
        {
 
460
            (*i)++;
 
461
            if ( static_cast<unsigned int>(*i) < args.size() ) 
 
462
                                _extractValue( args[*i] );
 
463
            else
 
464
                                throw( ArgParseException("Missing a value for this argument!",
 
465
                                                    toString() ) );
 
466
        }
 
467
        else
 
468
                        _extractValue( value );
 
469
                                
 
470
        _alreadySet = true;
 
471
        _checkWithVisitor();
 
472
        return true;
 
473
    }   
 
474
    else
 
475
                return false;
 
476
}
 
477
 
 
478
/**
 
479
 * Implementation of shortID.
 
480
 */
 
481
template<class T>
 
482
std::string ValueArg<T>::shortID(const std::string& val) const
 
483
{
 
484
    return Arg::shortID( _typeDesc ); 
 
485
}
 
486
 
 
487
/**
 
488
 * Implementation of longID.
 
489
 */
 
490
template<class T>
 
491
std::string ValueArg<T>::longID(const std::string& val) const
 
492
{
 
493
    return Arg::longID( _typeDesc ); 
 
494
}
 
495
 
 
496
template<class T>
 
497
void ValueArg<T>::_extractValue( const std::string& val ) 
 
498
{
 
499
        VALUE_ARG_HELPER::ValueExtractor<T> ve(_value);
 
500
 
 
501
        int err = ve.extractValue(val);
 
502
 
 
503
        if ( err == VALUE_ARG_HELPER::EXTRACT_FAILURE )
 
504
                throw( ArgParseException("Couldn't read argument value from string '" +
 
505
                                     val + "'", toString() ) );
 
506
 
 
507
        if ( err == VALUE_ARG_HELPER::EXTRACT_TOO_MANY )
 
508
                throw( ArgParseException(
 
509
                                        "More than one valid value parsed from string '" +
 
510
                                    val + "'", toString() ) );
 
511
 
 
512
        if ( _constraint != NULL )
 
513
                if ( ! _constraint->check( _value ) )
 
514
                        throw( CmdLineParseException( "Value '" + val + 
 
515
                                                                              "' does not meet constraint: " + 
 
516
                                                                                  _constraint->description(),
 
517
                                                                                  toString() ) );
 
518
}
 
519
 
 
520
} // namespace TCLAP
 
521
 
 
522
#endif