VR-Link API Documentation for HLA 1516
cmdLine.h
Go to the documentation of this file.
00001 /****************************************************************************** 
00002  * 
00003  *  file:  CmdLine.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 #ifndef DtCmdLine_CMDLINE_H
00023 #define DtCmdLine_CMDLINE_H
00024  
00028 
00029 #include "cmdSwitchArg.h"
00030 #include "cmdUnlabeledValueArg.h"
00031 #include "cmdUnlabeledMultiArg.h"
00032 
00033 #include "cmdXorHandler.h"
00034 #include "cmdHelpVisitor.h"
00035 #include "cmdVersionVisitor.h"
00036 #include "cmdIgnoreRestVisitor.h"
00037 
00038 #include "cmdLineOutput.h"
00039 #include "cmdStdOutput.h"
00040 
00041 #include <string>
00042 #include <vector>
00043 #include <list>
00044 #include <iostream>
00045 #include <iomanip>
00046 #include <algorithm>
00047 
00048 #include <vlutil/vlProcessControl.h>
00049 #include <vlutil/vlKeyboard.h>
00050 #include <vlutil/vlPrint.h>
00051 
00052 #ifdef DtUSE_UTILITIES_NAMESPACE
00053 namespace DtUSE_UTILITIES_NAMESPACE
00054 {
00055 #endif
00056 
00057 namespace DtCmdLine {
00058 
00063 
00064    class CmdLine : public CmdLineInterface
00065    {
00066    protected:
00067 
00072       std::list<Arg*> _argList;
00073 
00077       std::string _progName;
00078 
00082       std::string _message;
00083 
00087       std::string _version;
00088 
00094       int _numRequired;
00095 
00100       char _delimiter;
00101 
00105       XorHandler _xorHandler;
00106 
00112       std::list<Arg*> _argDeleteOnExitList;
00113 
00119       std::list<Visitor*> _visitorDeleteOnExitList;
00120 
00124       CmdLineOutput* _output;
00125 
00132       bool _emptyCombined(const std::string& s);
00133 
00134       bool myPressAnyKey;
00135 
00136    private:
00137 
00142       void _constructor();
00143 
00147       void deleteOnExit(Arg* ptr);
00148 
00152       void deleteOnExit(Visitor* ptr);
00153 
00158       bool _userSetOutput;
00159 
00160    public:
00161 
00172       CmdLine(const std::string& name, 
00173               const std::string& message,
00174               const std::string& version = "none",
00175 #ifdef _WIN32
00176               bool pressAnyKey = true);
00177 #else
00178               bool pressAnyKey = false);
00179 #endif
00180 
00191       CmdLine(const std::string& message, 
00192               const char delimiter = ' ',
00193               const std::string& version = "none",
00194 #ifdef _WIN32
00195               bool pressAnyKey = true);
00196 #else
00197               bool pressAnyKey = false);
00198 #endif
00199 
00203       virtual ~CmdLine();
00204 
00209       void add( Arg& a );
00210 
00215       void add( Arg* a );
00216 
00223       void xorAdd( Arg& a, Arg& b );
00224 
00230       void xorAdd( std::vector<Arg*>& xors );
00231 
00237       void parse(int argc, char** argv);
00238 
00242       CmdLineOutput* getOutput();
00243 
00247       void setOutput(CmdLineOutput* co);
00248 
00252       std::string& getVersion();
00253 
00257       std::string& getProgramName();
00258 
00262       std::list<Arg*>& getArgList();
00263 
00267       XorHandler& getXorHandler();
00268 
00272       char getDelimiter();
00273 
00277       std::string& getMessage();
00278    };
00279 
00280 
00282    //Begin CmdLine.cpp
00284 
00285    inline CmdLine::CmdLine(const std::string& n, 
00286                            const std::string& m, 
00287                            const std::string& v,
00288                            bool pressAnyKey)
00289       : _progName(n),
00290       _message(m),
00291       _version(v),
00292       _numRequired(0),
00293       _delimiter(' '),
00294       myPressAnyKey(pressAnyKey),
00295       _userSetOutput(false)
00296       { 
00297          _constructor();
00298       }
00299 
00300    inline CmdLine::CmdLine(const std::string& m, 
00301                            char delim, 
00302                            const std::string& v,
00303                            bool pressAnyKey)
00304       : _progName("not_set_yet"),
00305       _message(m),
00306       _version(v),
00307       _numRequired(0),
00308       _delimiter(delim),
00309       myPressAnyKey(pressAnyKey),
00310       _userSetOutput(false)
00311       {
00312          _constructor();
00313       }
00314 
00315    inline CmdLine::~CmdLine()
00316    {
00317       ArgListIterator argIter;
00318       VisitorListIterator visIter;
00319 
00320       for( argIter = _argDeleteOnExitList.begin(); 
00321            argIter != _argDeleteOnExitList.end(); 
00322            ++argIter)
00323          delete *argIter;
00324 
00325       for( visIter = _visitorDeleteOnExitList.begin(); 
00326            visIter != _visitorDeleteOnExitList.end(); 
00327            ++visIter) 
00328          delete *visIter;
00329 
00330       if ( !_userSetOutput )
00331          delete _output;
00332    }
00333 
00334    inline void CmdLine::_constructor()
00335    { 
00336       _output = new StdOutput;
00337 
00338       Visitor *v;
00339 
00340       Arg::setDelimiter( _delimiter );
00341 
00342       v = new HelpVisitor( this, &_output, myPressAnyKey );
00343       SwitchArg* help = new SwitchArg("h","help", 
00344                                       "Displays usage information and exits.", 
00345                                       false, v);
00346       add( help );
00347       deleteOnExit(help);
00348       deleteOnExit(v);
00349 
00350       v = new VersionVisitor( this, &_output, myPressAnyKey );
00351       SwitchArg* vers = new SwitchArg("v","version", 
00352                                       "Displays version information and exits.", 
00353                                       false, v);
00354       add( vers );
00355       deleteOnExit(vers);
00356       deleteOnExit(v);
00357 
00358       v = new IgnoreRestVisitor();
00359       SwitchArg* ignore  = new SwitchArg(Arg::flagStartString(), 
00360                                          Arg::ignoreNameString(),
00361                                          "Ignores the rest of the labeled arguments following this flag.",
00362                                          false, v);
00363       add( ignore );
00364       deleteOnExit(ignore);
00365       deleteOnExit(v);
00366    }
00367 
00368    inline void CmdLine::xorAdd( std::vector<Arg*>& ors )
00369    {
00370       _xorHandler.add( ors );
00371 
00372       for (ArgVectorIterator it = ors.begin(); it != ors.end(); it++)
00373       {
00374          (*it)->forceRequired();
00375          (*it)->setRequireLabel( "OR required" );
00376 
00377          add( *it );
00378       }
00379    }
00380 
00381    inline void CmdLine::xorAdd( Arg& a, Arg& b ) 
00382    {
00383       std::vector<Arg*> ors;
00384       ors.push_back( &a );
00385       ors.push_back( &b );
00386       xorAdd( ors );
00387    }
00388 
00389    inline void CmdLine::add( Arg& a ) 
00390    { 
00391       add( &a );
00392    }
00393 
00394    inline void CmdLine::add( Arg* a ) 
00395    { 
00396       for( ArgListIterator it = _argList.begin(); it != _argList.end(); it++ ) 
00397          if ( *a == *(*it) ) 
00398             throw( SpecificationException( "Argument with same flag/name already exists!", 
00399                    a->longID() ) );
00400 
00401       a->addToList( _argList );
00402 
00403       if ( a->isRequired() ) 
00404          _numRequired++;   
00405    }
00406 
00407    inline void CmdLine::parse(int argc, char** argv)
00408    {
00409       try {
00410 
00411          _progName = argv[0]; 
00412 
00414          std::vector<std::string> args;
00415          int i;
00416          for (i = 1; i < argc; i++)
00417             args.push_back(argv[i]);
00418 
00419          int requiredCount = 0;
00420 
00421          for (i = 0; (unsigned int)i < args.size(); i++)
00422          {
00423             bool matched = false;
00424             for (ArgListIterator it = _argList.begin(); it != _argList.end(); it++)
00425             {
00426                if ( (*it)->processArg( &i, args ) )
00427                {
00428                   requiredCount += _xorHandler.check( *it );
00429                   matched = true;
00430                   break;
00431                }
00432             }
00433 
00436             if ( !matched && _emptyCombined( args[i] ) )
00437                matched = true;
00438 
00439             if ( !matched && !Arg::ignoreRest() )
00440                throw(CmdLineParseException("Couldn't find match for argument",
00441                                            args[i]));
00442          }
00443 
00444          if ( requiredCount < _numRequired )
00445             throw(CmdLineParseException("One or more required arguments missing!"));
00446 
00447          if ( requiredCount > _numRequired )
00448             throw(CmdLineParseException("Too many arguments!"));
00449 
00450       } catch ( ArgException e ) { 
00451            _output->failure(*this,e); 
00452 
00453            int oldNotifyLevel = DtNotifyLevel;
00454            DtNotifyLevel = 3;
00455 
00456            if (myPressAnyKey)
00457            {
00458               DtInfo << "Press any key to continue" << std::endl;
00459 
00460               while (DtPollBlockingInputChar() == '\0')
00461               {
00462                  DtSleep(0.1);
00463               }
00464            }
00465            
00466            DtNotifyLevel = oldNotifyLevel;
00467            
00468            exit(1); 
00469         }
00470    }
00471 
00472    inline bool CmdLine::_emptyCombined(const std::string& s)
00473    {
00474       if ( s[0] != Arg::flagStartChar() )
00475          return false;
00476 
00477       for ( int i = 1; (unsigned int)i < s.length(); i++ )
00478          if ( s[i] != Arg::blankChar() )
00479             return false;
00480 
00481       return true;
00482    }
00483 
00484    inline void CmdLine::deleteOnExit(Arg* ptr)
00485    {
00486       _argDeleteOnExitList.push_back(ptr);
00487    }
00488 
00489    inline void CmdLine::deleteOnExit(Visitor* ptr)
00490    {
00491       _visitorDeleteOnExitList.push_back(ptr);
00492    }
00493 
00494    inline CmdLineOutput* CmdLine::getOutput()
00495    {
00496       return _output;
00497    }
00498 
00499    inline void CmdLine::setOutput(CmdLineOutput* co)
00500    {
00501       _userSetOutput = true;
00502       _output = co;
00503    }
00504 
00505    inline std::string& CmdLine::getVersion()
00506    {
00507       return _version;
00508    }
00509 
00510    inline std::string& CmdLine::getProgramName()
00511    {
00512       return _progName;
00513    }
00514 
00515    inline std::list<Arg*>& CmdLine::getArgList()
00516    {
00517       return _argList;
00518    }
00519 
00520    inline XorHandler& CmdLine::getXorHandler()
00521    {
00522       return _xorHandler;
00523    }
00524 
00525    inline char CmdLine::getDelimiter()
00526    {
00527       return _delimiter;
00528    }
00529 
00530    inline std::string& CmdLine::getMessage()
00531    {
00532       return _message;
00533    }
00534 
00536    //End CmdLine.cpp
00538 
00539 
00540 
00541 } //namespace DtCmdLine
00542 
00543 #ifdef DtUSE_UTILITIES_NAMESPACE
00544 }     
00545 #endif
00546 
00547 #endif 

Document ID: Generated on Mon May 14 08:06:18 EDT 2012 from SVN revision 114750
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)