Provide eoParser::setORcreateParam to set a paramter in the parser to

a specific value.
This commit is contained in:
kuepper 2005-08-29 07:50:50 +00:00
commit f0fd15f20c
3 changed files with 421 additions and 399 deletions

View file

@ -3,25 +3,25 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoParam.h // eoParam.h
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000 // (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact: todos@geneura.ugr.es, http://geneura.ugr.es Contact: todos@geneura.ugr.es, http://geneura.ugr.es
Marc.Schoenauer@polytechnique.fr Marc.Schoenauer@polytechnique.fr
mkeijzer@dhi.dk mkeijzer@dhi.dk
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef eoParam_h #ifndef eoParam_h
@ -43,154 +43,177 @@
#include <vector> #include <vector>
#include <iterator> // for GCC 3.2 #include <iterator> // for GCC 3.2
#include <stdexcept> #include <stdexcept>
#include <eoScalarFitness.h> // for specializations #include <eoScalarFitness.h> // for specializations
/** /**
eoParam: Base class for monitoring and parsing parameters eoParam: Base class for monitoring and parsing parameters
*/ */
class eoParam class eoParam
{ {
public: public:
/** Empty constructor - called from outside any parser
*/
eoParam ()
: repLongName(""), repDefault(""), repDescription(""),
repShortHand(0), repRequired(false){}
/** /** Empty constructor - called from outside any parser */
* Construct a Param. eoParam ()
* @param _longName Long name of the argument : repLongName(""), repDefault(""), repDescription(""),
* @param _default The default value repShortHand(0), repRequired(false)
* @param _description Description of the parameter. What is useful for. {}
* @param _shortName Short name of the argument (Optional)
* @param _required If it is a necessary parameter or not
*/
eoParam (std::string _longName, std::string _default,
std::string _description, char _shortName = 0, bool _required = false)
: repLongName(_longName), repDefault(_default),
repDescription(_description ),
repShortHand(_shortName), repRequired( _required) {}
/**
* Virtual destructor is needed.
*/
virtual ~eoParam () {};
/**
* Pure virtual function to get the value out.
*/
virtual std::string getValue ( void ) const = 0;
/** /** Construct a Param.
* Pure virtual function to set the value *
*/ * @param _longName Long name of the argument
virtual void setValue(std::string _value) = 0 ; * @param _default The default value
* @param _description Description of the parameter. What is useful for.
* @param _shortName Short name of the argument (Optional)
* @param _required If it is a necessary parameter or not
*/
eoParam (std::string _longName, std::string _default,
std::string _description, char _shortName = 0, bool _required = false)
: repLongName(_longName), repDefault(_default),
repDescription(_description ),
repShortHand(_shortName), repRequired( _required)
{}
/** /**
* Returns the short name. * Virtual destructor is needed.
*/ */
char shortName ( void ) const { return repShortHand; }; virtual ~eoParam () {};
/** /**
* Returns the long name. * Pure virtual function to get the value out.
*/ */
const std::string& longName ( void ) const { return repLongName; }; virtual std::string getValue () const = 0;
/** /**
* Returns the description of the argument * Pure virtual function to set the value
*/ */
const std::string& description ( void ) const { return repDescription; }; virtual void setValue(const std::string& _value) = 0 ;
/** /**
* Returns the default value of the argument * Returns the short name.
*/ */
const std::string& defValue ( void ) const { return repDefault; }; char shortName() const { return repShortHand; };
/** /**
* Sets the default value of the argument, * Returns the long name.
*/ */
void defValue ( std::string str ) { repDefault = str; }; const std::string& longName() const { return repLongName; };
/** /**
* ALlows to change the name (see the prefix in eoParser.h) * Returns the description of the argument
*/ */
void setLongName(std::string _longName) { repLongName = _longName;} const std::string& description() const { return repDescription; };
/**
* Returns the default value of the argument
*/
const std::string& defValue() const { return repDefault; };
/**
* Sets the default value of the argument,
*/
void defValue( const std::string& str ) { repDefault = str; };
/**
* ALlows to change the name (see the prefix in eoParser.h)
*/
void setLongName(std::string _longName) { repLongName = _longName;}
/**
* Returns if required or not.
*/
bool required() const { return repRequired; };
/**
* Returns if required or not.
*/
bool required ( void ) const { return repRequired; };
private: private:
std::string repLongName; std::string repLongName;
std::string repDefault; std::string repDefault;
std::string repDescription; std::string repDescription;
char repShortHand; char repShortHand;
bool repRequired; bool repRequired;
}; };
/** /**
eoValueParam<ValueType>: templatized derivation of eoParam. Can be used to contain eoValueParam<ValueType>: templatized derivation of eoParam. Can be used to contain
any scalar value type. It makes use of std::strstream to get and set values. This any scalar value type. It makes use of std::strstream to get and set values. This
should be changed to std::stringstream when that class is available in g++. should be changed to std::stringstream when that class is available in g++.
Note also that there is a template specialization for std::pair<double, double> and Note also that there is a template specialization for std::pair<double, double> and
for std::vector<double>. These stream their contents delimited with whitespace. for std::vector<double>. These stream their contents delimited with whitespace.
*/ */
template <class ValueType> template <class ValueType>
class eoValueParam : public eoParam class eoValueParam : public eoParam
{ {
public : public :
/** Construct a Param. */
eoValueParam(void) : eoParam() {} eoValueParam(void) : eoParam() {}
/** /** Construct a Param.
* Construct a Param. *
* @param _defaultValue The default value * @param _defaultValue The default value
* @param _longName Long name of the argument * @param _longName Long name of the argument
* @param _description Description of the parameter. What is useful for. * @param _description Description of the parameter. What is useful for.
* @param _shortName Short name of the argument (Optional) * @param _shortName Short name of the argument (Optional)
* @param _required If it is a necessary parameter or not * @param _required If it is a necessary parameter or not
*/ */
eoValueParam (ValueType _defaultValue, eoValueParam(ValueType _defaultValue,
std::string _longName, std::string _longName,
std::string _description = "No description", std::string _description = "No description",
char _shortHand = 0, char _shortHand = 0,
bool _required = false) bool _required = false)
: eoParam(_longName, "", _description, _shortHand, _required), repValue(_defaultValue) : eoParam(_longName, "", _description, _shortHand, _required),
{ repValue(_defaultValue)
eoParam::defValue(getValue()); {
} eoParam::defValue(getValue());
}
/** Parameter value
@return parameter value
*/
ValueType& value()
{ return repValue; }
/** Parameter value
@overload
@return parameter value
*/
const ValueType& value() const
{ return repValue; }
ValueType& value() { return repValue; }
ValueType value() const { return repValue; }
std::string getValue(void) const std::string getValue(void) const
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::ostringstream os; std::ostringstream os;
os << repValue; os << repValue;
#else #else
char buf[1024]; char buf[1024];
std::ostrstream os(buf, 1023); std::ostrstream os(buf, 1023);
os << repValue; os << repValue;
os << std::ends; os << std::ends;
#endif #endif
return os.str(); return os.str();
} }
void setValue(std::string _value)
{ void setValue(const std::string& _value)
{
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
#else #else
std::istrstream is(_value.c_str()); std::istrstream is(_value.c_str());
#endif #endif
is >> repValue; is >> repValue;
} }
protected:
//private :
ValueType repValue; ValueType repValue;
}; };
@ -198,14 +221,14 @@ public :
Specialization for std::string Specialization for std::string
*/ */
template <> template <>
inline std::string eoValueParam<std::string>::getValue(void) const inline std::string eoValueParam<std::string>::getValue() const
{ {
return repValue; return repValue;
} }
template <> template <>
inline void eoValueParam<bool>::setValue(std::string _value) inline void eoValueParam<bool>::setValue(const std::string& _value)
{ {
if (_value.empty()) if (_value.empty())
{ {
@ -239,7 +262,7 @@ inline std::string eoValueParam<std::pair<double, double> >::getValue(void) cons
/// Because MSVC does not support partial specialization, the std::pair is a double, not a T /// Because MSVC does not support partial specialization, the std::pair is a double, not a T
template <> template <>
inline void eoValueParam<std::pair<double, double> >::setValue(std::string _value) inline void eoValueParam<std::pair<double, double> >::setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -264,8 +287,8 @@ inline std::string eoValueParam<std::vector<std::vector<double> > >::getValue(vo
os << repValue.size() << ' '; os << repValue.size() << ' ';
for (unsigned i = 0; i < repValue.size(); ++i) for (unsigned i = 0; i < repValue.size(); ++i)
{ {
os << repValue[i].size() << ' '; os << repValue[i].size() << ' ';
std::copy(repValue[i].begin(), repValue[i].end(), std::ostream_iterator<double>(os, " ")); std::copy(repValue[i].begin(), repValue[i].end(), std::ostream_iterator<double>(os, " "));
} }
#ifndef HAVE_SSTREAM #ifndef HAVE_SSTREAM
@ -276,7 +299,7 @@ inline std::string eoValueParam<std::vector<std::vector<double> > >::getValue(vo
/// Because MSVC does not support partial specialization, the std::vector is a std::vector of doubles, not a T /// Because MSVC does not support partial specialization, the std::vector is a std::vector of doubles, not a T
template <> template <>
inline void eoValueParam<std::vector<std::vector<double> > >::setValue(std::string _value) inline void eoValueParam<std::vector<std::vector<double> > >::setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -289,13 +312,13 @@ inline void eoValueParam<std::vector<std::vector<double> > >::setValue(std::stri
for (i = 0; i < repValue.size(); ++i) for (i = 0; i < repValue.size(); ++i)
{ {
unsigned sz2; unsigned sz2;
is >> sz2; is >> sz2;
repValue[i].resize(sz2); repValue[i].resize(sz2);
for (j = 0; j < sz2; ++j) for (j = 0; j < sz2; ++j)
{ {
is >> repValue[i][j]; is >> repValue[i][j];
} }
} }
} }
@ -320,7 +343,7 @@ inline std::string eoValueParam<std::vector<double> >::getValue(void) const
/// Because MSVC does not support partial specialization, the std::vector is a double, not a T /// Because MSVC does not support partial specialization, the std::vector is a double, not a T
template <> template <>
inline void eoValueParam<std::vector<double> >::setValue(std::string _value) inline void eoValueParam<std::vector<double> >::setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -355,7 +378,7 @@ inline std::string eoValueParam<std::vector<eoMinimizingFitness> >::getValue(voi
/// Because MSVC does not support partial specialization, the std::vector is a eoMinimizingFitness, not a T /// Because MSVC does not support partial specialization, the std::vector is a eoMinimizingFitness, not a T
// NOTE: g++ doesn support it either!!! // NOTE: g++ doesn support it either!!!
template <> template <>
inline void eoValueParam<std::vector<eoMinimizingFitness> >::setValue(std::string _value) inline void eoValueParam<std::vector<eoMinimizingFitness> >::setValue(const std::string& _value)
{ {
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
std::istringstream is(_value); std::istringstream is(_value);
@ -373,41 +396,41 @@ inline void eoValueParam<std::vector<eoMinimizingFitness> >::setValue(std::strin
template <> template <>
inline std::string eoValueParam<std::vector<void*> >::getValue(void) const inline std::string eoValueParam<std::vector<void*> >::getValue(void) const
{ {
throw std::runtime_error("I cannot getValue for a std::vector<EOT*>"); throw std::runtime_error("I cannot getValue for a std::vector<EOT*>");
return std::string(""); return std::string("");
} }
template <> template <>
inline void eoValueParam<std::vector<void*> >::setValue(std::string) inline void eoValueParam<std::vector<void*> >::setValue(const std::string&)
{ {
throw std::runtime_error("I cannot setValue for a std::vector<EOT*>"); throw std::runtime_error("I cannot setValue for a std::vector<EOT*>");
return; return;
} }
/*template <class ContainerType> /*template <class ContainerType>
class eoContainerParam : public eoParam class eoContainerParam : public eoParam
{ {
public : public :
eoContainerParam (ContainerType& value, std::string _shortName, std::string _longName, eoContainerParam (ContainerType& value, std::string _shortName, std::string _longName,
std::string _default, std::string _default,
std::string _description, std::string _description,
bool _required, bool _required,
bool _change ) bool _change )
: value(_value), eoParam(_shortName, _longName, _description, _default, _required, _change) : value(_value), eoParam(_shortName, _longName, _description, _default, _required, _change)
{} {}
// void setValue(const std::string & _value) // void setValue(const std::string & _value)
// { // {
// std::istd::stringstream is(_value); // std::istd::stringstream is(_value);
// copy(std::istream_iterator<Container::value_type>(is), std::istream_iterator<Container::value_type>(), back_inserter(value)); // copy(std::istream_iterator<Container::value_type>(is), std::istream_iterator<Container::value_type>(), back_inserter(value));
// } // }
private : private :
ContainerType& value; ContainerType& value;
};*/ };*/
/** /**
* Another helper class for parsing parameters like * Another helper class for parsing parameters like
* Keyword(arg1, arg2, ...) * Keyword(arg1, arg2, ...)
* *
@ -420,65 +443,65 @@ private :
class eoParamParamType : public std::pair<std::string,std::vector<std::string> > class eoParamParamType : public std::pair<std::string,std::vector<std::string> >
{ {
public: public:
eoParamParamType(std::string _value) eoParamParamType(std::string _value)
{ {
readFrom(_value); readFrom(_value);
} }
std::ostream & printOn(std::ostream & _os) const std::ostream & printOn(std::ostream & _os) const
{ {
_os << first; _os << first;
unsigned narg = second.size(); unsigned narg = second.size();
if (!narg) if (!narg)
return _os; return _os;
// Here, we do have args // Here, we do have args
_os << "("; _os << "(";
if (narg == 1) // 1 arg only if (narg == 1) // 1 arg only
{ {
_os << second[0] << ")" ; _os << second[0] << ")" ;
return _os; return _os;
} }
// and here more than 1 arg // and here more than 1 arg
for (unsigned i=0; i<narg-1; i++) for (unsigned i=0; i<narg-1; i++)
_os << second[i] << "," ; _os << second[i] << "," ;
_os << second[narg-1] << ")"; _os << second[narg-1] << ")";
return _os; return _os;
} }
std::istream & readFrom(std::istream & _is) std::istream & readFrom(std::istream & _is)
{ {
std::string value; std::string value;
_is >> value; _is >> value;
readFrom(value); readFrom(value);
return _is; return _is;
} }
void readFrom(std::string & _value) void readFrom(std::string & _value)
{ {
second.resize(0); // just in case second.resize(0); // just in case
size_t pos = _value.find('('); size_t pos = _value.find('(');
if (pos >= _value.size()) // no arguments if (pos >= _value.size()) // no arguments
{ {
first = _value; first = _value;
return; return;
} }
// so here we do have arguments // so here we do have arguments
std::string t = _value.substr(pos+1);// the arguments std::string t = _value.substr(pos+1);// the arguments
_value.resize(pos); _value.resize(pos);
first = _value; // done for the keyword (NOTE: may be empty std::string!) first = _value; // done for the keyword (NOTE: may be empty std::string!)
// now all arguments // now all arguments
std::string delim(" (),"); std::string delim(" (),");
while ( (pos=t.find_first_not_of(delim)) < t.size()) while ( (pos=t.find_first_not_of(delim)) < t.size())
{ {
size_t posEnd = t.find_first_of(delim, pos); size_t posEnd = t.find_first_of(delim, pos);
std::string u = t.substr(pos,posEnd);//(t, pos); std::string u = t.substr(pos,posEnd);//(t, pos);
/*u.resize(posEnd - pos);*/ /*u.resize(posEnd - pos);*/
second.push_back(u); second.push_back(u);
t = t.substr(posEnd+1); t = t.substr(posEnd+1);
} }
} }
}; };
// at the moment, the following are defined in eoParser.cpp // at the moment, the following are defined in eoParser.cpp

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoParser.cpp // eoParser.cpp
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000 // (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -31,7 +31,7 @@
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include <utils/compatibility.h> #include <utils/compatibility.h>
@ -49,8 +49,8 @@ std::ostream& printSectionHeader(std::ostream& os, std::string section)
if (section == "") if (section == "")
section = "General"; section = "General";
os << '\n' << setw(10) << "###### " << setw(20) << section << setw(10) << " ######\n"; os << '\n' << setw(10) << "###### " << setw(20) << section << setw(10) << " ######\n";
return os; return os;
} }
eoParameterLoader::~eoParameterLoader() eoParameterLoader::~eoParameterLoader()
@ -62,102 +62,62 @@ eoParameterLoader::~eoParameterLoader()
} }
eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription, string _lFileParamName, char _shortHand) : eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription,
programName( _argv[0]), string _lFileParamName, char _shortHand) :
programDescription( _programDescription), programName(_argv[0]),
programDescription( _programDescription),
needHelp(false, "help", "Prints this message", 'h'), needHelp(false, "help", "Prints this message", 'h'),
stopOnUnknownParam(true, "stopOnUnknownParam", "Stop if unkown param entered", '\0') stopOnUnknownParam(true, "stopOnUnknownParam", "Stop if unkown param entered", '\0')
{ {
// need to process the param file first // need to process the param file first
// if we want command-line to have highest priority // if we want command-line to have highest priority
unsigned i; unsigned i;
for (i = 1; i < _argc; ++i) for (i = 1; i < _argc; ++i)
{ {
if (_argv[i][0] == '@') if(_argv[i][0] == '@')
{ // read response file { // read response file
char *pts = _argv[i]+1; // yes a char*, sorry :-) char *pts = _argv[i]+1; // yes a char*, sorry :-)
ifstream ifs (pts); ifstream ifs (pts);
ifs.peek(); // check if it exists ifs.peek(); // check if it exists
if (!ifs) if (!ifs)
{ {
string msg = (string)("Could not open response file: ") + pts; string msg = string("Could not open response file: ") + pts;
throw runtime_error(msg); throw runtime_error(msg);
} }
// read - will be overwritten by command-line // read - will be overwritten by command-line
readFrom(ifs); readFrom(ifs);
break; // stop reading command line args for '@' break; // stop reading command line args for '@'
} }
} }
// now read arguments on command-line // now read arguments on command-line
#ifdef HAVE_SSTREAM #ifdef HAVE_SSTREAM
stringstream stream; stringstream stream;
#else #else
strstream stream; strstream stream;
#endif #endif
for (i = 1; i < _argc; ++i) for (i = 1; i < _argc; ++i)
{ {
stream << _argv[i] << '\n'; stream << _argv[i] << '\n';
} }
readFrom(stream); readFrom(stream);
processParam(needHelp); processParam(needHelp);
processParam(stopOnUnknownParam); processParam(stopOnUnknownParam);
} }
/**
* get a handle on a param from its longName
* eoParam * eoParser::getParamWithLongName(const std::string& _name) const
* if not found, returns 0 (null pointer :-)
*
* Not very clean (requires hard-coding of the long name twice!)
* but very useful in many occasions...
*/
eoParam* eoParser::getParamWithLongName(std::string _name)
{ {
typedef std::multimap<std::string, eoParam*> MultiMapType; typedef std::multimap<std::string, eoParam*> MultiMapType;
typedef MultiMapType::const_iterator It; typedef MultiMapType::const_iterator iter;
for (It p = params.begin(); p != params.end(); ++p) std::string search(prefix+_name);
{ for(iter p = params.begin(); p != params.end(); ++p)
if (p->second->longName() == prefix+_name) if(p->second->longName() == search)
return p->second; return p->second;
} return 0;
return 0;
} }
/** it seems finally that the easiest use of the above method is
through the following, whose interface is similar to that of the
widely-used createParam
For some (probably very stupid) reason, I failed to put it in
the .cpp. Any hint???
*/
/*
template <class ValueType>
eoValueParam<ValueType>& eoParser::getORcreateParam (
ValueType _defaultValue,
std::string _longName,
std::string _description,
char _shortHand,
std::string _section,
bool _required)
{
eoParam* ptParam = getParamWithLongName(_longName);
if (ptParam) { // found
eoValueParam<ValueType>* ptTypedParam =
dynamic_cast<eoValueParam<ValueType>*>(ptParam);
return *ptTypedParam;
}
// not found -> create it
return createParam (_defaultValue, _longName, _description,
_shortHand, _section, _required);
}
*/
void eoParser::processParam(eoParam& param, std::string section) void eoParser::processParam(eoParam& param, std::string section)
{ {
@ -210,7 +170,7 @@ pair<bool, string> eoParser::getValue(eoParam& _param) const
result.second = it->second; result.second = it->second;
result.first = true; result.first = true;
return result; return result;
} }
// else (TODO: check environment, just long names) // else (TODO: check environment, just long names)
return result; return result;
@ -256,7 +216,7 @@ void eoParser::readFrom(istream& is)
{ {
string::iterator equalLocation = find(str.begin() + 2, str.end(), '='); string::iterator equalLocation = find(str.begin() + 2, str.end(), '=');
string value; string value;
if (equalLocation == str.end()) if (equalLocation == str.end())
{ // TODO: it should be the next string { // TODO: it should be the next string
value = ""; value = "";
@ -306,7 +266,7 @@ void eoParser::printOn(ostream& os) const
printSectionHeader(os, section); printSectionHeader(os, section);
//print every param with its value //print every param with its value
for (; p != params.end(); ++p) for (; p != params.end(); ++p)
{ {
std::string newSection = p->first; std::string newSection = p->first;
@ -315,14 +275,14 @@ void eoParser::printOn(ostream& os) const
section = newSection; section = newSection;
printSectionHeader(os, section); printSectionHeader(os, section);
} }
eoParam* param = p->second; eoParam* param = p->second;
if (!isItThere(*param)) // comment out the ones not set by the user if (!isItThere(*param)) // comment out the ones not set by the user
os << "# "; os << "# ";
string str = "--" + param->longName() + "=" + param->getValue(); string str = "--" + param->longName() + "=" + param->getValue();
os.setf(ios_base::left, ios_base::adjustfield); os.setf(ios_base::left, ios_base::adjustfield);
os << setw(40) << str; os << setw(40) << str;
@ -330,7 +290,7 @@ void eoParser::printOn(ostream& os) const
if (param->shortName()) if (param->shortName())
os << '-' << param->shortName() << " : "; os << '-' << param->shortName() << " : ";
os << param->description(); os << param->description();
if (param->required()) if (param->required())
{ {
os << " REQUIRED "; os << " REQUIRED ";
@ -340,7 +300,7 @@ void eoParser::printOn(ostream& os) const
} }
} }
void eoParser::printHelp(ostream& os) void eoParser::printHelp(ostream& os)
{ {
if (needHelp.value() == false && !messages.empty()) if (needHelp.value() == false && !messages.empty())
{ {
@ -355,7 +315,7 @@ void eoParser::printHelp(ostream& os)
// print the usage when calling the program from the command line // print the usage when calling the program from the command line
os << "Usage: "<< programName<<" [Options]\n"; os << "Usage: "<< programName<<" [Options]\n";
// only short usage! // only short usage!
os << "Options of the form \"-f[=Value]\" or \"--Name[=value]\"" << endl; os << "Options of the form \"-f[=Value]\" or \"--Name[=value]\"" << endl;
os << "Where:"<<endl; os << "Where:"<<endl;
@ -368,7 +328,7 @@ void eoParser::printHelp(ostream& os)
printSectionHeader(os, section); printSectionHeader(os, section);
//print every param with its value //print every param with its value
for (; p != params.end(); ++p) for (; p != params.end(); ++p)
{ {
std::string newSection = p->first; std::string newSection = p->first;
@ -383,7 +343,7 @@ void eoParser::printHelp(ostream& os)
os << "--" <<p->second->longName() <<":\t" os << "--" <<p->second->longName() <<":\t"
<< p->second->description() ; << p->second->description() ;
os << "\n" << setw(20) << ( (p->second->required())?"Required":"Optional" ); os << "\n" << setw(20) << ( (p->second->required())?"Required":"Optional" );
os <<". By default: "<<p->second->defValue() << '\n'; os <<". By default: "<<p->second->defValue() << '\n';
} // for p } // for p
@ -393,10 +353,10 @@ void eoParser::printHelp(ostream& os)
} }
bool eoParser::userNeedsHelp(void) bool eoParser::userNeedsHelp(void)
{ {
/* /*
check whether there are long or short names entered check whether there are long or short names entered
without a corresponding parameter without a corresponding parameter
*/ */
// first, check if we want to check that ! // first, check if we want to check that !
@ -445,18 +405,18 @@ bool eoParser::userNeedsHelp(void)
} }
} }
} }
return needHelp.value() || !messages.empty(); return needHelp.value() || !messages.empty();
} }
///////////////// I put these here at the moment ///////////////// I put these here at the moment
ostream & operator<<(ostream & _os, const eoParamParamType & _rate) ostream & operator<<(ostream & _os, const eoParamParamType & _rate)
{ {
_rate.printOn(_os); _rate.printOn(_os);
return _os; return _os;
} }
istream & operator>>(istream & _is, eoParamParamType & _rate) istream & operator>>(istream & _is, eoParamParamType & _rate)
{ {
_rate.readFrom(_is); _rate.readFrom(_is);
return _is; return _is;
} }

View file

@ -3,7 +3,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// eoParser.h // eoParser.h
// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000 // (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000
/* /*
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
@ -24,12 +24,13 @@
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** /**
CVS Info: $Date: 2004-04-05 15:28:12 $ $Version$ $Author: evomarc $ CVS Info: $Date: 2005-08-29 07:50:50 $ $Version$ $Author: kuepper $
*/ */
#ifndef eoParser_h #ifndef eoParser_h
#define eoParser_h #define eoParser_h
#include <map> #include <map>
#include <sstream>
#include <string> #include <string>
#include "eoParam.h" #include "eoParam.h"
@ -37,64 +38,68 @@ CVS Info: $Date: 2004-04-05 15:28:12 $ $Version$ $Author: evomarc $
#include "eoPersistent.h" #include "eoPersistent.h"
/** /**
eoParameterLoader is an abstract class that can be used as a base for your own eoParameterLoader is an abstract class that can be used as a base for your own
parameter loading and saving. The command line parser eoParser is derived from parameter loading and saving. The command line parser eoParser is derived from
this class. this class.
*/ */
class eoParameterLoader class eoParameterLoader
{ {
public : public :
/** Need a virtual destructor */ /** Need a virtual destructor */
virtual ~eoParameterLoader(); virtual ~eoParameterLoader();
/** /**
* processParam is used to register a parameter and set its value if it is known * processParam is used to register a parameter and set its value if it is known
* *
* @param param the parameter to process * @param param the parameter to process
* @param section the section where this parameter belongs * @param section the section where this parameter belongs
*/ */
virtual void processParam(eoParam& param, std::string section = "") = 0; virtual void processParam(eoParam& param, std::string section = "") = 0;
/** /**
* checks if _param has been actually entered * checks if _param has been actually entered
*/ */
virtual bool isItThere(eoParam& _param) const = 0; virtual bool isItThere(eoParam& _param) const = 0;
/** /**
* Construct a Param and sets its value. The loader will own the memory thus created * Construct a Param and sets its value. The loader will own the memory thus created
* *
* @param _defaultValue The default value * @param _defaultValue The default value
* @param _longName Long name of the argument * @param _longName Long name of the argument
* @param _description Description of the parameter. What is useful for. * @param _description Description of the parameter. What is useful for.
* @param _shortName Short name of the argument (Optional) * @param _shortName Short name of the argument (Optional)
* @param _section Name of the section where the parameter belongs * @param _section Name of the section where the parameter belongs
* @param _required If it is a necessary parameter or not * @param _required If it is a necessary parameter or not
*/ */
template <class ValueType> template <class ValueType>
eoValueParam<ValueType>& createParam eoValueParam<ValueType>& createParam
(ValueType _defaultValue, (ValueType _defaultValue,
std::string _longName, std::string _longName,
std::string _description, std::string _description,
char _shortHand = 0, char _shortHand = 0,
std::string _section = "", std::string _section = "",
bool _required = false) bool _required = false)
{ {
eoValueParam<ValueType>* p = new eoValueParam<ValueType>(_defaultValue, _longName, _description, _shortHand, _required); eoValueParam<ValueType>* p = new eoValueParam<ValueType>(_defaultValue,
_longName,
_description,
_shortHand,
_required);
ownedParams.push_back(p); ownedParams.push_back(p);
processParam(*p, _section); processParam(*p, _section);
return *p; return *p;
} }
private : private :
std::vector<eoParam*> ownedParams; std::vector<eoParam*> ownedParams;
}; };
/** /**
eoParser: command line parser and configuration file reader eoParser: command line parser and configuration file reader
This class is persistent, so it can be stored and reloaded to restore This class is persistent, so it can be stored and reloaded to restore
@ -109,6 +114,7 @@ public:
* Constructor * Constructor
* a complete constructor that reads the command line an optionally reads * a complete constructor that reads the command line an optionally reads
* a configuration file. * a configuration file.
* *
* myEo --param-file=param.rc will then load using the parameter file param.rc * myEo --param-file=param.rc will then load using the parameter file param.rc
* *
@ -118,9 +124,9 @@ public:
* @param _lFileParamName Name of the parameter specifying the configuration file (--param-file) * @param _lFileParamName Name of the parameter specifying the configuration file (--param-file)
* @param _shortHand Single charachter shorthand for specifying the configuration file * @param _shortHand Single charachter shorthand for specifying the configuration file
*/ */
eoParser ( unsigned _argc, char **_argv , std::string _programDescription = "", eoParser ( unsigned _argc, char **_argv , std::string _programDescription = "",
std::string _lFileParamName = "param-file", char _shortHand = 'p'); std::string _lFileParamName = "param-file", char _shortHand = 'p');
/** /**
Processes the parameter and puts it in the appropriate section for readability Processes the parameter and puts it in the appropriate section for readability
*/ */
@ -129,12 +135,12 @@ public:
void readFrom(std::istream& is); void readFrom(std::istream& is);
void printOn(std::ostream& os) const; void printOn(std::ostream& os) const;
/// className for readibility /// className for readibility
std::string className(void) const { return "Parser"; } std::string className(void) const { return "Parser"; }
/// true if the user made an error or asked for help /// true if the user made an error or asked for help
bool userNeedsHelp(void); bool userNeedsHelp(void);
/** /**
* Prints an automatic help in the specified output using the information * Prints an automatic help in the specified output using the information
* provided by parameters * provided by parameters
@ -142,79 +148,112 @@ public:
void printHelp(std::ostream& os); void printHelp(std::ostream& os);
std::string ProgramName() { return programName; } std::string ProgramName() { return programName; }
/** /**
* checks if _param has been actually entered by the user * checks if _param has been actually entered by the user
*/ */
virtual bool isItThere(eoParam& _param) const virtual bool isItThere(eoParam& _param) const
{ return getValue(_param).first; } { return getValue(_param).first; }
/** /**
* get a handle on a param from its longName * get a handle on a param from its longName
* *
* if not found, returns 0 (null pointer :-) * if not found, returns 0 (null pointer :-)
* *
* Not very clean (requires hard-coding of the long name twice!) * Not very clean (requires hard-coding of the long name twice!)
* but very useful in many occasions... * but very useful in many occasions...
*/ */
eoParam* getParamWithLongName(std::string _name); eoParam * getParamWithLongName(const std::string& _name) const;
/** it seems finally that the easiest use of the above method is
through the following, whose interface is similar to that of the
widely-used createParam /** Get or create parameter
For some (probably very stupid) reason, I failed to put it in
the .cpp. Any hint??? It seems finally that the easiest use of the above method is
*/ through the following, whose interface is similar to that of the
widely-used createParam.
For some (probably very stupid) reason, I failed to put it in the
.cpp. Any hint???
*/
template <class ValueType> template <class ValueType>
eoValueParam<ValueType>& getORcreateParam eoValueParam<ValueType>& getORcreateParam(ValueType _defaultValue,
(ValueType _defaultValue, std::string _longName,
std::string _longName, std::string _description,
std::string _description, char _shortHand = 0,
char _shortHand = 0, std::string _section = "",
std::string _section = "", bool _required = false)
bool _required = false) {
{ eoParam* ptParam = getParamWithLongName(_longName);
eoParam* ptParam = getParamWithLongName(_longName); if (ptParam) {
if (ptParam) { // found // found
eoValueParam<ValueType>* ptTypedParam = eoValueParam<ValueType>* ptTypedParam =
dynamic_cast<eoValueParam<ValueType>*>(ptParam); dynamic_cast<eoValueParam<ValueType>*>(ptParam);
return *ptTypedParam; return *ptTypedParam;
} }
// not found -> create it // not found -> create it
return createParam (_defaultValue, _longName, _description, return createParam (_defaultValue, _longName, _description,
_shortHand, _section, _required); _shortHand, _section, _required);
} }
// /** accessors to the stopOnUnknownParam value */
void setStopOnUnknownParam(bool _b) {stopOnUnknownParam.value()=_b;}
bool getStopOnUnknownParam() {return stopOnUnknownParam.value();}
/** Prefix handling */
void setPrefix(const std:: string & _prefix) {prefix = _prefix;} /** Make sure parameter has specific value
This requires that operator<< is defined for ValueType.
*/
template <class ValueType>
void setORcreateParam(ValueType _defaultValue, std::string _longName,
std::string _description, char _shortHand = 0,
std::string _section = "", bool _required = false)
{
eoParam *param = getParamWithLongName(_longName);
if(0 == param) {
createParam(_defaultValue, _longName, _description,
_shortHand, _section, _required);
} else {
#ifdef HAVE_SSTREAM
std::ostringstream os;
#else
std::ostrstream os;
#endif
os << _defaultValue;
dynamic_cast<eoValueParam<int> *>(param)->setValue(os.str());
}
}
/** accessors to the stopOnUnknownParam value */
void setStopOnUnknownParam(bool _b) {stopOnUnknownParam.value()=_b;}
bool getStopOnUnknownParam() {return stopOnUnknownParam.value();}
/** Prefix handling */
void setPrefix(const std:: string & _prefix) {prefix = _prefix;}
void resetPrefix() {prefix = "";} void resetPrefix() {prefix = "";}
std::string getPrefix() {return prefix;} std::string getPrefix() {return prefix;}
private: private:
void doRegisterParam(eoParam& param) const; void doRegisterParam(eoParam& param) const;
std::pair<bool, std::string> getValue(eoParam& _param) const; std::pair<bool, std::string> getValue(eoParam& _param) const;
void updateParameters() const; void updateParameters() const;
typedef std::multimap<std::string, eoParam*> MultiMapType; typedef std::multimap<std::string, eoParam*> MultiMapType;
// used to store all parameters that are processed // used to store all parameters that are processed
MultiMapType params; MultiMapType params;
std::string programName; std::string programName;
std::string programDescription; std::string programDescription;
typedef std::map<char, std::string> ShortNameMapType; typedef std::map<char, std::string> ShortNameMapType;
ShortNameMapType shortNameMap; ShortNameMapType shortNameMap;
typedef std::map<std::string, std::string> LongNameMapType; typedef std::map<std::string, std::string> LongNameMapType;
LongNameMapType longNameMap; LongNameMapType longNameMap;