multi_arg.hpp
Go to the documentation of this file.
00001 
00011 /*****************************************************************************
00012 ** Ifdefs
00013 *****************************************************************************/
00014 
00015 #ifndef TCLAP_MULTIPLE_ARGUMENT_H
00016 #define TCLAP_MULTIPLE_ARGUMENT_H
00017 
00018 #include <string>
00019 #include <vector>
00020 #include <cstdio>
00021 #include "arg.hpp"
00022 #include "constraint.hpp"
00023 
00024 #define HAVE_SSTREAM
00025 
00026 #if defined(HAVE_SSTREAM)
00027 #include <sstream>
00028 #elif defined(HAVE_STRSTREAM)
00029 #include <strstream>
00030 #else
00031 #error "Need a stringstream (sstream or strstream) to compile!"
00032 #endif
00033 
00034 namespace ecl {
00035 
00036 template<class T> class MultiArg;
00037 
00038 namespace MultiArgHelper {
00039 
00040 enum Error_e { EXTRACT_FAILURE = 1000, EXTRACT_TOO_MANY };
00041 
00053 template<class T>
00054 class ValueExtractor
00055 {
00056         friend class MultiArg<T>;
00057 
00058         private:
00059 
00064                 std::vector<T> &_values;
00065 
00070                 ValueExtractor(std::vector<T> &values) : _values(values) {}
00071 
00077                 int extractValue( const std::string& val )
00078                 {
00079                         T temp;
00080 
00081 #if defined(HAVE_SSTREAM)
00082                         std::istringstream is(val);
00083 #elif defined(HAVE_STRSTREAM)
00084                         std::istrstream is(val.c_str());
00085 #else
00086 #error "Need a stringstream (sstream or strstream) to compile!"
00087 #endif
00088 
00089                         int valuesRead = 0;
00090 
00091                         while ( is.good() )
00092                         {
00093                                 if ( is.peek() != EOF )
00094                                         is >> temp;
00095                                 else
00096                                         break;
00097 
00098                                 valuesRead++;
00099                         }
00100 
00101                         if ( is.fail() )
00102                                 return EXTRACT_FAILURE;
00103 
00104                         if ( valuesRead > 1 )
00105                                 return EXTRACT_TOO_MANY;
00106 
00107                         _values.push_back(temp);
00108 
00109                         return 0;
00110                 }
00111 };
00112 
00120 template<>
00121 class ValueExtractor<std::string>
00122 {
00123         friend class MultiArg<std::string>;
00124 
00125         private:
00126 
00131         std::vector<std::string> &_values;
00132 
00137         ValueExtractor(std::vector<std::string> &values) : _values(values) {}
00138 
00144         int extractValue( const std::string& val )
00145                 {
00146             _values.push_back( val );
00147             return 0;
00148         }
00149 };
00150 
00151 } //namespace MultiArgHelper
00152 
00158 template<class T>
00159 class MultiArg : public Arg
00160 {
00161         protected:
00162 
00166                 std::vector<T> _values;
00167 
00171                 std::string _typeDesc;
00172 
00176                 Constraint<T>* _constraint;
00177 
00184                 void _extractValue( const std::string& val );
00185 
00186                 bool _allowMore;
00187 
00188         public:
00189 
00207                 MultiArg( const std::string& flag,
00208                   const std::string& name,
00209                   const std::string& desc,
00210                   bool req,
00211                   const std::string& typeDesc,
00212                   Visitor* v = NULL);
00213 
00232                 MultiArg( const std::string& flag,
00233                   const std::string& name,
00234                   const std::string& desc,
00235                   bool req,
00236                   const std::string& typeDesc,
00237                   CmdLineInterface& parser,
00238                   Visitor* v = NULL );
00239 
00255                 MultiArg( const std::string& flag,
00256                   const std::string& name,
00257                   const std::string& desc,
00258                   bool req,
00259                   Constraint<T>* constraint,
00260                   Visitor* v = NULL );
00261 
00278                 MultiArg( const std::string& flag,
00279                   const std::string& name,
00280                   const std::string& desc,
00281                   bool req,
00282                   Constraint<T>* constraint,
00283                   CmdLineInterface& parser,
00284                   Visitor* v = NULL );
00285 
00294                 virtual bool processArg(int* i, std::vector<std::string>& args);
00295 
00300                 const std::vector<T>& getValue();
00301 
00306                 virtual std::string shortID(const std::string& val="val") const;
00307 
00312                 virtual std::string longID(const std::string& val="val") const;
00313 
00318                 virtual bool isRequired() const;
00319 
00320                 virtual bool allowMore();
00321 
00322 };
00323 
00324 template<class T>
00325 MultiArg<T>::MultiArg(const std::string& flag,
00326                       const std::string& name,
00327                       const std::string& desc,
00328                       bool req,
00329                       const std::string& typeDesc,
00330                       Visitor* v)
00331 : Arg( flag, name, desc, req, true, v ),
00332   _typeDesc( typeDesc ),
00333   _constraint( NULL ),
00334   _allowMore(false)
00335 {
00336         _acceptsMultipleValues = true;
00337 }
00338 
00339 template<class T>
00340 MultiArg<T>::MultiArg(const std::string& flag,
00341                       const std::string& name,
00342                       const std::string& desc,
00343                       bool req,
00344                       const std::string& typeDesc,
00345                       CmdLineInterface& parser,
00346                       Visitor* v)
00347 : Arg( flag, name, desc, req, true, v ),
00348   _typeDesc( typeDesc ),
00349   _constraint( NULL ),
00350   _allowMore(false)
00351 {
00352         parser.add( this );
00353         _acceptsMultipleValues = true;
00354 }
00355 
00359 template<class T>
00360 MultiArg<T>::MultiArg(const std::string& flag,
00361                       const std::string& name,
00362                       const std::string& desc,
00363                       bool req,
00364                       Constraint<T>* constraint,
00365                       Visitor* v)
00366 : Arg( flag, name, desc, req, true, v ),
00367   _typeDesc( constraint->shortID() ),
00368   _constraint( constraint ),
00369   _allowMore(false)
00370 {
00371         _acceptsMultipleValues = true;
00372 }
00373 
00374 template<class T>
00375 MultiArg<T>::MultiArg(const std::string& flag,
00376                       const std::string& name,
00377                       const std::string& desc,
00378                       bool req,
00379                       Constraint<T>* constraint,
00380                       CmdLineInterface& parser,
00381                       Visitor* v)
00382 : Arg( flag, name, desc, req, true, v ),
00383   _typeDesc( constraint->shortID() ),
00384   _constraint( constraint ),
00385   _allowMore(false)
00386 {
00387         parser.add( this );
00388         _acceptsMultipleValues = true;
00389 }
00390 
00391 template<class T>
00392 const std::vector<T>& MultiArg<T>::getValue() { return _values; }
00393 
00394 template<class T>
00395 bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
00396 {
00397         if ( _ignoreable && Arg::ignoreRest() )
00398                 return false;
00399 
00400         if ( _hasBlanks( args[*i] ) )
00401                 return false;
00402 
00403         std::string flag = args[*i];
00404         std::string value = "";
00405 
00406         trimFlag( flag, value );
00407 
00408         if ( argMatches( flag ) )
00409         {
00410                 if ( Arg::delimiter() != ' ' && value == "" )
00411                         throw( ArgParseException(
00412                                    "Couldn't find delimiter for this argument!",
00413                                            toString() ) );
00414 
00415                 // always take the first one, regardless of start string
00416                 if ( value == "" )
00417                 {
00418                         (*i)++;
00419                         if ( static_cast<unsigned int>(*i) < args.size() )
00420                                 _extractValue( args[*i] );
00421                         else
00422                                 throw( ArgParseException("Missing a value for this argument!",
00423                                          toString() ) );
00424                 }
00425                 else
00426                         _extractValue( value );
00427 
00428                 /*
00429                 // continuing taking the args until we hit one with a start string
00430                 while ( (unsigned int)(*i)+1 < args.size() &&
00431                                 args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
00432                         args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
00433                                 _extractValue( args[++(*i)] );
00434                 */
00435 
00436                 _alreadySet = true;
00437                 _checkWithVisitor();
00438 
00439                 return true;
00440         }
00441         else
00442                 return false;
00443 }
00444 
00448 template<class T>
00449 std::string MultiArg<T>::shortID(const std::string& val) const
00450 {
00451         std::string id = Arg::shortID(_typeDesc) + " ... ";
00452 
00453         return id;
00454 }
00455 
00459 template<class T>
00460 std::string MultiArg<T>::longID(const std::string& val) const
00461 {
00462         std::string id = Arg::longID(_typeDesc) + "  (accepted multiple times)";
00463 
00464         return id;
00465 }
00466 
00471 template<class T>
00472 bool MultiArg<T>::isRequired() const
00473 {
00474         if ( _required )
00475         {
00476                 if ( _values.size() > 1 )
00477                         return false;
00478                 else
00479                         return true;
00480         }
00481         else
00482                 return false;
00483 
00484 }
00485 
00486 template<class T>
00487 void MultiArg<T>::_extractValue( const std::string& val )
00488 {
00489         MultiArgHelper::ValueExtractor<T> ve(_values);
00490 
00491         int err = ve.extractValue(val);
00492 
00493         if ( err == MultiArgHelper::EXTRACT_FAILURE )
00494                 throw( ArgParseException("Couldn't read argument value "
00495                                  "from string '" + val + "'", toString() ) );
00496 
00497         if(err == MultiArgHelper::EXTRACT_TOO_MANY)
00498             throw( ArgParseException("More than one valid value "
00499                                  "parsed from string '" + val + "'",
00500                                                                  toString() ) );
00501         if ( _constraint != NULL )
00502                 if ( ! _constraint->check( _values.back() ) )
00503                         throw( CmdLineParseException( "Value '" + val +
00504                                           "' does not meet constraint: " +
00505                                           _constraint->description(),
00506                                                                                   toString() ) );
00507 }
00508 
00509 template<class T>
00510 bool MultiArg<T>::allowMore()
00511 {
00512         bool am = _allowMore;
00513         _allowMore = true;
00514         return am;
00515 }
00516 
00517 }; // namespace ecl
00518 
00519 
00520 #endif


ecl_command_line
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:12:37