UniversalIndentGUI 1.2.0
|
00001 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*- 00002 00003 /****************************************************************************** 00004 * 00005 * file: Arg.h 00006 * 00007 * Copyright (c) 2003, Michael E. Smoot . 00008 * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno . 00009 * All rights reverved. 00010 * 00011 * See the file COPYING in the top directory of this distribution for 00012 * more information. 00013 * 00014 * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00017 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00019 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00020 * DEALINGS IN THE SOFTWARE. 00021 * 00022 *****************************************************************************/ 00023 00024 00025 #ifndef TCLAP_ARGUMENT_H 00026 #define TCLAP_ARGUMENT_H 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #else 00031 #define HAVE_SSTREAM 00032 #endif 00033 00034 #include <string> 00035 #include <vector> 00036 #include <list> 00037 #include <iostream> 00038 #include <iomanip> 00039 #include <cstdio> 00040 00041 #if defined(HAVE_SSTREAM) 00042 #include <sstream> 00043 typedef std::istringstream istringstream; 00044 #elif defined(HAVE_STRSTREAM) 00045 #include <strstream> 00046 typedef std::istrstream istringstream; 00047 #else 00048 #error "Need a stringstream (sstream or strstream) to compile!" 00049 #endif 00050 00051 #include <tclap/ArgException.h> 00052 #include <tclap/Visitor.h> 00053 #include <tclap/CmdLineInterface.h> 00054 #include <tclap/ArgTraits.h> 00055 #include <tclap/StandardTraits.h> 00056 00057 namespace TCLAP { 00058 00064 class Arg 00065 { 00066 private: 00067 00071 static bool& ignoreRestRef() { static bool ign = false; return ign; } 00072 00077 static char& delimiterRef() { static char delim = ' '; return delim; } 00078 00079 protected: 00080 00089 std::string _flag; 00090 00098 std::string _name; 00099 00103 std::string _description; 00104 00108 bool _required; 00109 00114 std::string _requireLabel; 00115 00121 bool _valueRequired; 00122 00128 bool _alreadySet; 00129 00136 Visitor* _visitor; 00137 00141 bool _ignoreable; 00142 00147 bool _xorSet; 00148 00149 bool _acceptsMultipleValues; 00150 00154 void _checkWithVisitor() const; 00155 00169 Arg( const std::string& flag, 00170 const std::string& name, 00171 const std::string& desc, 00172 bool req, 00173 bool valreq, 00174 Visitor* v = NULL ); 00175 00176 public: 00180 virtual ~Arg(); 00181 00186 virtual void addToList( std::list<Arg*>& argList ) const; 00187 00191 static void beginIgnoring() { ignoreRestRef() = true; } 00192 00196 static bool ignoreRest() { return ignoreRestRef(); } 00197 00202 static char delimiter() { return delimiterRef(); } 00203 00208 static char blankChar() { return (char)7; } 00209 00213 static char flagStartChar() { return '-'; } 00214 00219 static const std::string flagStartString() { return "-"; } 00220 00225 static const std::string nameStartString() { return "--"; } 00226 00230 static const std::string ignoreNameString() { return "ignore_rest"; } 00231 00236 static void setDelimiter( char c ) { delimiterRef() = c; } 00237 00245 virtual bool processArg(int *i, std::vector<std::string>& args) = 0; 00246 00252 virtual bool operator==(const Arg& a) const; 00253 00257 const std::string& getFlag() const; 00258 00262 const std::string& getName() const; 00263 00267 std::string getDescription() const; 00268 00272 virtual bool isRequired() const; 00273 00278 void forceRequired(); 00279 00284 void xorSet(); 00285 00289 bool isValueRequired() const; 00290 00295 bool isSet() const; 00296 00300 bool isIgnoreable() const; 00301 00310 virtual bool argMatches( const std::string& s ) const; 00311 00316 virtual std::string toString() const; 00317 00322 virtual std::string shortID( const std::string& valueId = "val" ) const; 00323 00328 virtual std::string longID( const std::string& valueId = "val" ) const; 00329 00337 virtual void trimFlag( std::string& flag, std::string& value ) const; 00338 00345 bool _hasBlanks( const std::string& s ) const; 00346 00352 void setRequireLabel( const std::string& s ); 00353 00358 virtual bool allowMore(); 00359 00364 virtual bool acceptsMultipleValues(); 00365 00370 virtual void reset(); 00371 }; 00372 00376 typedef std::list<Arg*>::iterator ArgListIterator; 00377 00381 typedef std::vector<Arg*>::iterator ArgVectorIterator; 00382 00386 typedef std::list<Visitor*>::iterator VisitorListIterator; 00387 00388 /* 00389 * Extract a value of type T from it's string representation contained 00390 * in strVal. The ValueLike parameter used to select the correct 00391 * specialization of ExtractValue depending on the value traits of T. 00392 * ValueLike traits use operator>> to assign the value from strVal. 00393 */ 00394 template<typename T> void 00395 ExtractValue(T &destVal, const std::string& strVal, ValueLike vl) 00396 { 00397 static_cast<void>(vl); // Avoid warning about unused vl 00398 std::istringstream is(strVal); 00399 00400 int valuesRead = 0; 00401 while ( is.good() ) { 00402 if ( is.peek() != EOF ) 00403 #ifdef TCLAP_SETBASE_ZERO 00404 is >> std::setbase(0) >> destVal; 00405 #else 00406 is >> destVal; 00407 #endif 00408 else 00409 break; 00410 00411 valuesRead++; 00412 } 00413 00414 if ( is.fail() ) 00415 throw( ArgParseException("Couldn't read argument value " 00416 "from string '" + strVal + "'")); 00417 00418 00419 if ( valuesRead > 1 ) 00420 throw( ArgParseException("More than one valid value parsed from " 00421 "string '" + strVal + "'")); 00422 00423 } 00424 00425 /* 00426 * Extract a value of type T from it's string representation contained 00427 * in strVal. The ValueLike parameter used to select the correct 00428 * specialization of ExtractValue depending on the value traits of T. 00429 * StringLike uses assignment (operator=) to assign from strVal. 00430 */ 00431 template<typename T> void 00432 ExtractValue(T &destVal, const std::string& strVal, StringLike sl) 00433 { 00434 static_cast<void>(sl); // Avoid warning about unused sl 00435 SetString(destVal, strVal); 00436 } 00437 00439 //BEGIN Arg.cpp 00441 00442 inline Arg::Arg(const std::string& flag, 00443 const std::string& name, 00444 const std::string& desc, 00445 bool req, 00446 bool valreq, 00447 Visitor* v) : 00448 _flag(flag), 00449 _name(name), 00450 _description(desc), 00451 _required(req), 00452 _requireLabel("required"), 00453 _valueRequired(valreq), 00454 _alreadySet(false), 00455 _visitor( v ), 00456 _ignoreable(true), 00457 _xorSet(false), 00458 _acceptsMultipleValues(false) 00459 { 00460 if ( _flag.length() > 1 ) 00461 throw(SpecificationException( 00462 "Argument flag can only be one character long", toString() ) ); 00463 00464 if ( _name != ignoreNameString() && 00465 ( _flag == Arg::flagStartString() || 00466 _flag == Arg::nameStartString() || 00467 _flag == " " ) ) 00468 throw(SpecificationException("Argument flag cannot be either '" + 00469 Arg::flagStartString() + "' or '" + 00470 Arg::nameStartString() + "' or a space.", 00471 toString() ) ); 00472 00473 if ( ( _name.substr( 0, Arg::flagStartString().length() ) == Arg::flagStartString() ) || 00474 ( _name.substr( 0, Arg::nameStartString().length() ) == Arg::nameStartString() ) || 00475 ( _name.find( " ", 0 ) != std::string::npos ) ) 00476 throw(SpecificationException("Argument name begin with either '" + 00477 Arg::flagStartString() + "' or '" + 00478 Arg::nameStartString() + "' or space.", 00479 toString() ) ); 00480 00481 } 00482 00483 inline Arg::~Arg() { } 00484 00485 inline std::string Arg::shortID( const std::string& valueId ) const 00486 { 00487 std::string id = ""; 00488 00489 if ( _flag != "" ) 00490 id = Arg::flagStartString() + _flag; 00491 else 00492 id = Arg::nameStartString() + _name; 00493 00494 if ( _valueRequired ) 00495 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">"; 00496 00497 if ( !_required ) 00498 id = "[" + id + "]"; 00499 00500 return id; 00501 } 00502 00503 inline std::string Arg::longID( const std::string& valueId ) const 00504 { 00505 std::string id = ""; 00506 00507 if ( _flag != "" ) 00508 { 00509 id += Arg::flagStartString() + _flag; 00510 00511 if ( _valueRequired ) 00512 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">"; 00513 00514 id += ", "; 00515 } 00516 00517 id += Arg::nameStartString() + _name; 00518 00519 if ( _valueRequired ) 00520 id += std::string( 1, Arg::delimiter() ) + "<" + valueId + ">"; 00521 00522 return id; 00523 00524 } 00525 00526 inline bool Arg::operator==(const Arg& a) const 00527 { 00528 if ( ( _flag != "" && _flag == a._flag ) || _name == a._name) 00529 return true; 00530 else 00531 return false; 00532 } 00533 00534 inline std::string Arg::getDescription() const 00535 { 00536 std::string desc = ""; 00537 if ( _required ) 00538 desc = "(" + _requireLabel + ") "; 00539 00540 // if ( _valueRequired ) 00541 // desc += "(value required) "; 00542 00543 desc += _description; 00544 return desc; 00545 } 00546 00547 inline const std::string& Arg::getFlag() const { return _flag; } 00548 00549 inline const std::string& Arg::getName() const { return _name; } 00550 00551 inline bool Arg::isRequired() const { return _required; } 00552 00553 inline bool Arg::isValueRequired() const { return _valueRequired; } 00554 00555 inline bool Arg::isSet() const 00556 { 00557 if ( _alreadySet && !_xorSet ) 00558 return true; 00559 else 00560 return false; 00561 } 00562 00563 inline bool Arg::isIgnoreable() const { return _ignoreable; } 00564 00565 inline void Arg::setRequireLabel( const std::string& s) 00566 { 00567 _requireLabel = s; 00568 } 00569 00570 inline bool Arg::argMatches( const std::string& argFlag ) const 00571 { 00572 if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) || 00573 argFlag == Arg::nameStartString() + _name ) 00574 return true; 00575 else 00576 return false; 00577 } 00578 00579 inline std::string Arg::toString() const 00580 { 00581 std::string s = ""; 00582 00583 if ( _flag != "" ) 00584 s += Arg::flagStartString() + _flag + " "; 00585 00586 s += "(" + Arg::nameStartString() + _name + ")"; 00587 00588 return s; 00589 } 00590 00591 inline void Arg::_checkWithVisitor() const 00592 { 00593 if ( _visitor != NULL ) 00594 _visitor->visit(); 00595 } 00596 00600 inline void Arg::trimFlag(std::string& flag, std::string& value) const 00601 { 00602 int stop = 0; 00603 for ( int i = 0; static_cast<unsigned int>(i) < flag.length(); i++ ) 00604 if ( flag[i] == Arg::delimiter() ) 00605 { 00606 stop = i; 00607 break; 00608 } 00609 00610 if ( stop > 1 ) 00611 { 00612 value = flag.substr(stop+1); 00613 flag = flag.substr(0,stop); 00614 } 00615 00616 } 00617 00621 inline bool Arg::_hasBlanks( const std::string& s ) const 00622 { 00623 for ( int i = 1; static_cast<unsigned int>(i) < s.length(); i++ ) 00624 if ( s[i] == Arg::blankChar() ) 00625 return true; 00626 00627 return false; 00628 } 00629 00630 inline void Arg::forceRequired() 00631 { 00632 _required = true; 00633 } 00634 00635 inline void Arg::xorSet() 00636 { 00637 _alreadySet = true; 00638 _xorSet = true; 00639 } 00640 00644 inline void Arg::addToList( std::list<Arg*>& argList ) const 00645 { 00646 argList.push_front( const_cast<Arg*>(this) ); 00647 } 00648 00649 inline bool Arg::allowMore() 00650 { 00651 return false; 00652 } 00653 00654 inline bool Arg::acceptsMultipleValues() 00655 { 00656 return _acceptsMultipleValues; 00657 } 00658 00659 inline void Arg::reset() 00660 { 00661 _xorSet = false; 00662 _alreadySet = false; 00663 } 00664 00666 //END Arg.cpp 00668 00669 } //namespace TCLAP 00670 00671 #endif 00672