Ignore:
Timestamp:
24/08/10 11:23:06 (21 months ago)
Author:
Freddie Akeroyd
Message:

Update to tclap 1.2.0 from http://tclap.sourceforge.net/
Refs #244

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/third_party/tclap/MultiArg.h

    r1506 r1515  
    2828 
    2929#include <tclap/Arg.h> 
    30  
    31 #ifdef _____HAVE_CONFIG_H /* not needed */ 
    32 #include <config.h> 
    33 #else 
    34 #define HAVE_SSTREAM 
    35 #endif 
    36  
    37 #if defined(HAVE_SSTREAM) 
    38 #include <sstream> 
    39 #elif defined(HAVE_STRSTREAM) 
    40 #include <strstream> 
    41 #else 
    42 #error "Need a stringstream (sstream or strstream) to compile!" 
    43 #endif 
     30#include <tclap/Constraint.h> 
    4431 
    4532namespace TCLAP { 
    46  
    47 template<class T> class MultiArg; 
    48  
    49 namespace MULTI_ARG_HELPER { 
    50  
    51 enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY }; 
    52  
    53 /** 
    54  * This class is used to extract a value from an argument.  
    55  * It is used because we need a special implementation to 
    56  * deal with std::string and making a specialiced function 
    57  * puts it in the T segment, thus generating link errors. 
    58  * Having a specialiced class makes the symbols weak. 
    59  * This is not pretty but I don't know how to make it 
    60  * work any other way. 
    61  */ 
    62 template<class T> 
    63 class ValueExtractor  
    64 { 
    65         friend class MultiArg<T>; 
    66    
    67         private: 
    68  
    69                 /** 
    70                  * Reference to the vector of values where the result of the  
    71                  * extraction will be put. 
    72                  */ 
    73                 std::vector<T> &_values; 
    74    
    75                 /** 
    76                  * Constructor. 
    77                  * \param values - Where the values extracted will be put. 
    78                  */ 
    79                 ValueExtractor(std::vector<T> &values) : _values(values) {} 
    80    
    81                 /** 
    82                  * Method that will attempt to parse the input stream for values 
    83                  * of type T. 
    84                  * \param val - Where the values parsed will be put. 
    85                  */ 
    86                 int extractValue( const std::string& val )  
    87                 { 
    88                         T temp; 
    89  
    90 #if defined(HAVE_SSTREAM) 
    91                         std::istringstream is(val); 
    92 #elif defined(HAVE_STRSTREAM) 
    93                         std::istrstream is(val.c_str()); 
    94 #else 
    95 #error "Need a stringstream (sstream or strstream) to compile!" 
    96 #endif 
    97  
    98                         int valuesRead = 0; 
    99      
    100                         while ( is.good() )  
    101                         { 
    102                                 if ( is.peek() != EOF ) 
    103                                         is >> temp;  
    104                                 else 
    105                                         break; 
    106        
    107                                 valuesRead++; 
    108                         }                
    109      
    110                         if ( is.fail() ) 
    111                                 return EXTRACT_FAILURE; 
    112      
    113                         if ( valuesRead > 1 ) 
    114                                 return EXTRACT_TOO_MANY; 
    115      
    116                         _values.push_back(temp); 
    117      
    118                         return 0; 
    119                 }  
    120 }; 
    121  
    122 /** 
    123  * Specialization for string.  This is necessary because istringstream 
    124  * operator>> is not able to ignore spaces...  meaning -x "X Y" will only  
    125  * read 'X'... and thus the specialization. 
    126  */ 
    127 template<> 
    128 class ValueExtractor<std::string>  
    129 { 
    130         friend class MultiArg<std::string>; 
    131  
    132         private: 
    133  
    134                 /** 
    135                  * Reference to the vector of strings where the result of the  
    136                  * extraction will be put. 
    137                  */ 
    138         std::vector<std::string> &_values; 
    139    
    140                 /** 
    141                  * Constructor. 
    142                  * \param values - Where the strings extracted will be put. 
    143                  */ 
    144         ValueExtractor(std::vector<std::string> &values) : _values(values) {} 
    145  
    146                 /** 
    147                  * Method that will attempt to parse the input stream for values 
    148                  * of type std::string. 
    149                  * \param val - Where the values parsed will be put. 
    150                  */ 
    151         int extractValue( const std::string& val )  
    152                 { 
    153             _values.push_back( val ); 
    154             return 0; 
    155         } 
    156 }; 
    157  
    158 } //namespace MULTI_ARG_HELPER 
    159  
    16033/** 
    16134 * An argument that allows multiple values of type T to be specified.  Very 
     
    16639class MultiArg : public Arg 
    16740{ 
    168         protected: 
    169  
    170                 /** 
    171                  * The list of values parsed from the CmdLine. 
    172                  */ 
    173                 std::vector<T> _values; 
    174  
    175                 /** 
    176                  * A list of allowed values. 
    177                  * A list of values allowed for this argument. If the value parsed 
    178                  * for this arg is not found in this list, then an exception is 
    179                  * thrown.  If the list is empty, then any value is allowed. 
    180                  */ 
    181                 std::vector<T> _allowed; 
    182  
    183                 /** 
    184                  * The description of type T to be used in the usage. 
    185                  */ 
    186                 std::string _typeDesc; 
    187  
    188                 /** 
    189                  * Extracts the value from the string. 
    190                  * Attempts to parse string as type T, if this fails an exception 
    191                  * is thrown. 
    192                  * \param val - The string to be read. 
    193                  */ 
    194                 void _extractValue( const std::string& val ); 
    195  
    196                 /** 
    197                  * Checks to see if parsed value is in allowed list. 
    198                  * \param val - value parsed (only used in output). 
    199                  */ 
    200                 void _checkAllowed( const std::string& val ); 
    201  
    202         public: 
    203  
    204                 /** 
    205                  * Constructor. 
    206                  * \param flag - The one character flag that identifies this 
    207                  * argument on the command line. 
    208                  * \param name - A one word name for the argument.  Can be 
    209                  * used as a long flag on the command line. 
    210                  * \param desc - A description of what the argument is for or 
    211                  * does. 
    212                  * \param req - Whether the argument is required on the command 
    213                  * line. 
    214                  * \param typeDesc - A short, human readable description of the 
    215                  * type that this object expects.  This is used in the generation 
    216                  * of the USAGE statement.  The goal is to be helpful to the end user 
    217                  * of the program. 
    218                  * \param v - An optional visitor.  You probably should not 
    219                  * use this unless you have a very good reason. 
    220                  */ 
    221                 MultiArg( const std::string& flag, 
     41public: 
     42        typedef std::vector<T> container_type;   
     43        typedef typename container_type::iterator iterator; 
     44        typedef typename container_type::const_iterator const_iterator; 
     45 
     46protected: 
     47 
     48        /** 
     49         * The list of values parsed from the CmdLine. 
     50         */ 
     51        std::vector<T> _values; 
     52 
     53        /** 
     54         * The description of type T to be used in the usage. 
     55         */ 
     56        std::string _typeDesc; 
     57 
     58        /** 
     59         * A list of constraint on this Arg.  
     60         */ 
     61        Constraint<T>* _constraint; 
     62 
     63        /** 
     64         * Extracts the value from the string. 
     65         * Attempts to parse string as type T, if this fails an exception 
     66         * is thrown. 
     67         * \param val - The string to be read. 
     68         */ 
     69        void _extractValue( const std::string& val ); 
     70 
     71        /** 
     72         * Used by XorHandler to decide whether to keep parsing for this arg. 
     73         */ 
     74        bool _allowMore; 
     75 
     76public: 
     77 
     78        /** 
     79         * Constructor. 
     80         * \param flag - The one character flag that identifies this 
     81         * argument on the command line. 
     82         * \param name - A one word name for the argument.  Can be 
     83         * used as a long flag on the command line. 
     84         * \param desc - A description of what the argument is for or 
     85         * does. 
     86         * \param req - Whether the argument is required on the command 
     87         * line. 
     88         * \param typeDesc - A short, human readable description of the 
     89         * type that this object expects.  This is used in the generation 
     90         * of the USAGE statement.  The goal is to be helpful to the end user 
     91         * of the program. 
     92         * \param v - An optional visitor.  You probably should not 
     93         * use this unless you have a very good reason. 
     94         */ 
     95        MultiArg( const std::string& flag, 
    22296                  const std::string& name, 
    22397                  const std::string& desc, 
     
    226100                  Visitor* v = NULL); 
    227101 
    228                 /** 
    229                 * Constructor. 
    230                 * \param flag - The one character flag that identifies this 
    231                 * argument on the command line. 
    232                 * \param name - A one word name for the argument.  Can be 
    233                 * used as a long flag on the command line. 
    234                 * \param desc - A description of what the argument is for or 
    235                 * does. 
    236                 * \param req - Whether the argument is required on the command 
    237                 * line. 
    238                 * \param typeDesc - A short, human readable description of the 
    239                 * type that this object expects.  This is used in the generation 
    240                 * of the USAGE statement.  The goal is to be helpful to the end user 
    241                 * of the program. 
    242                 * \param parser - A CmdLine parser object to add this Arg to 
    243                 * \param v - An optional visitor.  You probably should not 
    244                 * use this unless you have a very good reason. 
    245                 */ 
    246                 MultiArg( const std::string& flag,  
     102        /** 
     103        * Constructor. 
     104        * \param flag - The one character flag that identifies this 
     105        * argument on the command line. 
     106        * \param name - A one word name for the argument.  Can be 
     107        * used as a long flag on the command line. 
     108        * \param desc - A description of what the argument is for or 
     109        * does. 
     110        * \param req - Whether the argument is required on the command 
     111        * line. 
     112        * \param typeDesc - A short, human readable description of the 
     113        * type that this object expects.  This is used in the generation 
     114        * of the USAGE statement.  The goal is to be helpful to the end user 
     115        * of the program. 
     116        * \param parser - A CmdLine parser object to add this Arg to 
     117        * \param v - An optional visitor.  You probably should not 
     118        * use this unless you have a very good reason. 
     119        */ 
     120        MultiArg( const std::string& flag,  
    247121                  const std::string& name, 
    248122                  const std::string& desc, 
     
    252126                  Visitor* v = NULL ); 
    253127 
    254                 /** 
    255                 * Constructor. 
    256                 * \param flag - The one character flag that identifies this 
    257                 * argument on the command line. 
    258                 * \param name - A one word name for the argument.  Can be 
    259                 * used as a long flag on the command line. 
    260                 * \param desc - A description of what the argument is for or 
    261                 * does. 
    262                 * \param req - Whether the argument is required on the command 
    263                 * line. 
    264                  * \param allowed - A vector of type T that where the values in the 
    265                  * vector are the only values allowed for the arg. 
    266                 * \param v - An optional visitor.  You probably should not 
    267                 * use this unless you have a very good reason. 
    268                 */ 
    269                 MultiArg( const std::string& flag, 
     128        /** 
     129        * Constructor. 
     130        * \param flag - The one character flag that identifies this 
     131        * argument on the command line. 
     132        * \param name - A one word name for the argument.  Can be 
     133        * used as a long flag on the command line. 
     134        * \param desc - A description of what the argument is for or 
     135        * does. 
     136        * \param req - Whether the argument is required on the command 
     137        * line. 
     138         * \param constraint - A pointer to a Constraint object used 
     139         * to constrain this Arg. 
     140        * \param v - An optional visitor.  You probably should not 
     141        * use this unless you have a very good reason. 
     142        */ 
     143        MultiArg( const std::string& flag, 
    270144                  const std::string& name, 
    271145                  const std::string& desc, 
    272146                  bool req, 
    273                   const std::vector<T>& allowed, 
     147                  Constraint<T>* constraint, 
    274148                  Visitor* v = NULL ); 
    275149                   
    276                 /** 
    277                 * Constructor. 
    278                 * \param flag - The one character flag that identifies this 
    279                 * argument on the command line. 
    280                 * \param name - A one word name for the argument.  Can be 
    281                 * used as a long flag on the command line. 
    282                 * \param desc - A description of what the argument is for or 
    283                 * does. 
    284                 * \param req - Whether the argument is required on the command 
    285                 * line. 
    286                  * \param allowed - A vector of type T that where the values in the 
    287                  * vector are the only values allowed for the arg. 
    288                 * \param parser - A CmdLine parser object to add this Arg to 
    289                 * \param v - An optional visitor.  You probably should not 
    290                 * use this unless you have a very good reason. 
    291                 */ 
    292                 MultiArg( const std::string& flag,  
     150        /** 
     151        * Constructor. 
     152        * \param flag - The one character flag that identifies this 
     153        * argument on the command line. 
     154        * \param name - A one word name for the argument.  Can be 
     155        * used as a long flag on the command line. 
     156        * \param desc - A description of what the argument is for or 
     157        * does. 
     158        * \param req - Whether the argument is required on the command 
     159        * line. 
     160         * \param constraint - A pointer to a Constraint object used 
     161         * to constrain this Arg. 
     162        * \param parser - A CmdLine parser object to add this Arg to 
     163        * \param v - An optional visitor.  You probably should not 
     164        * use this unless you have a very good reason. 
     165        */ 
     166        MultiArg( const std::string& flag,  
    293167                  const std::string& name, 
    294168                  const std::string& desc, 
    295169                  bool req, 
    296                   const std::vector<T>& allowed, 
     170                  Constraint<T>* constraint, 
    297171                  CmdLineInterface& parser, 
    298172                  Visitor* v = NULL ); 
    299173                   
    300                 /** 
    301                  * Handles the processing of the argument. 
    302                  * This re-implements the Arg version of this method to set the 
    303                  * _value of the argument appropriately.  It knows the difference 
    304                  * between labeled and unlabeled. 
    305                  * \param i - Pointer the the current argument in the list. 
    306                  * \param args - Mutable list of strings. Passed from main(). 
    307                  */ 
    308                 virtual bool processArg(int* i, std::vector<std::string>& args);  
    309  
    310                 /** 
    311                  * Returns a vector of type T containing the values parsed from 
    312                  * the command line. 
    313                  */ 
    314                 const std::vector<T>& getValue(); 
    315  
    316                 /** 
    317                  * Returns the a short id string.  Used in the usage.  
    318                  * \param val - value to be used. 
    319                  */ 
    320                 virtual std::string shortID(const std::string& val="val") const; 
    321  
    322                 /** 
    323                  * Returns the a long id string.  Used in the usage.  
    324                  * \param val - value to be used. 
    325                  */ 
    326                 virtual std::string longID(const std::string& val="val") const; 
    327  
    328                 /** 
    329                  * Once we've matched the first value, then the arg is no longer 
    330                  * required. 
    331                  */ 
    332                 virtual bool isRequired() const; 
    333  
    334         private: 
    335  
    336                 /** 
    337                  * Common initialization code for constructors with allowed vectors. 
    338                  */ 
    339                 void allowedInit(); 
     174        /** 
     175         * Handles the processing of the argument. 
     176         * This re-implements the Arg version of this method to set the 
     177         * _value of the argument appropriately.  It knows the difference 
     178         * between labeled and unlabeled. 
     179         * \param i - Pointer the the current argument in the list. 
     180         * \param args - Mutable list of strings. Passed from main(). 
     181         */ 
     182        virtual bool processArg(int* i, std::vector<std::string>& args);  
     183 
     184        /** 
     185         * Returns a vector of type T containing the values parsed from 
     186         * the command line. 
     187         */ 
     188        const std::vector<T>& getValue(); 
     189 
     190        /** 
     191         * Returns an iterator over the values parsed from the command 
     192         * line. 
     193         */ 
     194        const_iterator begin() const { return _values.begin(); } 
     195 
     196        /** 
     197         * Returns the end of the values parsed from the command 
     198         * line. 
     199         */ 
     200        const_iterator end() const { return _values.end(); } 
     201 
     202        /** 
     203         * Returns the a short id string.  Used in the usage.  
     204         * \param val - value to be used. 
     205         */ 
     206        virtual std::string shortID(const std::string& val="val") const; 
     207 
     208        /** 
     209         * Returns the a long id string.  Used in the usage.  
     210         * \param val - value to be used. 
     211         */ 
     212        virtual std::string longID(const std::string& val="val") const; 
     213 
     214        /** 
     215         * Once we've matched the first value, then the arg is no longer 
     216         * required. 
     217         */ 
     218        virtual bool isRequired() const; 
     219 
     220        virtual bool allowMore(); 
     221         
     222        virtual void reset(); 
     223 
    340224}; 
    341225 
    342 /** 
    343  * 
    344  */ 
    345 template<class T> 
    346 void MultiArg<T>::allowedInit() 
    347 { 
    348         for ( unsigned int i = 0; i < _allowed.size(); i++ ) 
    349         { 
    350  
    351 #if defined(HAVE_SSTREAM) 
    352                 std::ostringstream os; 
    353 #elif defined(HAVE_STRSTREAM) 
    354                 std::ostrstream os; 
    355 #else 
    356 #error "Need a stringstream (sstream or strstream) to compile!" 
    357 #endif 
    358  
    359                 os << _allowed[i]; 
    360  
    361                 std::string temp( os.str() ); 
    362  
    363                 if ( i > 0 ) 
    364                         _typeDesc += "|"; 
    365          
    366                 _typeDesc += temp; 
    367         } 
    368 } 
    369  
    370 /** 
    371  * 
    372  */ 
    373226template<class T> 
    374227MultiArg<T>::MultiArg(const std::string& flag,  
     
    379232                      Visitor* v) 
    380233: Arg( flag, name, desc, req, true, v ), 
    381   _typeDesc( typeDesc ) 
    382 { } 
     234  _typeDesc( typeDesc ), 
     235  _constraint( NULL ), 
     236  _allowMore(false) 
     237{  
     238        _acceptsMultipleValues = true; 
     239} 
    383240 
    384241template<class T> 
     
    391248                      Visitor* v) 
    392249: Arg( flag, name, desc, req, true, v ), 
    393   _typeDesc( typeDesc ) 
     250  _typeDesc( typeDesc ), 
     251  _constraint( NULL ), 
     252  _allowMore(false) 
    394253{  
    395254        parser.add( this ); 
     255        _acceptsMultipleValues = true; 
    396256} 
    397257 
     
    404264                      const std::string& desc, 
    405265                      bool req, 
    406                       const std::vector<T>& allowed, 
     266                      Constraint<T>* constraint, 
    407267                      Visitor* v) 
    408268: Arg( flag, name, desc, req, true, v ), 
    409   _allowed( allowed ) 
     269  _typeDesc( constraint->shortID() ), 
     270  _constraint( constraint ), 
     271  _allowMore(false) 
    410272{  
    411         allowedInit(); 
     273        _acceptsMultipleValues = true; 
    412274} 
    413275 
     
    417279                      const std::string& desc, 
    418280                      bool req, 
    419                       const std::vector<T>& allowed, 
     281                      Constraint<T>* constraint, 
    420282                      CmdLineInterface& parser, 
    421283                      Visitor* v) 
    422284: Arg( flag, name, desc, req, true, v ), 
    423   _allowed( allowed ) 
     285  _typeDesc( constraint->shortID() ), 
     286  _constraint( constraint ), 
     287  _allowMore(false) 
    424288{  
    425         allowedInit(); 
    426289        parser.add( this ); 
    427 } 
    428  
    429 /** 
    430  * 
    431  */ 
     290        _acceptsMultipleValues = true; 
     291} 
     292 
    432293template<class T> 
    433294const std::vector<T>& MultiArg<T>::getValue() { return _values; } 
    434295 
    435 /** 
    436  * 
    437  */ 
    438296template<class T> 
    439297bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)  
     
    457315                                           toString() ) ); 
    458316 
     317                // always take the first one, regardless of start string 
    459318                if ( value == "" ) 
    460319                { 
    461320                        (*i)++; 
    462                         if ( (unsigned int)*i < args.size() ) 
     321                        if ( static_cast<unsigned int>(*i) < args.size() ) 
    463322                                _extractValue( args[*i] ); 
    464323                        else 
    465324                                throw( ArgParseException("Missing a value for this argument!", 
    466325                                         toString() ) ); 
    467                 } 
     326                }  
    468327                else 
    469328                        _extractValue( value ); 
    470329 
     330                /* 
     331                // continuing taking the args until we hit one with a start string  
     332                while ( (unsigned int)(*i)+1 < args.size() && 
     333                                args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 && 
     334                        args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )  
     335                                _extractValue( args[++(*i)] ); 
     336                */ 
     337 
     338                _alreadySet = true; 
    471339                _checkWithVisitor(); 
    472340 
     
    478346 
    479347/** 
    480  * Checks to see if the value parsed is in the allowed list. 
     348 * 
    481349 */ 
    482350template<class T> 
    483 void MultiArg<T>::_checkAllowed( const std::string& val ) 
    484 { 
    485         if ( _allowed.size() > 0 ) 
    486                 if ( find(_allowed.begin(),_allowed.end(),_values.back())  
    487                  == _allowed.end() ) 
    488                         throw( CmdLineParseException( "Couldn't find '" + val + 
    489                                           "' in allowed list.", toString() ) ); 
     351std::string MultiArg<T>::shortID(const std::string& val) const 
     352{ 
     353        static_cast<void>(val); // Ignore input, don't warn 
     354        return Arg::shortID(_typeDesc) + " ... "; 
    490355} 
    491356 
     
    494359 */ 
    495360template<class T> 
    496 std::string MultiArg<T>::shortID(const std::string& val) const 
    497 { 
    498         std::string id = Arg::shortID(_typeDesc) + " ... "; 
    499  
    500         return id; 
    501 } 
    502  
    503 /** 
    504  * 
    505  */ 
    506 template<class T> 
    507361std::string MultiArg<T>::longID(const std::string& val) const 
    508362{ 
    509         std::string id = Arg::longID(_typeDesc) + "  (accepted multiple times)"; 
    510  
    511         return id; 
     363        static_cast<void>(val); // Ignore input, don't warn 
     364        return Arg::longID(_typeDesc) + "  (accepted multiple times)"; 
    512365} 
    513366 
     
    534387void MultiArg<T>::_extractValue( const std::string& val )  
    535388{ 
    536         MULTI_ARG_HELPER::ValueExtractor<T> ve(_values); 
    537                    
    538         int err = ve.extractValue(val); 
    539  
    540         if ( err == MULTI_ARG_HELPER::EXTRACT_FAILURE ) 
    541                 throw( ArgParseException("Couldn't read argument value " 
    542                                  "from string '" + val + "'", toString() ) ); 
    543  
    544         if(err == MULTI_ARG_HELPER::EXTRACT_TOO_MANY) 
    545             throw( ArgParseException("More than one valid value " 
    546                                  "parsed from string '" + val + "'",  
    547                                                                  toString() ) );                     
    548         _checkAllowed( val ); 
     389    try { 
     390        T tmp; 
     391        ExtractValue(tmp, val, typename ArgTraits<T>::ValueCategory()); 
     392        _values.push_back(tmp); 
     393    } catch( ArgParseException &e) { 
     394        throw ArgParseException(e.error(), toString()); 
     395    } 
     396 
     397    if ( _constraint != NULL ) 
     398        if ( ! _constraint->check( _values.back() ) ) 
     399            throw( CmdLineParseException( "Value '" + val + 
     400                                          "' does not meet constraint: " + 
     401                                          _constraint->description(),  
     402                                          toString() ) ); 
    549403} 
    550404                 
     405template<class T> 
     406bool MultiArg<T>::allowMore() 
     407{ 
     408        bool am = _allowMore; 
     409        _allowMore = true; 
     410        return am; 
     411} 
     412 
     413template<class T> 
     414void MultiArg<T>::reset() 
     415{ 
     416        Arg::reset(); 
     417        _values.clear(); 
     418} 
    551419 
    552420} // namespace TCLAP 
Note: See TracChangeset for help on using the changeset viewer.