VR-Forces 4.0.4 Class Documentation
include/vrvUtil/DtVrvCommandLineParser.h
Go to the documentation of this file.
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 }

Document ID: Generated on Fri Jun 29 16:33:32 EDT 2012 from SVN revision 116588
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)