![]() |
VR-Forces 4.0.4 Class Documentation
|
00001 /****************************************************************************** 00002 * 00003 * file: DtVrvCommandLineParser.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 *****************************************************************************/ 00021 00022 #pragma once 00023 00027 00028 #include <cmdLine/cmdLineInterface.h> 00029 00030 #include <vrvUtil/DtVrvCmdSwitchArg.h> 00031 #include <cmdLine/cmdUnlabeledValueArg.h> 00032 #include <cmdLine/cmdUnlabeledMultiArg.h> 00033 00034 #include <cmdLine/cmdXorHandler.h> 00035 #include <cmdLine/cmdHelpVisitor.h> 00036 #include <cmdLine/cmdVersionVisitor.h> 00037 #include <cmdLine/cmdIgnoreRestVisitor.h> 00038 00039 #include <cmdLine/cmdLineOutput.h> 00040 #include <cmdLine/cmdStdOutput.h> 00041 00042 #include <string> 00043 #include <vector> 00044 #include <list> 00045 #include <iostream> 00046 #include <iomanip> 00047 #include <algorithm> 00048 00049 #include <vlutil/vlProcessControl.h> 00050 #include <vlutil/vlKeyboard.h> 00051 #include <vlutil/vlPrint.h> 00052 00053 namespace makVrv { 00059 00060 00061 00062 class CmdLine : public DtCmdLine::CmdLineInterface 00063 { 00064 protected: 00065 00070 std::list<DtCmdLine::Arg*> _argList; 00071 00075 std::string _progName; 00076 00080 std::string _message; 00081 00085 std::string _version; 00086 00092 int _numRequired; 00093 00098 char _delimiter; 00099 00103 DtCmdLine::XorHandler _xorHandler; 00104 00110 std::list<DtCmdLine::Arg*> _argDeleteOnExitList; 00111 00117 std::list<DtCmdLine::Visitor*> _visitorDeleteOnExitList; 00118 00122 DtCmdLine::CmdLineOutput* _output; 00123 00130 bool _emptyCombined(const std::string& s); 00131 00132 bool myPressAnyKey; 00133 00134 private: 00135 00140 void _constructor(); 00141 00145 void deleteOnExit(DtCmdLine::Arg* ptr); 00146 00150 void deleteOnExit(DtCmdLine::Visitor* ptr); 00151 00156 bool _userSetOutput; 00157 00158 public: 00159 00170 CmdLine(const std::string& name, 00171 const std::string& message, 00172 const std::string& version = "none", 00173 #ifdef _WIN32 00174 bool pressAnyKey = true); 00175 #else 00176 bool pressAnyKey = false); 00177 #endif 00178 00189 CmdLine(const std::string& message, 00190 const char delimiter = ' ', 00191 const std::string& version = "none", 00192 #ifdef _WIN32 00193 bool pressAnyKey = true); 00194 #else 00195 bool pressAnyKey = false); 00196 #endif 00197 00201 virtual ~CmdLine(); 00202 00207 void add( DtCmdLine::Arg& a ); 00208 00213 void add( DtCmdLine::Arg* a ); 00214 00221 void xorAdd( DtCmdLine::Arg& a, DtCmdLine::Arg& b ); 00222 00228 void xorAdd( std::vector<DtCmdLine::Arg*>& xors ); 00229 00235 void parse(int argc, char** argv); 00236 00240 DtCmdLine::CmdLineOutput* getOutput(); 00241 00245 void setOutput(DtCmdLine::CmdLineOutput* co); 00246 00250 std::string& getVersion(); 00251 00255 std::string& getProgramName(); 00256 00260 std::list<DtCmdLine::Arg*>& getArgList(); 00261 00265 DtCmdLine::XorHandler& getXorHandler(); 00266 00270 char getDelimiter(); 00271 00275 std::string& getMessage(); 00276 }; 00277 00278 00280 //Begin CmdLine.cpp 00282 00283 inline CmdLine::CmdLine(const std::string& n, 00284 const std::string& m, 00285 const std::string& v, 00286 bool pressAnyKey) 00287 : _progName(n), 00288 _message(m), 00289 _version(v), 00290 _numRequired(0), 00291 _delimiter(' '), 00292 myPressAnyKey(pressAnyKey), 00293 _userSetOutput(false) 00294 { 00295 _constructor(); 00296 } 00297 00298 inline CmdLine::CmdLine(const std::string& m, 00299 char delim, 00300 const std::string& v, 00301 bool pressAnyKey) 00302 : _progName("not_set_yet"), 00303 _message(m), 00304 _version(v), 00305 _numRequired(0), 00306 _delimiter(delim), 00307 myPressAnyKey(pressAnyKey), 00308 _userSetOutput(false) 00309 { 00310 _constructor(); 00311 } 00312 00313 inline CmdLine::~CmdLine() 00314 { 00315 DtCmdLine::ArgListIterator argIter; 00316 DtCmdLine::VisitorListIterator visIter; 00317 00318 for( argIter = _argDeleteOnExitList.begin(); 00319 argIter != _argDeleteOnExitList.end(); 00320 ++argIter) 00321 delete *argIter; 00322 00323 for( visIter = _visitorDeleteOnExitList.begin(); 00324 visIter != _visitorDeleteOnExitList.end(); 00325 ++visIter) 00326 delete *visIter; 00327 00328 if ( !_userSetOutput ) 00329 delete _output; 00330 } 00331 00332 inline void CmdLine::_constructor() 00333 { 00334 _output = new DtCmdLine::StdOutput; 00335 00336 DtCmdLine::Visitor *v; 00337 00338 DtCmdLine::Arg::setDelimiter( _delimiter ); 00339 00340 v = new DtCmdLine::HelpVisitor( this, &_output, myPressAnyKey ); 00341 makVrv::SwitchArg* help = new makVrv::SwitchArg("h","help", 00342 "Displays usage information and exits.", 00343 false, v); 00344 add( help ); 00345 deleteOnExit(help); 00346 deleteOnExit(v); 00347 00348 v = new DtCmdLine::VersionVisitor( this, &_output, myPressAnyKey ); 00349 makVrv::SwitchArg* vers = new makVrv::SwitchArg("v","version", 00350 "Displays version information and exits.", 00351 false, v); 00352 add( vers ); 00353 deleteOnExit(vers); 00354 deleteOnExit(v); 00355 00356 v = new DtCmdLine::IgnoreRestVisitor(); 00357 makVrv::SwitchArg* ignore = new makVrv::SwitchArg(DtCmdLine::Arg::flagStartString(), 00358 DtCmdLine::Arg::ignoreNameString(), 00359 "Ignores the rest of the labeled arguments following this flag.", 00360 false, v); 00361 add( ignore ); 00362 deleteOnExit(ignore); 00363 deleteOnExit(v); 00364 } 00365 00366 inline void CmdLine::xorAdd( std::vector<DtCmdLine::Arg*>& ors ) 00367 { 00368 _xorHandler.add( ors ); 00369 00370 for (DtCmdLine::ArgVectorIterator it = ors.begin(); it != ors.end(); it++) 00371 { 00372 (*it)->forceRequired(); 00373 (*it)->setRequireLabel( "OR required" ); 00374 00375 add( *it ); 00376 } 00377 } 00378 00379 inline void CmdLine::xorAdd( DtCmdLine::Arg& a, DtCmdLine::Arg& b ) 00380 { 00381 std::vector<DtCmdLine::Arg*> ors; 00382 ors.push_back( &a ); 00383 ors.push_back( &b ); 00384 xorAdd( ors ); 00385 } 00386 00387 inline void CmdLine::add( DtCmdLine::Arg& a ) 00388 { 00389 add( &a ); 00390 } 00391 00392 inline void CmdLine::add( DtCmdLine::Arg* a ) 00393 { 00394 for( DtCmdLine::ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) 00395 if ( *a == *(*it) ) 00396 throw( DtCmdLine::SpecificationException( "Argument with same flag/name already exists!", 00397 a->longID() ) ); 00398 00399 a->addToList( _argList ); 00400 00401 if ( a->isRequired() ) 00402 _numRequired++; 00403 } 00404 00405 inline void CmdLine::parse(int argc, char** argv) 00406 { 00407 try { 00408 00409 _progName = argv[0]; 00410 00412 std::vector<std::string> args; 00413 int i; 00414 for (i = 1; i < argc; i++) 00415 args.push_back(argv[i]); 00416 00417 int requiredCount = 0; 00418 00419 for (i = 0; (unsigned int)i < args.size(); i++) 00420 { 00421 bool matched = false; 00422 for (DtCmdLine::ArgListIterator it = _argList.begin(); it != _argList.end(); it++) 00423 { 00424 if ( (*it)->processArg( &i, args ) ) 00425 { 00426 requiredCount += _xorHandler.check( *it ); 00427 matched = true; 00428 break; 00429 } 00430 } 00431 00434 if ( !matched && _emptyCombined( args[i] ) ) 00435 matched = true; 00436 00437 if ( !matched && !DtCmdLine::Arg::ignoreRest() ) 00438 throw(DtCmdLine::CmdLineParseException("Couldn't find match for argument", 00439 args[i])); 00440 } 00441 00442 if ( requiredCount < _numRequired ) 00443 throw(DtCmdLine::CmdLineParseException("One or more required arguments missing!")); 00444 00445 if ( requiredCount > _numRequired ) 00446 throw(DtCmdLine::CmdLineParseException("Too many arguments!")); 00447 00448 } catch ( DtCmdLine::ArgException e ) { 00449 _output->failure(*this,e); 00450 00451 int oldNotifyLevel = DtNotifyLevel; 00452 DtNotifyLevel = 3; 00453 00454 if (myPressAnyKey) 00455 { 00456 DtInfo << "Press any key to continue" << std::endl; 00457 00458 while (DtPollBlockingInputChar() == '\0') 00459 { 00460 DtSleep(0.1); 00461 } 00462 } 00463 00464 DtNotifyLevel = oldNotifyLevel; 00465 00466 exit(1); 00467 } 00468 } 00469 00470 inline bool CmdLine::_emptyCombined(const std::string& s) 00471 { 00472 if ( s[0] != DtCmdLine::Arg::flagStartChar() ) 00473 return false; 00474 00475 for ( int i = 1; (unsigned int)i < s.length(); i++ ) 00476 if ( s[i] != DtCmdLine::Arg::blankChar() ) 00477 return false; 00478 00479 return true; 00480 } 00481 00482 inline void CmdLine::deleteOnExit(DtCmdLine::Arg* ptr) 00483 { 00484 _argDeleteOnExitList.push_back(ptr); 00485 } 00486 00487 inline void CmdLine::deleteOnExit(DtCmdLine::Visitor* ptr) 00488 { 00489 _visitorDeleteOnExitList.push_back(ptr); 00490 } 00491 00492 inline DtCmdLine::CmdLineOutput* CmdLine::getOutput() 00493 { 00494 return _output; 00495 } 00496 00497 inline void CmdLine::setOutput(DtCmdLine::CmdLineOutput* co) 00498 { 00499 _userSetOutput = true; 00500 _output = co; 00501 } 00502 00503 inline std::string& CmdLine::getVersion() 00504 { 00505 return _version; 00506 } 00507 00508 inline std::string& CmdLine::getProgramName() 00509 { 00510 return _progName; 00511 } 00512 00513 inline std::list<DtCmdLine::Arg*>& CmdLine::getArgList() 00514 { 00515 return _argList; 00516 } 00517 00518 inline DtCmdLine::XorHandler& CmdLine::getXorHandler() 00519 { 00520 return _xorHandler; 00521 } 00522 00523 inline char CmdLine::getDelimiter() 00524 { 00525 return _delimiter; 00526 } 00527 00528 inline std::string& CmdLine::getMessage() 00529 { 00530 return _message; 00531 } 00532 00534 //End CmdLine.cpp 00536 }