Go to the documentation of this file.00001
00011
00012
00013
00014
00015
00016 #ifndef TCLAP_ARGUMENT_H
00017 #define TCLAP_ARGUMENT_H
00018
00019 #include <string>
00020 #include <vector>
00021 #include <list>
00022 #include <iostream>
00023
00024 #include "arg_exception.hpp"
00025 #include "visitor.hpp"
00026 #include "cmd_line_interface.hpp"
00027
00028 namespace ecl {
00029
00037 class Arg
00038 {
00039 private:
00040
00044 static bool& ignoreRestRef() { static bool ign = false; return ign; }
00045
00050 static char& delimiterRef() { static char delim = ' '; return delim; }
00051
00052 protected:
00053
00062 std::string _flag;
00063
00071 std::string _name;
00072
00076 std::string _description;
00077
00081 bool _required;
00082
00087 std::string _requireLabel;
00088
00094 bool _valueRequired;
00095
00101 bool _alreadySet;
00102
00109 Visitor* _visitor;
00110
00114 bool _ignoreable;
00115
00120 bool _xorSet;
00121
00122 bool _acceptsMultipleValues;
00123
00127 void _checkWithVisitor() const;
00128
00142 Arg( const std::string& flag,
00143 const std::string& name,
00144 const std::string& desc,
00145 bool req,
00146 bool valreq,
00147 Visitor* v = NULL );
00148
00149 public:
00153 virtual ~Arg();
00154
00159 virtual void addToList( std::list<Arg*>& argList ) const;
00160
00164 static void beginIgnoring() { ignoreRestRef() = true; }
00165
00169 static bool ignoreRest() { return ignoreRestRef(); }
00170
00175 static char delimiter() { return delimiterRef(); }
00176
00182 static char blankChar() { return '*'; }
00183
00187 static char flagStartChar() { return '-'; }
00188
00193 static std::string flagStartString() { return "-"; }
00194
00199 static std::string nameStartString() { return "--"; }
00200
00204 static std::string ignoreNameString() { return "ignore_rest"; }
00205
00210 static void setDelimiter( char c ) { delimiterRef() = c; }
00211
00219 virtual bool processArg(int *i, std::vector<std::string>& args) = 0;
00220
00226 virtual bool operator==(const Arg& a) const;
00227
00231 const std::string& getFlag() const;
00232
00236 const std::string& getName() const;
00237
00241 std::string getDescription() const;
00242
00246 virtual bool isRequired() const;
00247
00252 void forceRequired();
00253
00258 void xorSet();
00259
00263 bool isValueRequired() const;
00264
00269 bool isSet() const;
00270
00274 bool isIgnoreable() const;
00275
00284 virtual bool argMatches( const std::string& s ) const;
00285
00290 virtual std::string toString() const;
00291
00296 virtual std::string shortID( const std::string& valueId = "val" ) const;
00297
00302 virtual std::string longID( const std::string& valueId = "val" ) const;
00303
00311 virtual void trimFlag( std::string& flag, std::string& value ) const;
00312
00319 bool _hasBlanks( const std::string& s ) const;
00320
00326 void setRequireLabel( const std::string& s );
00327
00328 virtual bool allowMore();
00329 virtual bool acceptsMultipleValues();
00330
00331 };
00332
00336 typedef std::list<Arg*>::iterator ArgListIterator;
00337
00341 typedef std::vector<Arg*>::iterator ArgVectorIterator;
00342
00346 typedef std::list<Visitor*>::iterator VisitorListIterator;
00347
00348
00350
00352
00353 inline Arg::Arg(const std::string& flag,
00354 const std::string& name,
00355 const std::string& desc,
00356 bool req,
00357 bool valreq,
00358 Visitor* v) :
00359 _flag(flag),
00360 _name(name),
00361 _description(desc),
00362 _required(req),
00363 _requireLabel("required"),
00364 _valueRequired(valreq),
00365 _alreadySet(false),
00366 _visitor( v ),
00367 _ignoreable(true),
00368 _xorSet(false),
00369 _acceptsMultipleValues(false)
00370 {
00371 if ( _flag.length() > 1 )
00372 throw(SpecificationException(
00373 "Argument flag can only be one character long", toString() ) );
00374
00375 if ( _name != ignoreNameString() &&
00376 ( _flag == Arg::flagStartString() ||
00377 _flag == Arg::nameStartString() ||
00378 _flag == " " ) )
00379 throw(SpecificationException("Argument flag cannot be either '" +
00380 Arg::flagStartString() + "' or '" +
00381 Arg::nameStartString() + "' or a space.",
00382 toString() ) );
00383
00384 if ( ( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) ||
00385 ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) ||
00386 ( _name.find( " ", 0 ) != std::string::npos ) )
00387 throw(SpecificationException("Argument name cannot contain either '" +
00388 Arg::flagStartString() + "' or '" +
00389 Arg::nameStartString() + "' or space.",
00390 toString() ) );
00391
00392 }
00393
00394 inline Arg::~Arg() { }
00395
00396 inline std::string Arg::shortID( const std::string& valueId ) const
00397 {
00398 std::string id = "";
00399
00400 if ( _flag != "" )
00401 id = Arg::flagStartString() + _flag;
00402 else
00403 id = Arg::nameStartString() + _name;
00404
00405 std::string delim = " ";
00406 delim[0] = Arg::delimiter();
00407
00408 if ( _valueRequired )
00409 id += delim + "<" + valueId + ">";
00410
00411 if ( !_required )
00412 id = "[" + id + "]";
00413
00414 return id;
00415 }
00416
00417 inline std::string Arg::longID( const std::string& valueId ) const
00418 {
00419 std::string id = "";
00420
00421 if ( _flag != "" )
00422 {
00423 id += Arg::flagStartString() + _flag;
00424
00425 if ( _valueRequired )
00426 id += " <" + valueId + ">";
00427
00428 id += ", ";
00429 }
00430
00431 id += Arg::nameStartString() + _name;
00432
00433 if ( _valueRequired )
00434 id += " <" + valueId + ">";
00435
00436 return id;
00437
00438 }
00439
00440 inline bool Arg::operator==(const Arg& a) const
00441 {
00442 if ( ( _flag != "" && _flag == a._flag ) || _name == a._name)
00443 return true;
00444 else
00445 return false;
00446 }
00447
00448 inline std::string Arg::getDescription() const
00449 {
00450 std::string desc = "";
00451 if ( _required )
00452 desc = "(" + _requireLabel + ") ";
00453
00454
00455
00456
00457 desc += _description;
00458 return desc;
00459 }
00460
00461 inline const std::string& Arg::getFlag() const { return _flag; }
00462
00463 inline const std::string& Arg::getName() const { return _name; }
00464
00465 inline bool Arg::isRequired() const { return _required; }
00466
00467 inline bool Arg::isValueRequired() const { return _valueRequired; }
00468
00469 inline bool Arg::isSet() const
00470 {
00471 if ( _alreadySet && !_xorSet )
00472 return true;
00473 else
00474 return false;
00475 }
00476
00477 inline bool Arg::isIgnoreable() const { return _ignoreable; }
00478
00479 inline void Arg::setRequireLabel( const std::string& s)
00480 {
00481 _requireLabel = s;
00482 }
00483
00484 inline bool Arg::argMatches( const std::string& argFlag ) const
00485 {
00486 if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) ||
00487 argFlag == Arg::nameStartString() + _name )
00488 return true;
00489 else
00490 return false;
00491 }
00492
00493 inline std::string Arg::toString() const
00494 {
00495 std::string s = "";
00496
00497 if ( _flag != "" )
00498 s += Arg::flagStartString() + _flag + " ";
00499
00500 s += "(" + Arg::nameStartString() + _name + ")";
00501
00502 return s;
00503 }
00504
00505 inline void Arg::_checkWithVisitor() const
00506 {
00507 if ( _visitor != NULL )
00508 _visitor->visit();
00509 }
00510
00514 inline void Arg::trimFlag(std::string& flag, std::string& value) const
00515 {
00516 int stop = 0;
00517 for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ )
00518 if ( flag[i] == Arg::delimiter() )
00519 {
00520 stop = i;
00521 break;
00522 }
00523
00524 if ( stop > 1 )
00525 {
00526 value = flag.substr(stop+1);
00527 flag = flag.substr(0,stop);
00528 }
00529
00530 }
00531
00535 inline bool Arg::_hasBlanks( const std::string& s ) const
00536 {
00537 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ )
00538 if ( s[i] == Arg::blankChar() )
00539 return true;
00540
00541 return false;
00542 }
00543
00544 inline void Arg::forceRequired()
00545 {
00546 _required = true;
00547 }
00548
00549 inline void Arg::xorSet()
00550 {
00551 _alreadySet = true;
00552 _xorSet = true;
00553 }
00554
00558 inline void Arg::addToList( std::list<Arg*>& argList ) const
00559 {
00560 argList.push_front( const_cast<Arg*>(this) );
00561 }
00562
00563 inline bool Arg::allowMore()
00564 {
00565 return false;
00566 }
00567
00568 inline bool Arg::acceptsMultipleValues()
00569 {
00570 return _acceptsMultipleValues;
00571 }
00572
00574
00576
00577 };
00578
00579 #endif
00580