diff --git a/include/tclap/MultiArg.h b/include/tclap/MultiArg.h index 039a047..6db0f98 100644 --- a/include/tclap/MultiArg.h +++ b/include/tclap/MultiArg.h @@ -47,6 +47,14 @@ class MultiArg : public Arg */ vector _values; + /** + * A list of allowed values. + * A list of values allowed for this argument. If the value parsed + * for this arg is not found in this list, then an exception is + * thrown. If the list is empty, then any value is allowed. + */ + vector _allowed; + /** * The description of type T to be used in the usage. */ @@ -58,8 +66,15 @@ class MultiArg : public Arg * is thrown. * \param val - The string to be read. */ + void _extractValue( const string& val ); - + + /** + * Checks to see if parsed value is in allowed list. + * \param val - value parsed (only used in output). + */ + void _checkAllowed( const string& val ); + public: /** @@ -86,6 +101,28 @@ class MultiArg : public Arg const string& typeDesc, Visitor* v = NULL); + /** + * Constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param allowed - A vector of type T that where the values in the + * vector are the only values allowed for the arg. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + MultiArg( const string& flag, + const string& name, + const string& desc, + bool req, + const vector& allowed, + Visitor* v = NULL); + /** * Destructor. */ @@ -119,6 +156,12 @@ class MultiArg : public Arg */ virtual string longID(const string& val="val") const; + /** + * Once we've matched the first value, then the arg is no longer + * required. + */ + virtual bool isRequired() const; + }; /** @@ -135,6 +178,34 @@ MultiArg::MultiArg(const string& flag, _typeDesc( typeDesc ) { }; + +/** + * + */ +template +MultiArg::MultiArg(const string& flag, + const string& name, + const string& desc, + bool req, + const vector& allowed, + Visitor* v) +: Arg( flag, name, desc, req, true, v ), + _allowed( allowed ) +{ + for ( unsigned int i = 0; i < _allowed.size(); i++ ) + { + ostringstream os; + os << _allowed[i]; + + string temp( os.str() ); + + if ( i > 0 ) + _typeDesc += ","; + _typeDesc += temp; + } +}; + + /** * */ @@ -217,8 +288,11 @@ void MultiArg::_extractValue( const string& val ) throw( ArgException("More than one valid value parsed from string '" + val + "'", toString() ) ); + _values.push_back(temp); + _checkAllowed( val ); + } /** @@ -228,7 +302,22 @@ void MultiArg::_extractValue( const string& val ) template<> void MultiArg::_extractValue( const string& val ) { - _values.push_back(val); + _values.push_back( val ); + + _checkAllowed( val ); +} + +/** + * Checks to see if the value parsed is in the allowed list. + */ +template +void MultiArg::_checkAllowed( const string& val ) +{ + if ( _allowed.size() > 0 ) + if ( find(_allowed.begin(),_allowed.end(),_values.back()) + == _allowed.end() ) + throw( ArgException( "Couldn't find '" + val + + "' in allowed list.", toString() ) ); } /** @@ -253,6 +342,25 @@ string MultiArg::longID(const string& val) const return id; } +/** + * Once we've matched the first value, then the arg is no longer + * required. + */ +template +bool MultiArg::isRequired() const +{ + if ( _required ) + { + if ( _values.size() > 1 ) + return false; + else + return true; + } + else + return false; + +} + } #endif diff --git a/include/tclap/UnlabeledMultiArg.h b/include/tclap/UnlabeledMultiArg.h index 1aadc24..d3324c3 100644 --- a/include/tclap/UnlabeledMultiArg.h +++ b/include/tclap/UnlabeledMultiArg.h @@ -63,6 +63,25 @@ class UnlabeledMultiArg : public MultiArg bool ignoreable = false, Visitor* v = NULL ); + /** + * Constructor. + * \param name - The name of the Arg. Note that this is used for + * identification, not as a long flag. + * \param desc - A description of what the argument is for or + * does. + * \param allowed - A vector of type T that where the values in the + * vector are the only values allowed for the arg. + * \param ignoreable - Whether or not this argument can be ignored + * using the "--" flag. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + UnlabeledMultiArg( const string& name, + const string& desc, + const vector& allowed, + bool ignoreable = false, + Visitor* v = NULL ); + /** * Handles the processing of the argument. * This re-implements the Arg version of this method to set the @@ -109,6 +128,17 @@ UnlabeledMultiArg::UnlabeledMultiArg(const string& name, _ignoreable = ignoreable; }; +template +UnlabeledMultiArg::UnlabeledMultiArg(const string& name, + const string& desc, + const vector& allowed, + bool ignoreable, + Visitor* v) +: MultiArg("", name, desc, false, allowed, v) +{ + _ignoreable = ignoreable; +}; + template bool UnlabeledMultiArg::processArg(int *i, vector& args) { diff --git a/include/tclap/UnlabeledValueArg.h b/include/tclap/UnlabeledValueArg.h index 8fb7e67..8e9b613 100644 --- a/include/tclap/UnlabeledValueArg.h +++ b/include/tclap/UnlabeledValueArg.h @@ -75,6 +75,33 @@ class UnlabeledValueArg : public ValueArg bool ignoreable = false, Visitor* v = NULL); + /** + * UnlabeledValueArg constructor. + * Note that this constructor does not have a required flag. Any + * unlabeled argument added to the CmdLine is by default required. + * If you want optional, unlabeled arguments then use an + * UnlabeledMultiArg. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param allowed - A vector of type T that where the values in the + * vector are the only values allowed for the arg. + * \param ignoreable - Allows you to specify that this argument can be + * ignored if the '--' flag is set. This defaults to false (cannot + * be ignored) and should generally stay that way unless you have + * some special need for certain arguments to be ignored. + * \param v - Optional Vistor. You should leave this blank unless + * you have a very good reason. + */ + UnlabeledValueArg(const string& name, + const string& desc, + T value, + const vector& allowed, + bool ignoreable = false, + Visitor* v = NULL); /** * Handles the processing of the argument. @@ -123,6 +150,21 @@ UnlabeledValueArg::UnlabeledValueArg(const string& name, _ignoreable = ignoreable; }; +/** + * Constructor implemenation. + */ +template +UnlabeledValueArg::UnlabeledValueArg(const string& name, + const string& desc, + T val, + const vector& allowed, + bool ignoreable, + Visitor* v) +: ValueArg("", name, desc, true, val, allowed, v) +{ + _ignoreable = ignoreable; +}; + /** * Implementation of processArg(). */ diff --git a/include/tclap/ValueArg.h b/include/tclap/ValueArg.h index 725bf9c..4d3499e 100644 --- a/include/tclap/ValueArg.h +++ b/include/tclap/ValueArg.h @@ -42,7 +42,7 @@ namespace TCLAP { * Instead use an UnlabeledValueArg. */ template -class ValueArg : public Arg +class ValueArg : public Arg { protected: @@ -53,6 +53,14 @@ class ValueArg : public Arg */ T _value; + /** + * A list of allowed values. + * A list of values allowed for this argument. If the value parsed + * for this arg is not found in this list, then an exception is + * thrown. If the list is empty, then any value is allowed. + */ + vector _allowed; + /** * A human readable description of the type to be parsed. * This is a hack, plain and simple. Ideally we would use RTTI to @@ -70,6 +78,12 @@ class ValueArg : public Arg */ void _extractValue( const string& val ); + /** + * Checks to see if parsed value is in allowed list. + * \param val - value parsed (only used in output). + */ + void _checkAllowed( const string& val ); + public: /** @@ -103,6 +117,35 @@ class ValueArg : public Arg const string& typeDesc, Visitor* v = NULL); + /** + * Labeled ValueArg constructor. + * You could conceivably call this constructor with a blank flag, + * but that would make you a bad person. It would also cause + * an exception to be thrown. If you want an unlabeled argument, + * use the other constructor. + * \param flag - The one character flag that identifies this + * argument on the command line. + * \param name - A one word name for the argument. Can be + * used as a long flag on the command line. + * \param desc - A description of what the argument is for or + * does. + * \param req - Whether the argument is required on the command + * line. + * \param value - The default value assigned to this argument if it + * is not present on the command line. + * \param allowed - A vector of type T that where the values in the + * vector are the only values allowed for the arg. + * \param v - An optional visitor. You probably should not + * use this unless you have a very good reason. + */ + ValueArg(const string& flag, + const string& name, + const string& desc, + bool req, + T value, + const vector& allowed, + Visitor* v = NULL); + /** * Destructor. */ @@ -153,7 +196,36 @@ ValueArg::ValueArg(const string& flag, : Arg(flag, name, desc, req, true, v), _value( val ), _typeDesc( typeDesc ) -{ }; +{ } + +/** + * Constructor with allowed list. + */ +template +ValueArg::ValueArg(const string& flag, + const string& name, + const string& desc, + bool req, + T val, + const vector& allowed, + Visitor* v) +: Arg(flag, name, desc, req, true, v), + _value( val ), + _allowed( allowed ) +{ + for ( unsigned int i = 0; i < _allowed.size(); i++ ) + { + ostringstream os; + os << _allowed[i]; + + string temp( os.str() ); + + if ( i > 0 ) + _typeDesc += ","; + _typeDesc += temp; + } +} + /** * Destructor implementation. @@ -239,6 +311,7 @@ void ValueArg::_extractValue( const string& val ) throw( ArgException("More than one valid value parsed from string '" + val + "'", toString() ) ); + _checkAllowed( val ); } /** @@ -249,9 +322,22 @@ void ValueArg::_extractValue( const string& val ) template<> void ValueArg::_extractValue( const string& val ) { + _checkAllowed( val ); _value = val; } +/** + * Checks to see if the value parsed is in the allowed list. + */ +template +void ValueArg::_checkAllowed( const string& val ) +{ + if ( _allowed.size() > 0 ) + if ( find(_allowed.begin(),_allowed.end(),_value) == _allowed.end() ) + throw( ArgException( "Couldn't find '" + val + + "' in allowed list.", toString() ) ); +} + /** * Implementation of shortID. */