tclap 1.2.2
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
26#ifndef TCLAP_ARGUMENT_H
27#define TCLAP_ARGUMENT_H
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32
33#include <string>
34#include <vector>
35#include <list>
36#include <iostream>
37#include <iomanip>
38#include <cstdio>
39
40#include <tclap/sstream.h>
41
42#if defined(HAVE_SSTREAM)
43#include <sstream>
44typedef std::istringstream istringstream;
45#elif defined(HAVE_STRSTREAM)
46#include <strstream>
47typedef std::istrstream istringstream;
48#else
49#error "Need a stringstream (sstream or strstream) to compile!"
50#endif
51
52#include <tclap/ArgException.h>
53#include <tclap/Visitor.h>
55#include <tclap/ArgTraits.h>
57
58namespace TCLAP {
59
65class Arg
66{
67 private:
71 Arg(const Arg& rhs);
72
76 Arg& operator=(const Arg& rhs);
77
81 static bool& ignoreRestRef() { static bool ign = false; return ign; }
82
87 static char& delimiterRef() { static char delim = ' '; return delim; }
88
89 protected:
90
99 std::string _flag;
100
108 std::string _name;
109
113 std::string _description;
114
119
124 std::string _requireLabel;
125
132
139
147
152
158
160
164 void _checkWithVisitor() const;
165
179 Arg( const std::string& flag,
180 const std::string& name,
181 const std::string& desc,
182 bool req,
183 bool valreq,
184 Visitor* v = NULL );
185
186 public:
190 virtual ~Arg();
191
196 virtual void addToList( std::list<Arg*>& argList ) const;
197
201 static void beginIgnoring() { ignoreRestRef() = true; }
202
206 static bool ignoreRest() { return ignoreRestRef(); }
207
212 static char delimiter() { return delimiterRef(); }
213
218 static char blankChar() { return (char)7; }
219
224#ifndef TCLAP_FLAGSTARTCHAR
225#define TCLAP_FLAGSTARTCHAR '-'
226#endif
227 static char flagStartChar() { return TCLAP_FLAGSTARTCHAR; }
228
234#ifndef TCLAP_FLAGSTARTSTRING
235#define TCLAP_FLAGSTARTSTRING "-"
236#endif
237 static const std::string flagStartString() { return TCLAP_FLAGSTARTSTRING; }
238
243#ifndef TCLAP_NAMESTARTSTRING
244#define TCLAP_NAMESTARTSTRING "--"
245#endif
246 static const std::string nameStartString() { return TCLAP_NAMESTARTSTRING; }
247
251 static const std::string ignoreNameString() { return "ignore_rest"; }
252
257 static void setDelimiter( char c ) { delimiterRef() = c; }
258
266 virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
267
273 virtual bool operator==(const Arg& a) const;
274
278 const std::string& getFlag() const;
279
283 const std::string& getName() const;
284
288 std::string getDescription() const;
289
293 virtual bool isRequired() const;
294
299 void forceRequired();
300
305 void xorSet();
306
310 bool isValueRequired() const;
311
316 bool isSet() const;
317
321 bool isIgnoreable() const;
322
331 virtual bool argMatches( const std::string& s ) const;
332
337 virtual std::string toString() const;
338
343 virtual std::string shortID( const std::string& valueId = "val" ) const;
344
349 virtual std::string longID( const std::string& valueId = "val" ) const;
350
358 virtual void trimFlag( std::string& flag, std::string& value ) const;
359
366 bool _hasBlanks( const std::string& s ) const;
367
373 void setRequireLabel( const std::string& s );
374
379 virtual bool allowMore();
380
385 virtual bool acceptsMultipleValues();
386
391 virtual void reset();
392};
393
397typedef std::list<Arg*>::iterator ArgListIterator;
398
402typedef std::vector<Arg*>::iterator ArgVectorIterator;
403
407typedef std::list<Visitor*>::iterator VisitorListIterator;
408
409/*
410 * Extract a value of type T from it's string representation contained
411 * in strVal. The ValueLike parameter used to select the correct
412 * specialization of ExtractValue depending on the value traits of T.
413 * ValueLike traits use operator>> to assign the value from strVal.
414 */
415template<typename T> void
416ExtractValue(T &destVal, const std::string& strVal, ValueLike vl)
417{
418 static_cast<void>(vl); // Avoid warning about unused vl
419 istringstream is(strVal.c_str());
420
421 int valuesRead = 0;
422 while ( is.good() ) {
423 if ( is.peek() != EOF )
424#ifdef TCLAP_SETBASE_ZERO
425 is >> std::setbase(0) >> destVal;
426#else
427 is >> destVal;
428#endif
429 else
430 break;
431
432 valuesRead++;
433 }
434
435 if ( is.fail() )
436 throw( ArgParseException("Couldn't read argument value "
437 "from string '" + strVal + "'"));
438
439
440 if ( valuesRead > 1 )
441 throw( ArgParseException("More than one valid value parsed from "
442 "string '" + strVal + "'"));
443
444}
445
446/*
447 * Extract a value of type T from it's string representation contained
448 * in strVal. The ValueLike parameter used to select the correct
449 * specialization of ExtractValue depending on the value traits of T.
450 * StringLike uses assignment (operator=) to assign from strVal.
451 */
452template<typename T> void
453ExtractValue(T &destVal, const std::string& strVal, StringLike sl)
454{
455 static_cast<void>(sl); // Avoid warning about unused sl
456 SetString(destVal, strVal);
457}
458
460//BEGIN Arg.cpp
462
463inline Arg::Arg(const std::string& flag,
464 const std::string& name,
465 const std::string& desc,
466 bool req,
467 bool valreq,
468 Visitor* v) :
469 _flag(flag),
470 _name(name),
471 _description(desc),
472 _required(req),
473 _requireLabel("required"),
474 _valueRequired(valreq),
475 _alreadySet(false),
476 _visitor( v ),
477 _ignoreable(true),
478 _xorSet(false),
480{
481 if ( _flag.length() > 1 )
483 "Argument flag can only be one character long", toString() ) );
484
485 if ( _name != ignoreNameString() &&
488 _flag == " " ) )
489 throw(SpecificationException("Argument flag cannot be either '" +
490 Arg::flagStartString() + "' or '" +
491 Arg::nameStartString() + "' or a space.",
492 toString() ) );
493
494 if ( ( _name.substr( 0, Arg::flagStartString().length() ) == Arg::flagStartString() ) ||
495 ( _name.substr( 0, Arg::nameStartString().length() ) == Arg::nameStartString() ) ||
496 ( _name.find( " ", 0 ) != std::string::npos ) )
497 throw(SpecificationException("Argument name begin with either '" +
498 Arg::flagStartString() + "' or '" +
499 Arg::nameStartString() + "' or space.",
500 toString() ) );
501
502}
503
504inline Arg::~Arg() { }
505
506inline std::string Arg::shortID( const std::string& valueId ) const
507{
508 std::string id = "";
509
510 if ( _flag != "" )
512 else
514
515 if ( _valueRequired )
516 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
517
518 if ( !_required )
519 id = "[" + id + "]";
520
521 return id;
522}
523
524inline std::string Arg::longID( const std::string& valueId ) const
525{
526 std::string id = "";
527
528 if ( _flag != "" )
529 {
530 id += Arg::flagStartString() + _flag;
531
532 if ( _valueRequired )
533 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
534
535 id += ", ";
536 }
537
538 id += Arg::nameStartString() + _name;
539
540 if ( _valueRequired )
541 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">";
542
543 return id;
544
545}
546
547inline bool Arg::operator==(const Arg& a) const
548{
549 if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
550 return true;
551 else
552 return false;
553}
554
555inline std::string Arg::getDescription() const
556{
557 std::string desc = "";
558 if ( _required )
559 desc = "(" + _requireLabel + ") ";
560
561// if ( _valueRequired )
562// desc += "(value required) ";
563
564 desc += _description;
565 return desc;
566}
567
568inline const std::string& Arg::getFlag() const { return _flag; }
569
570inline const std::string& Arg::getName() const { return _name; }
571
572inline bool Arg::isRequired() const { return _required; }
573
574inline bool Arg::isValueRequired() const { return _valueRequired; }
575
576inline bool Arg::isSet() const
577{
578 if ( _alreadySet && !_xorSet )
579 return true;
580 else
581 return false;
582}
583
584inline bool Arg::isIgnoreable() const { return _ignoreable; }
585
586inline void Arg::setRequireLabel( const std::string& s)
587{
588 _requireLabel = s;
589}
590
591inline bool Arg::argMatches( const std::string& argFlag ) const
592{
593 if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
594 argFlag == Arg::nameStartString() + _name )
595 return true;
596 else
597 return false;
598}
599
600inline std::string Arg::toString() const
601{
602 std::string s = "";
603
604 if ( _flag != "" )
605 s += Arg::flagStartString() + _flag + " ";
606
607 s += "(" + Arg::nameStartString() + _name + ")";
608
609 return s;
610}
611
612inline void Arg::_checkWithVisitor() const
613{
614 if ( _visitor != NULL )
615 _visitor->visit();
616}
617
621inline void Arg::trimFlag(std::string& flag, std::string& value) const
622{
623 int stop = 0;
624 for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
625 if ( flag[i] == Arg::delimiter() )
626 {
627 stop = i;
628 break;
629 }
630
631 if ( stop > 1 )
632 {
633 value = flag.substr(stop+1);
634 flag = flag.substr(0,stop);
635 }
636
637}
638
642inline bool Arg::_hasBlanks( const std::string& s ) const
643{
644 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
645 if ( s[i] == Arg::blankChar() )
646 return true;
647
648 return false;
649}
650
652{
653 _required = true;
654}
655
656inline void Arg::xorSet()
657{
658 _alreadySet = true;
659 _xorSet = true;
660}
661
665inline void Arg::addToList( std::list<Arg*>& argList ) const
666{
667 argList.push_front( const_cast<Arg*>(this) );
668}
669
670inline bool Arg::allowMore()
671{
672 return false;
673}
674
676{
678}
679
680inline void Arg::reset()
681{
682 _xorSet = false;
683 _alreadySet = false;
684}
685
687//END Arg.cpp
689
690} //namespace TCLAP
691
692#endif
693
#define TCLAP_FLAGSTARTSTRING
The sting that indicates the beginning of a flag.
Definition Arg.h:235
#define TCLAP_FLAGSTARTCHAR
The char that indicates the beginning of a flag.
Definition Arg.h:225
std::istringstream istringstream
Definition Arg.h:44
#define TCLAP_NAMESTARTSTRING
The sting that indicates the beginning of a name.
Definition Arg.h:244
Thrown from within the child Arg classes when it fails to properly parse the argument it has been pas...
static char blankChar()
The char used as a place holder when SwitchArgs are combined.
Definition Arg.h:218
void _checkWithVisitor() const
Performs the special handling described by the Visitor.
Definition Arg.h:612
bool _acceptsMultipleValues
Definition Arg.h:159
virtual ~Arg()
Destructor.
Definition Arg.h:504
bool isSet() const
Indicates whether the argument has already been set.
Definition Arg.h:576
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition Arg.h:524
static const std::string nameStartString()
Definition Arg.h:246
static void beginIgnoring()
Begin ignoring arguments since the "--" argument was specified.
Definition Arg.h:201
std::string _requireLabel
Label to be used in usage description.
Definition Arg.h:124
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:642
static bool ignoreRest()
Whether to ignore the rest.
Definition Arg.h:206
bool isIgnoreable() const
Indicates whether the argument can be ignored, if desired.
Definition Arg.h:584
void forceRequired()
Sets _required to true.
Definition Arg.h:651
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...
const std::string & getFlag() const
Returns the argument flag.
Definition Arg.h:568
static const std::string ignoreNameString()
The name used to identify the ignore rest argument.
Definition Arg.h:251
bool _valueRequired
Indicates whether a value is required for the argument.
Definition Arg.h:131
bool isValueRequired() const
Indicates whether a value must be specified for argument.
Definition Arg.h:574
static char flagStartChar()
Definition Arg.h:227
bool _alreadySet
Indicates whether the argument has been set.
Definition Arg.h:138
bool _ignoreable
Whether this argument can be ignored, if desired.
Definition Arg.h:151
std::string _description
Description of the argument.
Definition Arg.h:113
virtual void addToList(std::list< Arg * > &argList) const
Adds this to the specified list of Args.
Definition Arg.h:665
virtual bool allowMore()
Used for MultiArgs and XorHandler to determine whether args can still be set.
Definition Arg.h:670
const std::string & getName() const
Returns the argument name.
Definition Arg.h:570
Visitor * _visitor
A pointer to a visitor object.
Definition Arg.h:146
static char delimiter()
The delimiter that separates an argument flag/name from the value.
Definition Arg.h:212
void setRequireLabel(const std::string &s)
Sets the requireLabel.
Definition Arg.h:586
std::string getDescription() const
Returns the argument description.
Definition Arg.h:555
bool _xorSet
Indicates that the arg was set as part of an XOR and not on the command line.
Definition Arg.h:157
virtual void reset()
Clears the Arg object and allows it to be reused by new command lines.
Definition Arg.h:680
std::string _name
A single word namd identifying the argument.
Definition Arg.h:108
virtual bool argMatches(const std::string &s) const
A method that tests whether a string matches this argument.
Definition Arg.h:591
static void setDelimiter(char c)
Sets the delimiter for all arguments.
Definition Arg.h:257
bool _required
Indicating whether the argument is required.
Definition Arg.h:118
virtual bool acceptsMultipleValues()
Use by output classes to determine whether an Arg accepts multiple values.
Definition Arg.h:675
virtual void trimFlag(std::string &flag, std::string &value) const
Trims a value off of the flag.
Definition Arg.h:621
virtual std::string toString() const
Returns a simple string representation of the argument.
Definition Arg.h:600
std::string _flag
The single char flag used to identify the argument.
Definition Arg.h:99
void xorSet()
Sets the _alreadySet value to true.
Definition Arg.h:656
virtual bool isRequired() const
Indicates whether the argument is required.
Definition Arg.h:572
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition Arg.h:506
virtual bool operator==(const Arg &a) const
Operator ==.
Definition Arg.h:547
static const std::string flagStartString()
Definition Arg.h:237
Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
A base class that defines the interface for visitors.
Definition Visitor.h:32
Definition Arg.h:58
std::vector< Arg * >::iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition Arg.h:402
std::list< Visitor * >::iterator VisitorListIterator
Typedef of a Visitor list iterator.
Definition Arg.h:407
std::istringstream istringstream
Definition sstream.h:37
void SetString(T &dst, const std::string &src)
std::list< Arg * >::iterator ArgListIterator
Typedef of an Arg list iterator.
Definition Arg.h:397
void ExtractValue(T &destVal, const std::string &strVal, ValueLike vl)
Definition Arg.h:416
A string like argument value type is a value that can be set using operator=(string).
Definition ArgTraits.h:48
A value like argument value type is a value that can be set using operator>>.
Definition ArgTraits.h:38