00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef _MSC_VER
00028 #pragma warning(disable:4786)
00029 #endif
00030
00031 #include <stdexcept>
00032 #include <algorithm>
00033 #include <fstream>
00034 #include <iomanip>
00035
00036 #include <utils/compatibility.h>
00037
00038 #include <utils/eoParser.h>
00039
00040 using namespace std;
00041
00042 void eoWarning(std::string str)
00043 {
00044 cout << str << '\n';
00045 }
00046
00047 std::ostream& printSectionHeader(std::ostream& os, std::string section)
00048 {
00049 if (section == "")
00050 section = "General";
00051
00052 os << '\n' << setw(10) << "###### " << setw(20) << section << setw(10) << " ######\n";
00053 return os;
00054 }
00055
00056 eoParameterLoader::~eoParameterLoader()
00057 {
00058 for (unsigned i = 0; i < ownedParams.size(); ++i)
00059 {
00060 delete ownedParams[i];
00061 }
00062 }
00063
00064
00065 eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription,
00066 string _lFileParamName, char _shortHand) :
00067 programName(_argv[0]),
00068 programDescription( _programDescription),
00069 needHelp(false, "help", "Prints this message", 'h'),
00070 stopOnUnknownParam(true, "stopOnUnknownParam", "Stop if unkown param entered", '\0')
00071 {
00072
00073
00074 unsigned i;
00075 for (i = 1; i < _argc; ++i)
00076 {
00077 if(_argv[i][0] == '@')
00078 {
00079 char *pts = _argv[i]+1;
00080 ifstream ifs (pts);
00081 ifs.peek();
00082 if (!ifs)
00083 {
00084 string msg = string("Could not open response file: ") + pts;
00085 throw runtime_error(msg);
00086 }
00087
00088 readFrom(ifs);
00089 break;
00090 }
00091 }
00092
00093 stringstream stream;
00094 for (i = 1; i < _argc; ++i)
00095 {
00096 stream << _argv[i] << '\n';
00097 }
00098 readFrom(stream);
00099 processParam(needHelp);
00100 processParam(stopOnUnknownParam);
00101 }
00102
00103
00104
00105 eoParam * eoParser::getParamWithLongName(const std::string& _name) const
00106 {
00107 typedef std::multimap<std::string, eoParam*> MultiMapType;
00108 typedef MultiMapType::const_iterator iter;
00109 std::string search(prefix+_name);
00110 for(iter p = params.begin(); p != params.end(); ++p)
00111 if(p->second->longName() == search)
00112 return p->second;
00113 return 0;
00114 }
00115
00116
00117
00118 void eoParser::processParam(eoParam& param, std::string section)
00119 {
00120
00121 if (prefix != "")
00122 {
00123 param.setLongName(prefix+param.longName());
00124 section = prefix + section;
00125 }
00126 doRegisterParam(param);
00127 params.insert(make_pair(section, ¶m));
00128 }
00129
00130 void eoParser::doRegisterParam(eoParam& param) const
00131 {
00132 if (param.required() && !isItThere(param))
00133 {
00134 string msg = "Required parameter: " + param.longName() + " missing";
00135 messages.push_back(msg);
00136 }
00137 pair<bool, string> value = getValue(param);
00138 if (value.first)
00139 {
00140 param.setValue(value.second);
00141 }
00142 }
00143
00144 pair<bool, string> eoParser::getValue(eoParam& _param) const
00145 {
00146 pair<bool, string> result(false, "");
00147
00148 if (_param.shortName() != 0)
00149 {
00150 map<char, string>::const_iterator it = shortNameMap.find(_param.shortName());
00151 if (it != shortNameMap.end())
00152 {
00153 result.second = it->second;
00154 result.first = true;
00155 return result;
00156 }
00157 }
00158 map<string, string>::const_iterator it = longNameMap.find(_param.longName());
00159 if (it != longNameMap.end())
00160 {
00161 result.second = it->second;
00162 result.first = true;
00163 return result;
00164 }
00165
00166 return result;
00167 }
00168
00169 void eoParser::updateParameters() const
00170 {
00171 typedef MultiMapType::const_iterator It;
00172
00173 for (It p = params.begin(); p != params.end(); ++p)
00174 {
00175 doRegisterParam(*p->second);
00176 }
00177 }
00178
00179 void eoParser::readFrom(istream& is)
00180 {
00181 string str;
00182
00183 bool processing = true;
00184 while (is >> str)
00185 {
00186 if (str.find(string("\\section{"))==0)
00187 processing = (str.find(string("Parser"))<str.size());
00188
00189 if (processing)
00190 {
00191 if (str[0] == '#')
00192 {
00193 string tempStr;
00194 getline(is, tempStr);
00195 }
00196 if (str[0] == '-')
00197 {
00198 if (str.size() < 2)
00199 {
00200 eoWarning("Missing parameter");
00201 needHelp.value() = true;
00202 return;
00203 }
00204
00205 if (str[1] == '-')
00206 {
00207 string::iterator equalLocation = find(str.begin() + 2, str.end(), '=');
00208 string value;
00209
00210 if (equalLocation == str.end())
00211 {
00212 value = "";
00213 }
00214 else
00215 {
00216 value = string(equalLocation + 1, str.end());
00217 }
00218
00219 string name(str.begin() + 2, equalLocation);
00220 longNameMap[name] = value;
00221 }
00222 else
00223 {
00224 string value = "1";
00225
00226 if (str.size() >= 2)
00227 {
00228 if (str[2] == '=')
00229 {
00230 if (str.size() >= 3)
00231 value = string(str.begin() + 3, str.end());
00232 }
00233 else
00234 {
00235 value = string(str.begin() + 2, str.end());
00236 }
00237 }
00238
00239 shortNameMap[str[1]] = value;
00240 }
00241 }
00242 }
00243 }
00244
00245 updateParameters();
00246 }
00247
00248 void eoParser::printOn(ostream& os) const
00249 {
00250 typedef MultiMapType::const_iterator It;
00251
00252 It p = params.begin();
00253
00254 std::string section = p->first;
00255
00256 printSectionHeader(os, section);
00257
00258 for (; p != params.end(); ++p)
00259 {
00260 std::string newSection = p->first;
00261
00262 if (newSection != section)
00263 {
00264 section = newSection;
00265 printSectionHeader(os, section);
00266 }
00267
00268 eoParam* param = p->second;
00269
00270 if (!isItThere(*param))
00271 os << "# ";
00272
00273 string str = "--" + param->longName() + "=" + param->getValue();
00274
00275 os.setf(ios_base::left, ios_base::adjustfield);
00276 os << setw(40) << str;
00277
00278 os << setw(0) << " # ";
00279 if (param->shortName())
00280 os << '-' << param->shortName() << " : ";
00281 os << param->description();
00282
00283 if (param->required())
00284 {
00285 os << " REQUIRED ";
00286 }
00287
00288 os << '\n';
00289 }
00290 }
00291
00292 void eoParser::printHelp(ostream& os)
00293 {
00294 if (needHelp.value() == false && !messages.empty())
00295 {
00296 std::copy(messages.begin(), messages.end(), ostream_iterator<string>(os, "\n"));
00297 messages.clear();
00298 return;
00299 }
00300
00301
00302 os << this->programName <<": "<< programDescription << "\n\n";
00303
00304
00305 os << "Usage: "<< programName<<" [Options]\n";
00306
00307 os << "Options of the form \"-f[=Value]\" or \"--Name[=value]\"" << endl;
00308
00309 os << "Where:"<<endl;
00310
00311 typedef MultiMapType::const_iterator It;
00312
00313 It p = params.begin();
00314
00315 std::string section = p->first;
00316
00317 printSectionHeader(os, section);
00318
00319
00320 for (; p != params.end(); ++p)
00321 {
00322 std::string newSection = p->first;
00323
00324 if (newSection != section)
00325 {
00326 section = newSection;
00327 printSectionHeader(os, section);
00328 }
00329
00330 if (p->second->shortName())
00331 os << "-" << p->second->shortName() << ", ";
00332
00333 os << "--" <<p->second->longName() <<":\t"
00334 << p->second->description() ;
00335
00336 os << "\n" << setw(20) << ( (p->second->required())?"Required":"Optional" );
00337 os <<". By default: "<<p->second->defValue() << '\n';
00338 }
00339
00340 os << "\n@param_file \t defines a file where the parameters are stored\n";
00341 os << '\n';
00342
00343 }
00344
00345 bool eoParser::userNeedsHelp(void)
00346 {
00347
00348
00349
00350
00351
00352 if (stopOnUnknownParam.value())
00353 {
00354 for (LongNameMapType::const_iterator lIt = longNameMap.begin(); lIt != longNameMap.end(); ++lIt)
00355 {
00356 string entry = lIt->first;
00357
00358 MultiMapType::const_iterator it;
00359
00360 for (it = params.begin(); it != params.end(); ++it)
00361 {
00362 if (entry == it->second->longName())
00363 {
00364 break;
00365 }
00366 }
00367
00368 if (it == params.end())
00369 {
00370 string msg = "Unknown parameter: --" + entry + " entered, type -h or --help to see available parameters";
00371 messages.push_back(msg);
00372 }
00373 }
00374
00375 for (ShortNameMapType::const_iterator sIt = shortNameMap.begin(); sIt != shortNameMap.end(); ++sIt)
00376 {
00377 char entry = sIt->first;
00378
00379 MultiMapType::const_iterator it;
00380
00381 for (it = params.begin(); it != params.end(); ++it)
00382 {
00383 if (entry == it->second->shortName())
00384 {
00385 break;
00386 }
00387 }
00388
00389 if (it == params.end())
00390 {
00391 string entryString(1, entry);
00392 string msg = "Unknown parameter: -" + entryString + " entered, type -h or --help to see available parameters";
00393 messages.push_back(msg);
00394 }
00395 }
00396 }
00397 return needHelp.value() || !messages.empty();
00398 }
00399
00401 ostream & operator<<(ostream & _os, const eoParamParamType & _rate)
00402 {
00403 _rate.printOn(_os);
00404 return _os;
00405 }
00406
00407 istream & operator>>(istream & _is, eoParamParamType & _rate)
00408 {
00409 _rate.readFrom(_is);
00410 return _is;
00411 }
00412