![]() |
VR-Link API Documentation for DIS
|
00001 /****************************************************************************** 00002 * 00003 * file: Arg.h 00004 * 00005 * Copyright (c) 2003, Michael E. Smoot . 00006 * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno . 00007 * All rights reverved. 00008 * 00009 * See the file COPYING in the top directory of this distribution for 00010 * more information. 00011 * 00012 * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 00013 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00014 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00015 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00016 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00017 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00018 * DEALINGS IN THE SOFTWARE. 00019 * 00020 *****************************************************************************/ 00024 00025 #ifndef DtCmdLine_ARGUMENT_H 00026 #define DtCmdLine_ARGUMENT_H 00027 00028 #include <string> 00029 #include <vector> 00030 #include <list> 00031 #include <iostream> 00032 00033 #include "cmdArgException.h" 00034 #include "cmdVisitor.h" 00035 #include "cmdLineInterface.h" 00036 00037 #ifdef DtUSE_UTILITIES_NAMESPACE 00038 namespace DtUSE_UTILITIES_NAMESPACE 00039 { 00040 #endif 00041 00042 namespace DtCmdLine { 00043 00048 class Arg 00049 { 00050 private: 00051 00055 static bool& ignoreRestRef() { static bool ign = false; return ign; } 00056 00061 static char& delimiterRef() { static char delim = ' '; return delim; } 00062 00063 protected: 00064 00073 std::string _flag; 00074 00082 std::string _name; 00083 00087 std::string _description; 00088 00092 bool _required; 00093 00098 std::string _requireLabel; 00099 00105 bool _valueRequired; 00106 00112 bool _alreadySet; 00113 00120 Visitor* _visitor; 00121 00125 bool _ignoreable; 00126 00131 bool _xorSet; 00132 00136 void _checkWithVisitor() const; 00137 00151 Arg( const std::string& flag, 00152 const std::string& name, 00153 const std::string& desc, 00154 bool req, 00155 bool valreq, 00156 Visitor* v = NULL ); 00157 00158 public: 00162 virtual ~Arg(); 00163 00168 virtual void addToList( std::list<Arg*>& argList ) const; 00169 00173 static void beginIgnoring() { ignoreRestRef() = true; } 00174 00178 static bool ignoreRest() { return ignoreRestRef(); } 00179 00184 static char delimiter() { return delimiterRef(); } 00185 00191 static const char blankChar() { return '*'; } 00192 00196 static const char flagStartChar() { return '-'; } 00197 00202 static const std::string flagStartString() { return "-"; } 00203 00208 static const std::string nameStartString() { return "--"; } 00209 00213 static const std::string ignoreNameString() { return "ignore_rest"; } 00214 00219 static void setDelimiter( char c ) { delimiterRef() = c; } 00220 00228 virtual bool processArg(int *i, std::vector<std::string>& args) = 0; 00229 00235 virtual bool operator==(const Arg& a); 00236 00240 const std::string& getFlag() const; 00241 00245 const std::string& getName() const; 00246 00250 std::string getDescription() const; 00251 00255 virtual bool isRequired() const; 00256 00261 void forceRequired(); 00262 00267 void xorSet(); 00268 00272 bool isValueRequired() const; 00273 00278 bool isSet() const; 00279 00283 bool isIgnoreable() const; 00284 00293 virtual bool argMatches( const std::string& s ) const; 00294 00299 virtual std::string toString() const; 00300 00305 virtual std::string shortID( const std::string& valueId = "val" ) const; 00306 00311 virtual std::string longID( const std::string& valueId = "val" ) const; 00312 00320 virtual void trimFlag( std::string& flag, std::string& value ) const; 00321 00328 bool _hasBlanks( const std::string& s ) const; 00329 00335 void setRequireLabel( const std::string& s ); 00336 00337 }; 00338 00342 typedef std::list<Arg*>::iterator ArgListIterator; 00343 00347 typedef std::vector<Arg*>::iterator ArgVectorIterator; 00348 00352 typedef std::list<Visitor*>::iterator VisitorListIterator; 00353 00354 00356 //BEGIN Arg.cpp 00358 00359 inline Arg::Arg(const std::string& flag, 00360 const std::string& name, 00361 const std::string& desc, 00362 bool req, 00363 bool valreq, 00364 Visitor* v) : 00365 _flag(flag), 00366 _name(name), 00367 _description(desc), 00368 _required(req), 00369 _requireLabel("required"), 00370 _valueRequired(valreq), 00371 _alreadySet(false), 00372 _visitor( v ), 00373 _ignoreable(true), 00374 _xorSet(false) 00375 { 00376 if ( _flag.length() > 1 ) 00377 throw(SpecificationException( 00378 "Argument flag can only be one character long", toString() ) ); 00379 00380 if ( _name != ignoreNameString() && 00381 ( _flag == Arg::flagStartString() || 00382 _flag == Arg::nameStartString() || 00383 _flag == " " ) ) 00384 throw(SpecificationException("Argument flag cannot be either '" + 00385 Arg::flagStartString() + "' or '" + 00386 Arg::nameStartString() + "' or a space.", 00387 toString() ) ); 00388 00389 if ( ( _name.find( Arg::flagStartString(), 0 ) != std::string::npos ) || 00390 ( _name.find( Arg::nameStartString(), 0 ) != std::string::npos ) || 00391 ( _name.find( " ", 0 ) != std::string::npos ) ) 00392 throw(SpecificationException("Argument name cannot contain either '" + 00393 Arg::flagStartString() + "' or '" + 00394 Arg::nameStartString() + "' or space.", 00395 toString() ) ); 00396 00397 } 00398 00399 inline Arg::~Arg() { } 00400 00401 inline std::string Arg::shortID( const std::string& valueId ) const 00402 { 00403 std::string id = ""; 00404 00405 if ( _flag != "" ) 00406 id = Arg::flagStartString() + _flag; 00407 else 00408 id = Arg::nameStartString() + _name; 00409 00410 std::string delim = " "; 00411 delim[0] = Arg::delimiter(); 00412 00413 if ( _valueRequired ) 00414 id += delim + "<" + valueId + ">"; 00415 00416 if ( !_required ) 00417 id = "[" + id + "]"; 00418 00419 return id; 00420 } 00421 00422 inline std::string Arg::longID( const std::string& valueId ) const 00423 { 00424 std::string id = ""; 00425 00426 if ( _flag != "" ) 00427 { 00428 id += Arg::flagStartString() + _flag; 00429 00430 if ( _valueRequired ) 00431 id += " <" + valueId + ">"; 00432 00433 id += ", "; 00434 } 00435 00436 id += Arg::nameStartString() + _name; 00437 00438 if ( _valueRequired ) 00439 id += " <" + valueId + ">"; 00440 00441 return id; 00442 00443 } 00444 00445 inline bool Arg::operator==(const Arg& a) 00446 { 00447 if ( ( _flag != "" && _flag == a._flag ) || 00448 (_name == a._name)) 00449 { 00450 return true; 00451 } 00452 else 00453 { 00454 return false; 00455 } 00456 } 00457 00458 inline std::string Arg::getDescription() const 00459 { 00460 std::string desc = ""; 00461 if ( _required ) 00462 desc = "(" + _requireLabel + ") "; 00463 00464 //if ( _valueRequired ) 00466 00467 desc += _description; 00468 return desc; 00469 } 00470 00471 inline const std::string& Arg::getFlag() const { return _flag; } 00472 00473 inline const std::string& Arg::getName() const { return _name; } 00474 00475 inline bool Arg::isRequired() const { return _required; } 00476 00477 inline bool Arg::isValueRequired() const { return _valueRequired; } 00478 00479 inline bool Arg::isSet() const 00480 { 00481 if ( _alreadySet && !_xorSet ) 00482 return true; 00483 else 00484 return false; 00485 } 00486 00487 inline bool Arg::isIgnoreable() const { return _ignoreable; } 00488 00489 inline void Arg::setRequireLabel( const std::string& s) 00490 { 00491 _requireLabel = s; 00492 } 00493 00494 inline bool Arg::argMatches( const std::string& argFlag ) const 00495 { 00496 if ( ( argFlag == Arg::flagStartString() + _flag && _flag != "" ) || 00497 argFlag == Arg::nameStartString() + _name ) 00498 return true; 00499 else 00500 return false; 00501 } 00502 00503 inline std::string Arg::toString() const 00504 { 00505 std::string s = ""; 00506 00507 if ( _flag != "" ) 00508 s += Arg::flagStartString() + _flag + " "; 00509 00510 s += "(" + Arg::nameStartString() + _name + ")"; 00511 00512 return s; 00513 } 00514 00515 inline void Arg::_checkWithVisitor() const 00516 { 00517 if ( _visitor != NULL ) 00518 _visitor->visit(); 00519 } 00520 00524 inline void Arg::trimFlag(std::string& flag, std::string& value) const 00525 { 00526 int stop = 0; 00527 for ( int i = 0; (unsigned int)i < flag.length(); i++ ) 00528 if ( flag[i] == Arg::delimiter() ) 00529 { 00530 stop = i; 00531 break; 00532 } 00533 00534 if ( stop > 1 ) 00535 { 00536 value = flag.substr(stop+1); 00537 flag = flag.substr(0,stop); 00538 } 00539 00540 } 00541 00545 inline bool Arg::_hasBlanks( const std::string& s ) const 00546 { 00547 for ( int i = 1; (unsigned int)i < s.length(); i++ ) 00548 if ( s[i] == Arg::blankChar() ) 00549 return true; 00550 00551 return false; 00552 } 00553 00554 inline void Arg::forceRequired() 00555 { 00556 _required = true; 00557 } 00558 00559 inline void Arg::xorSet() 00560 { 00561 _alreadySet = true; 00562 _xorSet = true; 00563 } 00564 00568 inline void Arg::addToList( std::list<Arg*>& argList ) const 00569 { 00570 argList.push_front( (Arg*)this ); 00571 } 00572 00574 //END Arg.cpp 00576 00577 } //namespace DtCmdLine 00578 00579 #ifdef DtUSE_UTILITIES_NAMESPACE 00580 } 00581 #endif 00582 00583 #endif 00584