diff --git a/eo/src/Makefile.am b/eo/src/Makefile.am index 23f08b5ce..3b4a1c90e 100644 --- a/eo/src/Makefile.am +++ b/eo/src/Makefile.am @@ -5,20 +5,22 @@ ############################################################################### lib_LIBRARIES = libeo.a -libeo_a_SOURCES = eoPrintable.cpp eoPersistent.cpp +libeo_a_SOURCES = eoPrintable.cpp eoPersistent.cpp eoParserUtils.cpp libeoincdir = $(includedir)/eo libeoinc_HEADERS = EO.h eo eo1d.h eo2d.h eo2dVector.h eoAged.h eoAlgo.h\ eoAtomBitFlip.h eoAtomCreep.h eoAtomMutation.h eoAtomMutator.h \ eoAtomRandom.h eoBin.h eoBitOp.h eoBitOpFactory.h eoBreeder.h\ - eoData.h eoDetTournament.h eoDup.h eoESChrom.h eoESFullChrom.h eoESFullMut.h eoEasyEA.h\ + eoData.h eoDetTournament.h eoDup.h eoESChrom.h eoESFullChrom.h \ + eoESFullMut.h eoEasyEA.h\ eoEvalFunc.h eoEvalFuncPtr.h eoFitTerm.h eoFitness.h\ eoGenTerm.h eoGeneration.h eoID.h eoInclusion.h eoInsertion.h\ - eoKill.h eoLottery.h eoMerge.h eoMultiBinOp.h eoMultiMonOp.h eoMutation.h eoNegExp.h\ + eoKill.h eoLottery.h eoMerge.h eoMultiBinOp.h eoMultiMonOp.h \ + eoMutation.h eoNegExp.h\ eoNonUniform.h eoNormal.h eoObject.h eoOp.h eoOpSelector.h\ eoParser.h eoPersistent.h eoPop.h eoPopOps.h eoPrintable.h\ eoProblem.h eoProportionalOpSel.h eoRNG.h eoRnd.h eoString.h\ eoStochTournament.h eoTerm.h eoTranspose.h eoUniform.h \ - eoUniformSelect.h eoUniformXOver.h eoVector.h eoXOver2.h - + eoUniformSelect.h eoUniformXOver.h eoVector.h eoXOver2.h \ + eoParserUtils.h diff --git a/eo/src/eoParser.h b/eo/src/eoParser.h index 7e110f4e8..ac6034bda 100644 --- a/eo/src/eoParser.h +++ b/eo/src/eoParser.h @@ -1,847 +1,820 @@ -// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - -//----------------------------------------------------------------------------- -/* eoParser.h - some classes to parser either the command line or a parameter file - - (c) Marc Schoenauer and Geneura team, 1999 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Contact: todos@geneura.ugr.es, http://geneura.ugr.es - */ -//----------------------------------------------------------------------------- - -#ifndef _PARSER_H -#define _PARSER_H - -#include // for strcasecmp ... maybe there's a c++ way of doing it? -#ifdef _MSC_VER -#define strcasecmp(a,b) _strnicmp(a,b,strlen(a)) -#endif - -// STL includes -#include -#include -#include -#include -#include -#include - -//----------------------------------------------------------------------------- -// Class UExceptions - probably useless ??? -//----------------------------------------------------------------------------- -/** - * This class manages exceptions. Itīs barely an extension of the standard except -ion, - * but it can be initialized with an STL string. Called UException (utils-except -ion)+ - * to avoid conflicts with other classes. - */ -class UException: public exception { - public: - /// - UException( const string& _msg ): msg( _msg ) { }; - - /// - virtual const char* what() const { return msg.c_str(); }; - - private: - string msg; -}; - - -//----------------------------------------------------------------------------- -// Class Param -//----------------------------------------------------------------------------- - -/** - * A param repesents an argument that can be passed to a program in the command line - */ -class Param { -public: - - /** - * Type of params - */ - enum valueType { INT, UL, FLOAT, STRING, BOOL, ARRAY, TITLE }; - - /** - * Construct an Param. - * @param _shortName Short name of the argument - * @param _longName Long name of the argument - * @param _default The default value - * @param _valueType Type of the parameter ("integer","unsigned long", "float","char", "bool" and so on) - * @param _description Description of the parameter. What is useful for. - * @param _required If it is a necessary parameter or not - */ - Param (string _shortName="-h", string _longName="--help", - string _default = "", valueType _valType= STRING, - string _description="Shows this help", - bool _required=false ) - : repShortName(_shortName), repLongName(_longName), - repDescription(_description ), repEnv(""), repDefault(_default), - repValue(_default), repValType( _valType), - repRequired( _required), repChanged(false) { - - const char *c = repLongName.c_str(); - for(unsigned i=0; i getArray (const string& _shortName, const string& _longName, - const string& _default = "", - const string& _description="", bool _required=false) { - Param param ( _shortName, _longName, _default, Param::ARRAY, _description, _required ); - parse( param ); - params.push_back( param ); - - istrstream is(param.value().c_str()); - vector retValue; - string tmpStr; - - is >> tmpStr; - while(is){ - retValue.push_back(tmpStr); - is >> tmpStr; - } - return retValue; - }; - - /** - * Gets the int value of a param given the full description of the parameter - * @param see above - * @exception BadType if the param's value isn't a correct int - */ - - int getInt (const string& _shortName, const string& _longName, - const string& _default = "", - const string& _description="", bool _required=false) { - Param param ( _shortName, _longName, _default, Param::INT, _description, _required ); - parse( param ); - params.push_back( param ); - - // now gets the value - istrstream is( param.value().c_str()); - int retValue; - is >> retValue; - - if (!is) { - throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float"); - return 0; - } else { - return retValue; - } - }; - - /** - * Gets the unsigned lon value of a param given ... - * @param see above - * @exception BadType if the param's value isn't a correct unsigned long - */ - - int getUnsignedLong (const string& _shortName, const string& _longName, - const string& _default = "", - const string& _description="", bool _required=false) { - Param param ( _shortName, _longName, _default, Param::UL, _description, _required ); - parse( param ); - params.push_back( param ); - - // now gets the value - istrstream is( param.value().c_str()); - unsigned long retValue; - is >> retValue; - - if (!is) { - throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float"); - return 0; - } else { - return retValue; - } - }; - - /** - * Gets the float value of a param given the description of the parameter - * @param see above - * @exception BadType if the param's value isn't a correct int - */ - - float getFloat (const string& _shortName, const string& _longName, - const string& _default = "", - const string& _description="", bool _required=false) { - Param param ( _shortName, _longName, _default, Param::FLOAT, _description, _required ); - parse( param ); - params.push_back( param ); - - // now gets the value - istrstream is( param.value().c_str()); - float retValue; - is >> retValue; - - if (!is) { - throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float"); - return 0; - } else { - return retValue; - } - }; - - - string parse_string (istream & _is) { - string paramValue; - _is >> paramValue; - //if the first character of the string or array is not a " => just one word or array-element. - if( paramValue[0] != '\"' ) - return paramValue; - - if( paramValue[1] == '\"' ) // the empty string - return "" ; - - //else => read until the next " (the end of the string). - const char *c = paramValue.c_str(); - string tmpStr = c+1;// skip the " - if (tmpStr[tmpStr.length()-1] == '\"') { // one word only - tmpStr[tmpStr.length()-1] = '\0'; - return tmpStr; - } - - bool stop = false; - while (_is && !stop) { - _is >> paramValue; - // test last character of paramValue for " - if (paramValue[paramValue.length()-1] == '\"') { - paramValue[paramValue.length()-1] = '\0'; - stop = true; - } - tmpStr = tmpStr + " " + paramValue ; - } - return tmpStr; - }; - - - void parse (Param & param) { - int i; - string tmpStr, ReadStr, FirstWord; - - // FIRST: look if the associated environment variables have any value, to use them. - if( getenv( param.environment().c_str() ) ) { - //cout <<"\t\t ENV param: ,"<shortName()<<", ,"<environment().c_str())<> tmpStr; - if ( ( !strcmp(tmpStr.c_str(), param.shortName().c_str()) ) || - ( !strcasecmp(tmpStr.c_str(), param.longName().c_str()) ) - ) { // found the keyword - - Param::valueType tmp = param.valType(); - switch ( tmp ) { - case Param::TITLE: - cerr << "Error, we should not be there" << endl; - exit(1); - break; - case Param::BOOL : - param.value("true" ); - break; - - case Param::INT: - case Param::UL: - case Param::FLOAT: - is >> tmpStr; - param.value(tmpStr); - break; - - case Param::STRING: - tmpStr = parse_string(is); - param.value(tmpStr); - break; - - case Param::ARRAY: - ReadStr = parse_string(is); - if ( ReadStr != "<" ) { // no "<" ">" --> a single string in the array - param.value(ReadStr); - break; - } - // read next word - and keep it in case of <> mismatch - FirstWord = parse_string(is); - // test for empty array - if (FirstWord == ">") { - param.value(""); - break; - } - // else, read all words until ">" - tmpStr = FirstWord; - ReadStr = parse_string(is); - while ( is && (ReadStr != ">") ) { - tmpStr = tmpStr + " " + ReadStr; - ReadStr = parse_string(is); - } - - if (!is) { // there was a "<" without the corresponding ">" - throw Parser::BadArrayParam( param.longName(), FirstWord ); - param.value(FirstWord); // assume unique string - } - else - param.value(tmpStr); - break; - } - } - } - } - - - // LAST (highest priority) parse the command line arguments - for (i=1 ; i" --> a single string in the array - param.value(ReadStr); - }else{ - // read next word - and keep it in case of <> mismatch - FirstWord = parse_argv[i++]; - - // test for empty array - if (FirstWord == ">") { - param.value(""); - }else{ - // else, read all words until ">" - tmpStr = FirstWord; - ReadStr = parse_argv[i++]; - while ( (i=parse_argc) && (ReadStr != ">") ) { // there was a "<" without the corresponding ">" - throw Parser::BadArrayParam( param.longName(), FirstWord ); - param.value(FirstWord); // assume unique string - }else{ - param.value(tmpStr); - } - } - } - } - } - break; - } - - //MS after trying all possibilities, and if the value has not changed - // though the parameter was required, protest! - if (param.required() && !param.changed()) - throw Parser::MissingReqParam(param.shortName()); - - }; - - /** - * Sets a new value for a param given its short name or its long name. - * @param _name One of the names of the param. - * @param _value Value to be assigned. - * @exception UnknownArg if the param doesn't exist - * @exception MissingVal if the param hasn't got a value - */ - Param::valueType setParamValue (const string& _name, const char* _value){ - vector::iterator pos; - - for (pos=params.begin() ; pos!=params.end() ; pos++) - if (pos->shortName()==_name || pos->longName()==_name) - break; - - // if found ... - if (pos!=params.end()) { - switch ( pos->valType() ) { - case Param::TITLE: - cerr << "Error, we should not be there" << endl; - exit(1); - break; - case Param::BOOL : - pos->value("true"); - break; - case Param::ARRAY : - case Param::INT: - case Param::UL: - case Param::FLOAT: - case Param::STRING: - if (_value != NULL){ - pos->value(_value); - }else{ - throw Parser::MissingVal(_name); - return Param::BOOL; - } - break; - } // switch - - return pos->valType(); - - }else{ - throw Parser::UnknownArg(_name); - return Param::BOOL; - } - }; - - /// the output method - generate the .status file (unless other name is given) - friend ostream & operator<< ( ostream & os, Parser & _parser ) - { - vector::iterator p; - //print every param with its value - for ( p=_parser.params.begin(); p!=_parser.params.end(); p++ ) { - switch ( p->valType() ) { - case Param::BOOL : - if(p->value() == "true") - os << p->longName(); - else - os << "#" << p->longName() ; // so the name of the bool is commented out - break; - - case Param::INT: - case Param::UL: - case Param::FLOAT: - os << p->longName()<<" "<value(); - break; - - case Param::ARRAY : - os << p->longName() << " < " << p->value().c_str() << " >" ; - break; - case Param::STRING: - os << p->longName()<<" \""<value().c_str()<<"\" "; - break; - case Param::TITLE: - os << endl; // Title is in the description below - break; - } // switch - os << "\t #" << p->shortName() << " : " << p->description(); - if (p->valType() != Param::TITLE) - os << " [" << p->defValue() << "]" ; - os << endl; - } - return os; - }; - - /** - * Prints out the list of parameters in the output file (if specified) - */ - void outputParam(string _OutputFile="") - { - if (_OutputFile == "") { - _OutputFile = parse_argv[0]; - _OutputFile += ".status"; - } - - ofstream os(_OutputFile.c_str()); - os << "Parameters used by \"" << programName << "\" (" - << programDescription << ")" << endl << endl; - os << *this; - }; - - /** - * Prints an automatic help in the standard output using the information - * provided by parameters - */ - void printHelp() { - vector::iterator p; -// unsigned i; - - // print program name and description - cout << this->programName <<": "<valType() != Param::TITLE ) { -// if( p->valType() != Param::BOOL ){ -// cout << ( (!p->required())?"[":""); -// cout <shortName()<<" value"<required())?"]":"")<<" "; -// }else{ -// cout << "["<shortName()<<"] "; -// } -// } // for p - cout << "Where:"<valType() != Param::TITLE ) { - cout << p->shortName()<<","<longName()<<":\t"<description()<valType() ) { - case Param::INT: cout <<"Integer"; break; - case Param::UL: cout <<"Unsigned Long Integer"; break; - case Param::FLOAT: cout <<"Float"; break; - case Param::STRING: cout <<"String"; break; - case Param::ARRAY: cout <<"An array of strings, enclosed within < >"; break; - case Param::BOOL: cout << "Flag"; break; - case Param::TITLE: break; - } // switch - if(p->valType() == Param::BOOL) - cout << ") True if present" << endl; - else - cout<<") "<<( (p->required())?"Required":"Optional" )<<". By default: "<defValue()<description() << endl; - } - } // for p - cout << endl; - }; - - /** - * This class managges unknown argument exceptions. - */ - class UnknownArg : public UException { - public: - - /** - * Constructor - * @param _arg string to be shown when the exception occurs - */ - UnknownArg( const string& _arg): UException( "Invalid argument: "+_arg ) { }; - }; - - /** - * This class managges bad param types. - */ - class BadType : public UException { - public: - - /** - * Constructor - * @param _param The param - * @param _value The value of the param - */ - BadType(const string& _param, const string& _value, const string& _correctType) - : UException("The value '" + _value + "' assigned to the argument " + _param + " isn't a correct "+_correctType) { }; - }; - - /** - * This class managges exceptions produced when there isn't a value for a parameter. - */ - class MissingVal : public UException { - public: - - /** - * Constructor - * @param _param The param - */ - MissingVal(const string& _param) : UException("Missing value for parameter " + _param) {}; - }; - - /** - * This class managges exceptions produced when the user forgot a required parameter. - */ - class MissingReqParam : public UException { - public: - - /** - * Constructor - * @param _shortName The param's short name - */ - MissingReqParam(const string& _shortName) : UException("Missing required parameter " + _shortName) {}; - }; - - /** - * This class managges exceptions du to < without a > in array value - */ - class BadArrayParam : public UException { - public: - - /** - * Constructor - * @param _param The param - * @param _first_word The first word read after the "<" - */ - BadArrayParam(const string& _param, const string &_first_word) : - UException("Array parameter " + _param + ": No matching > (" + _first_word - + "... )") {}; - }; - -private: - vector params; - string programName; - string programDescription; - int parse_argc; - char **parse_argv; - string InputFileName; - -}; - -/// Reproducible random seed -// Maybe there is a better place for this subroutine (a separate .cpp?) -#include - -//---------------------------------- -void InitRandom( Parser & parser) { -//---------------------------------- - unsigned long _seed; - try { - _seed = parser.getUnsignedLong("-S", "--seed", "0", "Seed for Random number generator" ); - } - catch (UException & e) - { - cout << e.what() << endl; - parser.printHelp(); - exit(1); - } - - if (_seed == 0) { // use clock to get a "random" seed - _seed = (unsigned long)( time( 0 ) ); - ostrstream s; - s << _seed; - parser.setParamValue("--seed", s.str()); // so it will be printed out in the status file, and canbe later re-used to re-run EXACTLY the same run - } - rng.reseed(_seed); - - return; -} - - -#endif +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +/* eoParser.h + some classes to parser either the command line or a parameter file + + (c) Marc Schoenauer and Geneura team, 1999 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + */ +//----------------------------------------------------------------------------- + +#ifndef _PARSER_H +#define _PARSER_H + +#include // for strcasecmp ... maybe there's a c++ way of doing it? +#ifdef _MSC_VER +#define strcasecmp(a,b) _strnicmp(a,b,strlen(a)) +#endif + +// STL includes +#include +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +// Class UExceptions - probably useless ??? +//----------------------------------------------------------------------------- +/** + * This class manages exceptions. Itīs barely an extension of the standard except + ion, + * but it can be initialized with an STL string. Called UException (utils-except + ion)+ + * to avoid conflicts with other classes. + */ +class UException: public exception { +public: + /// + UException( const string& _msg ): msg( _msg ) { }; + + /// + virtual const char* what() const { return msg.c_str(); }; + +private: + string msg; +}; + + +//----------------------------------------------------------------------------- +// Class Param +//----------------------------------------------------------------------------- + +/** + * A param repesents an argument that can be passed to a program in the command line + */ +class Param { +public: + + /** + * Type of params + */ + enum valueType { INT, UL, FLOAT, STRING, BOOL, ARRAY, TITLE }; + + /** + * Construct an Param. + * @param _shortName Short name of the argument + * @param _longName Long name of the argument + * @param _default The default value + * @param _valueType Type of the parameter ("integer","unsigned long", "float","char", "bool" and so on) + * @param _description Description of the parameter. What is useful for. + * @param _required If it is a necessary parameter or not + */ + Param (string _shortName="-h", string _longName="--help", + string _default = "", valueType _valType= STRING, + string _description="Shows this help", + bool _required=false ) + : repShortName(_shortName), repLongName(_longName), + repDescription(_description ), repEnv(""), repDefault(_default), + repValue(_default), repValType( _valType), + repRequired( _required), repChanged(false) { + + const char *c = repLongName.c_str(); + for(unsigned i=0; i getArray (const string& _shortName, const string& _longName, + const string& _default = "", + const string& _description="", bool _required=false) { + Param param ( _shortName, _longName, _default, Param::ARRAY, _description, _required ); + parse( param ); + params.push_back( param ); + + istrstream is(param.value().c_str()); + vector retValue; + string tmpStr; + + is >> tmpStr; + while(is){ + retValue.push_back(tmpStr); + is >> tmpStr; + } + return retValue; + }; + + /** + * Gets the int value of a param given the full description of the parameter + * @param see above + * @exception BadType if the param's value isn't a correct int + */ + + int getInt (const string& _shortName, const string& _longName, + const string& _default = "", + const string& _description="", bool _required=false) { + Param param ( _shortName, _longName, _default, Param::INT, _description, _required ); + parse( param ); + params.push_back( param ); + + // now gets the value + istrstream is( param.value().c_str()); + int retValue; + is >> retValue; + + if (!is) { + throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float"); + return 0; + } else { + return retValue; + } + }; + + /** + * Gets the unsigned lon value of a param given ... + * @param see above + * @exception BadType if the param's value isn't a correct unsigned long + */ + + int getUnsignedLong (const string& _shortName, const string& _longName, + const string& _default = "", + const string& _description="", bool _required=false) { + Param param ( _shortName, _longName, _default, Param::UL, _description, _required ); + parse( param ); + params.push_back( param ); + + // now gets the value + istrstream is( param.value().c_str()); + unsigned long retValue; + is >> retValue; + + if (!is) { + throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float"); + return 0; + } else { + return retValue; + } + }; + + /** + * Gets the float value of a param given the description of the parameter + * @param see above + * @exception BadType if the param's value isn't a correct int + */ + + float getFloat (const string& _shortName, const string& _longName, + const string& _default = "", + const string& _description="", bool _required=false) { + Param param ( _shortName, _longName, _default, Param::FLOAT, _description, _required ); + parse( param ); + params.push_back( param ); + + // now gets the value + istrstream is( param.value().c_str()); + float retValue; + is >> retValue; + + if (!is) { + throw Parser::BadType(param.longName().c_str(), param.value().c_str(), "float"); + return 0; + } else { + return retValue; + } + }; + + + string parse_string (istream & _is) { + string paramValue; + _is >> paramValue; + //if the first character of the string or array is not a " => just one word or array-element. + if( paramValue[0] != '\"' ) + return paramValue; + + if( paramValue[1] == '\"' ) // the empty string + return "" ; + + //else => read until the next " (the end of the string). + const char *c = paramValue.c_str(); + string tmpStr = c+1;// skip the " + if (tmpStr[tmpStr.length()-1] == '\"') { // one word only + tmpStr[tmpStr.length()-1] = '\0'; + return tmpStr; + } + + bool stop = false; + while (_is && !stop) { + _is >> paramValue; + // test last character of paramValue for " + if (paramValue[paramValue.length()-1] == '\"') { + paramValue[paramValue.length()-1] = '\0'; + stop = true; + } + tmpStr = tmpStr + " " + paramValue ; + } + return tmpStr; + }; + + + void parse (Param & param) { + int i; + string tmpStr, ReadStr, FirstWord; + + // FIRST: look if the associated environment variables have any value, to use them. + if( getenv( param.environment().c_str() ) ) { + //cout <<"\t\t ENV param: ,"<shortName()<<", ,"<environment().c_str())<> tmpStr; + if ( ( !strcmp(tmpStr.c_str(), param.shortName().c_str()) ) || + ( !strcasecmp(tmpStr.c_str(), param.longName().c_str()) ) + ) { // found the keyword + + Param::valueType tmp = param.valType(); + switch ( tmp ) { + case Param::TITLE: + cerr << "Error, we should not be there" << endl; + exit(1); + break; + case Param::BOOL : + param.value("true" ); + break; + + case Param::INT: + case Param::UL: + case Param::FLOAT: + is >> tmpStr; + param.value(tmpStr); + break; + + case Param::STRING: + tmpStr = parse_string(is); + param.value(tmpStr); + break; + + case Param::ARRAY: + ReadStr = parse_string(is); + if ( ReadStr != "<" ) { // no "<" ">" --> a single string in the array + param.value(ReadStr); + break; + } + // read next word - and keep it in case of <> mismatch + FirstWord = parse_string(is); + // test for empty array + if (FirstWord == ">") { + param.value(""); + break; + } + // else, read all words until ">" + tmpStr = FirstWord; + ReadStr = parse_string(is); + while ( is && (ReadStr != ">") ) { + tmpStr = tmpStr + " " + ReadStr; + ReadStr = parse_string(is); + } + + if (!is) { // there was a "<" without the corresponding ">" + throw Parser::BadArrayParam( param.longName(), FirstWord ); + param.value(FirstWord); // assume unique string + } + else + param.value(tmpStr); + break; + } + } + } + } + + + // LAST (highest priority) parse the command line arguments + for (i=1 ; i" --> a single string in the array + param.value(ReadStr); + }else{ + // read next word - and keep it in case of <> mismatch + FirstWord = parse_argv[i++]; + + // test for empty array + if (FirstWord == ">") { + param.value(""); + }else{ + // else, read all words until ">" + tmpStr = FirstWord; + ReadStr = parse_argv[i++]; + while ( (i=parse_argc) && (ReadStr != ">") ) { // there was a "<" without the corresponding ">" + throw Parser::BadArrayParam( param.longName(), FirstWord ); + param.value(FirstWord); // assume unique string + }else{ + param.value(tmpStr); + } + } + } + } + } + break; + } + + //MS after trying all possibilities, and if the value has not changed + // though the parameter was required, protest! + if (param.required() && !param.changed()) + throw Parser::MissingReqParam(param.shortName()); + + }; + + /** + * Sets a new value for a param given its short name or its long name. + * @param _name One of the names of the param. + * @param _value Value to be assigned. + * @exception UnknownArg if the param doesn't exist + * @exception MissingVal if the param hasn't got a value + */ + Param::valueType setParamValue (const string& _name, const char* _value){ + vector::iterator pos; + + for (pos=params.begin() ; pos!=params.end() ; pos++) + if (pos->shortName()==_name || pos->longName()==_name) + break; + + // if found ... + if (pos!=params.end()) { + switch ( pos->valType() ) { + case Param::TITLE: + cerr << "Error, we should not be there" << endl; + exit(1); + break; + case Param::BOOL : + pos->value("true"); + break; + case Param::ARRAY : + case Param::INT: + case Param::UL: + case Param::FLOAT: + case Param::STRING: + if (_value != NULL){ + pos->value(_value); + }else{ + throw Parser::MissingVal(_name); + return Param::BOOL; + } + break; + } // switch + + return pos->valType(); + + }else{ + throw Parser::UnknownArg(_name); + return Param::BOOL; + } + }; + + /// the output method - generate the .status file (unless other name is given) + friend ostream & operator<< ( ostream & os, Parser & _parser ) + { + vector::iterator p; + //print every param with its value + for ( p=_parser.params.begin(); p!=_parser.params.end(); p++ ) { + switch ( p->valType() ) { + case Param::BOOL : + if(p->value() == "true") + os << p->longName(); + else + os << "#" << p->longName() ; // so the name of the bool is commented out + break; + + case Param::INT: + case Param::UL: + case Param::FLOAT: + os << p->longName()<<" "<value(); + break; + + case Param::ARRAY : + os << p->longName() << " < " << p->value().c_str() << " >" ; + break; + case Param::STRING: + os << p->longName()<<" \""<value().c_str()<<"\" "; + break; + case Param::TITLE: + os << endl; // Title is in the description below + break; + } // switch + os << "\t #" << p->shortName() << " : " << p->description(); + if (p->valType() != Param::TITLE) + os << " [" << p->defValue() << "]" ; + os << endl; + } + return os; + }; + + /** + * Prints out the list of parameters in the output file (if specified) + */ + void outputParam(string _OutputFile="") + { + if (_OutputFile == "") { + _OutputFile = parse_argv[0]; + _OutputFile += ".status"; + } + + ofstream os(_OutputFile.c_str()); + os << "Parameters used by \"" << programName << "\" (" + << programDescription << ")" << endl << endl; + os << *this; + }; + + /** + * Prints an automatic help in the standard output using the information + * provided by parameters + */ + void printHelp() { + vector::iterator p; + // unsigned i; + + // print program name and description + cout << this->programName <<": "<valType() != Param::TITLE ) { + // if( p->valType() != Param::BOOL ){ + // cout << ( (!p->required())?"[":""); + // cout <shortName()<<" value"<required())?"]":"")<<" "; + // }else{ + // cout << "["<shortName()<<"] "; + // } + // } // for p + cout << "Where:"<valType() != Param::TITLE ) { + cout << p->shortName()<<","<longName()<<":\t"<description()<valType() ) { + case Param::INT: cout <<"Integer"; break; + case Param::UL: cout <<"Unsigned Long Integer"; break; + case Param::FLOAT: cout <<"Float"; break; + case Param::STRING: cout <<"String"; break; + case Param::ARRAY: cout <<"An array of strings, enclosed within < >"; break; + case Param::BOOL: cout << "Flag"; break; + case Param::TITLE: break; + } // switch + if(p->valType() == Param::BOOL) + cout << ") True if present" << endl; + else + cout<<") "<<( (p->required())?"Required":"Optional" )<<". By default: "<defValue()<description() << endl; + } + } // for p + cout << endl; + }; + + /** + * This class managges unknown argument exceptions. + */ + class UnknownArg : public UException { + public: + + /** + * Constructor + * @param _arg string to be shown when the exception occurs + */ + UnknownArg( const string& _arg): UException( "Invalid argument: "+_arg ) { }; + }; + + /** + * This class managges bad param types. + */ + class BadType : public UException { + public: + + /** + * Constructor + * @param _param The param + * @param _value The value of the param + */ + BadType(const string& _param, const string& _value, const string& _correctType) + : UException("The value '" + _value + "' assigned to the argument " + _param + " isn't a correct "+_correctType) { }; + }; + + /** + * This class managges exceptions produced when there isn't a value for a parameter. + */ + class MissingVal : public UException { + public: + + /** + * Constructor + * @param _param The param + */ + MissingVal(const string& _param) : UException("Missing value for parameter " + _param) {}; + }; + + /** + * This class managges exceptions produced when the user forgot a required parameter. + */ + class MissingReqParam : public UException { + public: + + /** + * Constructor + * @param _shortName The param's short name + */ + MissingReqParam(const string& _shortName) : UException("Missing required parameter " + _shortName) {}; + }; + + /** + * This class managges exceptions du to < without a > in array value + */ + class BadArrayParam : public UException { + public: + + /** + * Constructor + * @param _param The param + * @param _first_word The first word read after the "<" + */ + BadArrayParam(const string& _param, const string &_first_word) : + UException("Array parameter " + _param + ": No matching > (" + _first_word + + "... )") {}; + }; + +private: + vector params; + string programName; + string programDescription; + int parse_argc; + char **parse_argv; + string InputFileName; + +}; + + + + +#endif diff --git a/eo/src/eoParserUtils.cpp b/eo/src/eoParserUtils.cpp new file mode 100644 index 000000000..f12b6b962 --- /dev/null +++ b/eo/src/eoParserUtils.cpp @@ -0,0 +1,32 @@ +// See eoParserUtils.h + +#include +#include +/// Reproducible random seed + +//---------------------------------- +void InitRandom( Parser & parser) { +//---------------------------------- + unsigned long _seed; + try { + _seed = parser.getUnsignedLong("-S", "--seed", "0", + "Seed for Random number generator" ); + } + catch (UException & e) + { + cout << e.what() << endl; + parser.printHelp(); + exit(1); + } + + if (_seed == 0) { // use clock to get a "random" seed + _seed = (unsigned long)( time( 0 ) ); + ostrstream s; + s << _seed; + parser.setParamValue("--seed", s.str()); // so it will be printed out in the status file, and canbe later re-used to re-run EXACTLY the same run + } + rng.reseed(_seed); + + return; +} + diff --git a/eo/src/eoParserUtils.h b/eo/src/eoParserUtils.h new file mode 100644 index 000000000..4bd8dc456 --- /dev/null +++ b/eo/src/eoParserUtils.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------- +File..........: eoParserUtils.h +Author........: Geneura Team, Marc Shoenauer + (this file: Victor Rivas, vrivas@ujaen.es) +Date..........: 17-Dec-1999 +Description...: Some useful things that use eoParser. +Modifications.: +------------------- 1 ------------------- + Author.......: + Date.........: + Description..: +*/ + +#ifndef EO_PARSER_UTILS +#define EO_PARSER_UTILS + +#include +#include +/// Reproducible random seed + +//---------------------------------- +void InitRandom( Parser & parser); +//---------------------------------- +#endif