eoparser.cpp
来自「这是linux下的进化计算的源代码。 === === === === ==」· C++ 代码 · 共 413 行
CPP
413 行
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-//-----------------------------------------------------------------------------// eoParser.cpp// (c) Marc Schoenauer, Maarten Keijzer and GeNeura Team, 2000/* 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 Marc.Schoenauer@inria.fr mkeijzer@dhi.dk *///-----------------------------------------------------------------------------#ifdef _MSC_VER#pragma warning(disable:4786)#endif#include <stdexcept>#include <algorithm>#include <fstream>#include <iomanip>#include <utils/compatibility.h>#include <utils/eoParser.h>using namespace std;void eoWarning(std::string str){ cout << str << '\n';}std::ostream& printSectionHeader(std::ostream& os, std::string section){ if (section == "") section = "General"; os << '\n' << setw(10) << "###### " << setw(20) << section << setw(10) << " ######\n"; return os;}eoParameterLoader::~eoParameterLoader(){ for (unsigned i = 0; i < ownedParams.size(); ++i) { delete ownedParams[i]; }}eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription, string _lFileParamName, char _shortHand) : programName(_argv[0]), programDescription( _programDescription), needHelp(false, "help", "Prints this message", 'h'), stopOnUnknownParam(true, "stopOnUnknownParam", "Stop if unkown param entered", '\0'){ // need to process the param file first // if we want command-line to have highest priority unsigned i; for (i = 1; i < _argc; ++i) { if(_argv[i][0] == '@') { // read response file char *pts = _argv[i]+1; // yes a char*, sorry :-) ifstream ifs (pts); ifs.peek(); // check if it exists if (!ifs) { string msg = string("Could not open response file: ") + pts; throw runtime_error(msg); } // read - will be overwritten by command-line readFrom(ifs); break; // stop reading command line args for '@' } } // now read arguments on command-line stringstream stream; for (i = 1; i < _argc; ++i) { stream << _argv[i] << '\n'; } readFrom(stream); processParam(needHelp); processParam(stopOnUnknownParam);}eoParam * eoParser::getParamWithLongName(const std::string& _name) const{ typedef std::multimap<std::string, eoParam*> MultiMapType; typedef MultiMapType::const_iterator iter; std::string search(prefix+_name); for(iter p = params.begin(); p != params.end(); ++p) if(p->second->longName() == search) return p->second; return 0;}void eoParser::processParam(eoParam& param, std::string section){ // this param enters the parser: add the prefix to the long name if (prefix != "") { param.setLongName(prefix+param.longName()); section = prefix + section; // and to section } doRegisterParam(param); // plainly register it params.insert(make_pair(section, ¶m));}void eoParser::doRegisterParam(eoParam& param) const{ if (param.required() && !isItThere(param)) { string msg = "Required parameter: " + param.longName() + " missing"; messages.push_back(msg); } pair<bool, string> value = getValue(param); if (value.first) { param.setValue(value.second); }}pair<bool, string> eoParser::getValue(eoParam& _param) const{ pair<bool, string> result(false, ""); if (_param.shortName() != 0) { map<char, string>::const_iterator it = shortNameMap.find(_param.shortName()); if (it != shortNameMap.end()) { result.second = it->second; result.first = true; return result; } } map<string, string>::const_iterator it = longNameMap.find(_param.longName()); if (it != longNameMap.end()) { result.second = it->second; result.first = true; return result; } // else (TODO: check environment, just long names) return result;}void eoParser::updateParameters() const{ typedef MultiMapType::const_iterator It; for (It p = params.begin(); p != params.end(); ++p) { doRegisterParam(*p->second); }}void eoParser::readFrom(istream& is){ string str; // we must avoid processing \section{xxx} if xxx is NOT "Parser" bool processing = true; while (is >> str) { if (str.find(string("\\section{"))==0) // found section begin processing = (str.find(string("Parser"))<str.size()); if (processing) // right \section (or no \section at all) { if (str[0] == '#') { // skip the rest of the line string tempStr; getline(is, tempStr); } if (str[0] == '-') { if (str.size() < 2) { eoWarning("Missing parameter"); needHelp.value() = true; return; } if (str[1] == '-') // two consecutive dashes { string::iterator equalLocation = find(str.begin() + 2, str.end(), '='); string value; if (equalLocation == str.end()) { // TODO: it should be the next string value = ""; } else { value = string(equalLocation + 1, str.end()); } string name(str.begin() + 2, equalLocation); longNameMap[name] = value; } else // it should be a char { string value = "1"; // flags do not need a special if (str.size() >= 2) { if (str[2] == '=') { if (str.size() >= 3) value = string(str.begin() + 3, str.end()); } else { value = string(str.begin() + 2, str.end()); } } shortNameMap[str[1]] = value; } } } } updateParameters();}void eoParser::printOn(ostream& os) const{ typedef MultiMapType::const_iterator It; It p = params.begin(); std::string section = p->first; printSectionHeader(os, section); //print every param with its value for (; p != params.end(); ++p) { std::string newSection = p->first; if (newSection != section) { section = newSection; printSectionHeader(os, section); } eoParam* param = p->second; if (!isItThere(*param)) // comment out the ones not set by the user os << "# "; string str = "--" + param->longName() + "=" + param->getValue(); os.setf(ios_base::left, ios_base::adjustfield); os << setw(40) << str; os << setw(0) << " # "; if (param->shortName()) os << '-' << param->shortName() << " : "; os << param->description(); if (param->required()) { os << " REQUIRED "; } os << '\n'; }}void eoParser::printHelp(ostream& os){ if (needHelp.value() == false && !messages.empty()) { std::copy(messages.begin(), messages.end(), ostream_iterator<string>(os, "\n")); messages.clear(); return; } // print program name and description os << this->programName <<": "<< programDescription << "\n\n"; // print the usage when calling the program from the command line os << "Usage: "<< programName<<" [Options]\n"; // only short usage! os << "Options of the form \"-f[=Value]\" or \"--Name[=value]\"" << endl; os << "Where:"<<endl; typedef MultiMapType::const_iterator It; It p = params.begin(); std::string section = p->first; printSectionHeader(os, section); //print every param with its value for (; p != params.end(); ++p) { std::string newSection = p->first; if (newSection != section) { section = newSection; printSectionHeader(os, section); } if (p->second->shortName()) os << "-" << p->second->shortName() << ", "; os << "--" <<p->second->longName() <<":\t" << p->second->description() ; os << "\n" << setw(20) << ( (p->second->required())?"Required":"Optional" ); os <<". By default: "<<p->second->defValue() << '\n'; } // for p os << "\n@param_file \t defines a file where the parameters are stored\n"; os << '\n';}bool eoParser::userNeedsHelp(void){ /* check whether there are long or short names entered without a corresponding parameter */ // first, check if we want to check that ! if (stopOnUnknownParam.value()) { for (LongNameMapType::const_iterator lIt = longNameMap.begin(); lIt != longNameMap.end(); ++lIt) { string entry = lIt->first; MultiMapType::const_iterator it; for (it = params.begin(); it != params.end(); ++it) { if (entry == it->second->longName()) { break; } } if (it == params.end()) { string msg = "Unknown parameter: --" + entry + " entered, type -h or --help to see available parameters"; messages.push_back(msg); } } for (ShortNameMapType::const_iterator sIt = shortNameMap.begin(); sIt != shortNameMap.end(); ++sIt) { char entry = sIt->first; MultiMapType::const_iterator it; for (it = params.begin(); it != params.end(); ++it) { if (entry == it->second->shortName()) { break; } } if (it == params.end()) { string entryString(1, entry); string msg = "Unknown parameter: -" + entryString + " entered, type -h or --help to see available parameters"; messages.push_back(msg); } } } return needHelp.value() || !messages.empty();}///////////////// I put these here at the momentostream & operator<<(ostream & _os, const eoParamParamType & _rate){ _rate.printOn(_os); return _os;}istream & operator>>(istream & _is, eoParamParamType & _rate){ _rate.readFrom(_is); return _is;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?