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 }
00223 else
00224 {
00225 string value = "1";
00226
00227 if (str.size() >= 2)
00228 {
00229 if (str[2] == '=')
00230 {
00231 if (str.size() >= 3)
00232 value = string(str.begin() + 3, str.end());
00233 }
00234 else
00235 {
00236 value = string(str.begin() + 2, str.end());
00237 }
00238 }
00239
00240 shortNameMap[str[1]] = value;
00241 }
00242 }
00243 }
00244 }
00245
00246 updateParameters();
00247 }
00248
00249 void eoParser::printOn(ostream& os) const
00250 {
00251 typedef MultiMapType::const_iterator It;
00252
00253 It p = params.begin();
00254
00255 std::string section = p->first;
00256
00257 printSectionHeader(os, section);
00258
00259 for (; p != params.end(); ++p)
00260 {
00261 std::string newSection = p->first;
00262
00263 if (newSection != section)
00264 {
00265 section = newSection;
00266 printSectionHeader(os, section);
00267 }
00268
00269 eoParam* param = p->second;
00270
00271 if (!isItThere(*param))
00272 os << "# ";
00273
00274 string str = "--" + param->longName() + "=" + param->getValue();
00275
00276 os.setf(ios_base::left, ios_base::adjustfield);
00277 os << setw(40) << str;
00278
00279 os << setw(0) << " # ";
00280 if (param->shortName())
00281 os << '-' << param->shortName() << " : ";
00282 os << param->description();
00283
00284 if (param->required())
00285 {
00286 os << " REQUIRED ";
00287 }
00288
00289 os << '\n';
00290 }
00291 }
00292
00293 void eoParser::printHelp(ostream& os)
00294 {
00295 if (needHelp.value() == false && !messages.empty())
00296 {
00297 std::copy(messages.begin(), messages.end(), ostream_iterator<string>(os, "\n"));
00298 messages.clear();
00299 return;
00300 }
00301
00302
00303 os << this->programName <<": "<< programDescription << "\n\n";
00304
00305
00306 os << "Usage: "<< programName<<" [Options]\n";
00307
00308 os << "Options of the form \"-f[=Value]\" or \"--Name[=value]\"" << endl;
00309
00310 os << "Where:"<<endl;
00311
00312 typedef MultiMapType::const_iterator It;
00313
00314 It p = params.begin();
00315
00316 std::string section = p->first;
00317
00318 printSectionHeader(os, section);
00319
00320
00321 for (; p != params.end(); ++p)
00322 {
00323 std::string newSection = p->first;
00324
00325 if (newSection != section)
00326 {
00327 section = newSection;
00328 printSectionHeader(os, section);
00329 }
00330
00331 if (p->second->shortName())
00332 os << "-" << p->second->shortName() << ", ";
00333
00334 os << "--" <<p->second->longName() <<":\t"
00335 << p->second->description() ;
00336
00337 os << "\n" << setw(20) << ( (p->second->required())?"Required":"Optional" );
00338 os <<". By default: "<<p->second->defValue() << '\n';
00339 }
00340
00341 os << "\n@param_file \t defines a file where the parameters are stored\n";
00342 os << '\n';
00343
00344 }
00345
00346 bool eoParser::userNeedsHelp(void)
00347 {
00348
00349
00350
00351
00352
00353 if (stopOnUnknownParam.value())
00354 {
00355 for (LongNameMapType::const_iterator lIt = longNameMap.begin(); lIt != longNameMap.end(); ++lIt)
00356 {
00357 string entry = lIt->first;
00358
00359 MultiMapType::const_iterator it;
00360
00361 for (it = params.begin(); it != params.end(); ++it)
00362 {
00363 if (entry == it->second->longName())
00364 {
00365 break;
00366 }
00367 }
00368
00369 if (it == params.end())
00370 {
00371 string msg = "Unknown parameter: --" + entry + " entered, type -h or --help to see available parameters";
00372 messages.push_back(msg);
00373 }
00374 }
00375
00376 for (ShortNameMapType::const_iterator sIt = shortNameMap.begin(); sIt != shortNameMap.end(); ++sIt)
00377 {
00378 char entry = sIt->first;
00379
00380 MultiMapType::const_iterator it;
00381
00382 for (it = params.begin(); it != params.end(); ++it)
00383 {
00384 if (entry == it->second->shortName())
00385 {
00386 break;
00387 }
00388 }
00389
00390 if (it == params.end())
00391 {
00392 string entryString(1, entry);
00393 string msg = "Unknown parameter: -" + entryString + " entered, type -h or --help to see available parameters";
00394 messages.push_back(msg);
00395 }
00396 }
00397 }
00398 return needHelp.value() || !messages.empty();
00399 }
00400
00402 ostream & operator<<(ostream & _os, const eoParamParamType & _rate)
00403 {
00404 _rate.printOn(_os);
00405 return _os;
00406 }
00407
00408 istream & operator>>(istream & _is, eoParamParamType & _rate)
00409 {
00410 _rate.readFrom(_is);
00411 return _is;
00412 }
00413