VR-Link API Documentation for HLA Evolved
cmdMultiArg.h
Go to the documentation of this file.
00001 /****************************************************************************** 
00002  * 
00003  *  file:  MultiArg.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 
00023 #ifndef DtCmdLine_MULTIPLE_ARGUMENT_H
00024 #define DtCmdLine_MULTIPLE_ARGUMENT_H
00025 
00029 
00030 #include <cstdio>
00031 
00032 #include <string>
00033 #include <vector>
00034 
00035 #include "cmdArg.h"
00036 
00037 #ifdef HAVE_CONFIG_H
00038 #include <config.h>
00039 #else
00040 #define HAVE_SSTREAM
00041  
00042 #endif
00043 
00044 #if defined(HAVE_SSTREAM)
00045 #include <sstream>
00046 #elif defined(HAVE_STRSTREAM)
00047 #include <strstream>
00048 #else
00049 #error "Need a stringstream (sstream or strstream) to compile!"
00050 #endif
00051 
00052 #ifdef DtUSE_UTILITIES_NAMESPACE
00053 namespace DtUSE_UTILITIES_NAMESPACE
00054 {
00055 #endif
00056 
00057 namespace DtCmdLine {
00058 
00059    template<class T> class MultiArg;
00060 
00061    namespace MULTI_ARG_HELPER {
00062 
00063       enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY };
00064 
00074 
00075       template<class T>
00076          class ValueExtractor 
00077          {
00078             friend class MultiArg<T>;
00079 
00080          private:
00081 
00086             std::vector<T> &_values;
00087 
00092             ValueExtractor(std::vector<T> &values) : _values(values) {}
00093 
00099             int extractValue( const std::string& val ) 
00100             {
00101                T temp;
00102 
00103 #if defined(HAVE_SSTREAM)
00104                std::istringstream is(val);
00105 #elif defined(HAVE_STRSTREAM)
00106                std::istrstream is(val.c_str());
00107 #else
00108 #error "Need a stringstream (sstream or strstream) to compile!"
00109 #endif
00110 
00111                int valuesRead = 0;
00112 
00113                while ( is.good() ) 
00114                {
00115                   if ( is.peek() != EOF )
00116                      is >> temp; 
00117                   else
00118                      break;
00119 
00120                   valuesRead++;
00121                }     
00122 
00123                if ( is.fail() )
00124                   return EXTRACT_FAILURE;
00125 
00126                if ( valuesRead > 1 )
00127                   return EXTRACT_TOO_MANY;
00128 
00129                _values.push_back(temp);
00130 
00131                return 0;
00132             } 
00133          };
00134 
00140       template<>
00141          class ValueExtractor<std::string> 
00142          {
00143             friend class MultiArg<std::string>;
00144 
00145          private:
00146 
00151             std::vector<std::string> &_values;
00152 
00157             ValueExtractor(std::vector<std::string> &values) : _values(values) {}
00158 
00164             int extractValue( const std::string& val ) 
00165             {
00166                _values.push_back( val );
00167                return 0;
00168             }
00169          };
00170 
00171    } //namespace MULTI_ARG_HELPER
00172 
00178 
00179    template<class T>
00180       class MultiArg : public Arg
00181       {
00182       protected:
00183 
00187          std::vector<T> _values;
00188 
00195          std::vector<T> _allowed;
00196 
00200          std::string _typeDesc;
00201 
00208          void _extractValue( const std::string& val );
00209 
00214          void _checkAllowed( const std::string& val );
00215 
00216       public:
00217 
00235          MultiArg( const std::string& flag,
00236                    const std::string& name,
00237                    const std::string& desc,
00238                    bool req,
00239                    const std::string& typeDesc,
00240                    Visitor* v = NULL);
00241 
00260          MultiArg( const std::string& flag, 
00261                    const std::string& name,
00262                    const std::string& desc,
00263                    bool req,
00264                    const std::string& typeDesc,
00265                    CmdLineInterface& parser,
00266                    Visitor* v = NULL );
00267 
00283          MultiArg( const std::string& flag,
00284                    const std::string& name,
00285                    const std::string& desc,
00286                    bool req,
00287                    const std::vector<T>& allowed,
00288                    Visitor* v = NULL );
00289 
00306          MultiArg( const std::string& flag, 
00307                    const std::string& name,
00308                    const std::string& desc,
00309                    bool req,
00310                    const std::vector<T>& allowed,
00311                    CmdLineInterface& parser,
00312                    Visitor* v = NULL );
00313 
00322          virtual bool processArg(int* i, std::vector<std::string>& args); 
00323 
00328          const std::vector<T>& getValue() const;
00329 
00334          virtual std::string shortID(const std::string& val="val") const;
00335 
00340          virtual std::string longID(const std::string& val="val") const;
00341 
00346          virtual bool isRequired() const;
00347 
00348       private:
00349 
00353          void allowedInit();
00354       };
00355 
00359    template<class T>
00360       void MultiArg<T>::allowedInit()
00361       {
00362          for ( unsigned int i = 0; i < _allowed.size(); i++ )
00363          {
00364 
00365 #if defined(HAVE_SSTREAM)
00366             std::ostringstream os;
00367 #elif defined(HAVE_STRSTREAM)
00368             std::ostrstream os;
00369 #else
00370 #error "Need a stringstream (sstream or strstream) to compile!"
00371 #endif
00372 
00373             os << _allowed[i];
00374 
00375             std::string temp( os.str() );
00376 
00377             if ( i > 0 )
00378                _typeDesc += "|";
00379 
00380             _typeDesc += temp;
00381          }
00382       }
00383 
00387    template<class T>
00388       MultiArg<T>::MultiArg(const std::string& flag, 
00389                             const std::string& name,
00390                             const std::string& desc,
00391                             bool req,
00392                             const std::string& typeDesc,
00393                             Visitor* v)
00394       : Arg( flag, name, desc, req, true, v ),
00395       _typeDesc( typeDesc )
00396       { }
00397 
00398    template<class T>
00399       MultiArg<T>::MultiArg(const std::string& flag, 
00400                             const std::string& name,
00401                             const std::string& desc,
00402                             bool req,
00403                             const std::string& typeDesc,
00404                             CmdLineInterface& parser,
00405                             Visitor* v)
00406       : Arg( flag, name, desc, req, true, v ),
00407       _typeDesc( typeDesc )
00408       { 
00409          parser.add( this );
00410       }
00411 
00415    template<class T>
00416       MultiArg<T>::MultiArg(const std::string& flag, 
00417                             const std::string& name,
00418                             const std::string& desc,
00419                             bool req,
00420                             const std::vector<T>& allowed,
00421                             Visitor* v)
00422       : Arg( flag, name, desc, req, true, v ),
00423       _allowed( allowed )
00424       { 
00425          allowedInit();
00426       }
00427 
00428    template<class T>
00429       MultiArg<T>::MultiArg(const std::string& flag, 
00430                             const std::string& name,
00431                             const std::string& desc,
00432                             bool req,
00433                             const std::vector<T>& allowed,
00434                             CmdLineInterface& parser,
00435                             Visitor* v)
00436       : Arg( flag, name, desc, req, true, v ),
00437       _allowed( allowed )
00438       { 
00439          allowedInit();
00440          parser.add( this );
00441       }
00442 
00446    template<class T>
00447       const std::vector<T>& MultiArg<T>::getValue() const { return _values; }
00448 
00452    template<class T>
00453       bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args) 
00454       {
00455          if ( _ignoreable && Arg::ignoreRest() )
00456             return false;
00457 
00458          if ( _hasBlanks( args[*i] ) )
00459             return false;
00460 
00461          std::string flag = args[*i];
00462          std::string value = "";
00463 
00464          trimFlag( flag, value );
00465 
00466          if ( argMatches( flag ) )
00467          {
00468             if ( Arg::delimiter() != ' ' && value == "" )
00469                throw( ArgParseException( 
00470                                         "Couldn't find delimiter for this argument!",
00471                                         toString() ) );
00472 
00473             if ( value == "" )
00474             {
00475                (*i)++;
00476                if ( (unsigned int)*i < args.size() )
00477                   _extractValue( args[*i] );
00478                else
00479                   throw( ArgParseException("Missing a value for this argument!",
00480                                            toString() ) );
00481             }
00482             else
00483                _extractValue( value );
00484 
00485             _checkWithVisitor();
00486 
00487             return true;
00488          }
00489          else
00490             return false;
00491       }
00492 
00496    template<class T>
00497       void MultiArg<T>::_checkAllowed( const std::string& val )
00498       {
00499          if ( _allowed.size() > 0 )
00500             if ( std::find(_allowed.begin(),_allowed.end(),_values.back()) 
00501                  == _allowed.end() )
00502                throw( CmdLineParseException( "Couldn't find '" + val +
00503                                              "' in allowed list.", toString() ) );
00504       }
00505 
00509    template<class T>
00510       std::string MultiArg<T>::shortID(const std::string& val) const
00511       {
00512          std::string id = Arg::shortID(_typeDesc) + " ... ";
00513 
00514          return id;
00515       }
00516 
00520    template<class T>
00521       std::string MultiArg<T>::longID(const std::string& val) const
00522       {
00523          std::string id = Arg::longID(_typeDesc) + "  (accepted multiple times)";
00524 
00525          return id;
00526       }
00527 
00532    template<class T>
00533       bool MultiArg<T>::isRequired() const
00534       {
00535          if ( _required )
00536          {
00537             if ( _values.size() > 1 )
00538                return false;
00539             else
00540                return true;
00541          }
00542          else
00543             return false;
00544 
00545       }
00546 
00547    template<class T>
00548       void MultiArg<T>::_extractValue( const std::string& val ) 
00549       {
00550          MULTI_ARG_HELPER::ValueExtractor<T> ve(_values);
00551 
00552          int err = ve.extractValue(val);
00553 
00554          if ( err == MULTI_ARG_HELPER::EXTRACT_FAILURE )
00555             throw( ArgParseException("Couldn't read argument value "
00556                                      "from string '" + val + "'", toString() ) );
00557 
00558          if(err == MULTI_ARG_HELPER::EXTRACT_TOO_MANY)
00559             throw( ArgParseException("More than one valid value "
00560                                      "parsed from string '" + val + "'", 
00561                                      toString() ) );         
00562          _checkAllowed( val );
00563       }
00564 
00565 
00566 } 
00567 
00568 #ifdef DtUSE_UTILITIES_NAMESPACE
00569 }     
00570 #endif
00571 
00572 #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)