#include "Initfile.h" #include #include #include #include using namespace std; namespace AMDiS { /// the small parser for the initfile. see description of /// read(Initfile&,istream&) struct Parser { Parser(const string& line) { size_t pos = line.find(':'); if (pos == string::npos) { throw runtime_error("cannot find the delimiter ':' in line " "'" + line + "'"); } name = line.substr(0, pos); value = line.substr(pos + 1, line.length() - (pos + 1)); // remove everything after the % pos = value.find('%'); if (pos != string::npos) value = value.substr(0, pos); } string name; string value; }; Initfile* Initfile::singlett= NULL; std::set Initfile::fn_include_list; /// initialize singleton object an global parameters void Initfile::init(std::string in) { initIntern(); singlett->clear(); fn_include_list.clear(); singlett->read(in); singlett->getInternalParameters(); // initialize global strcutures using parameters Global::init(); }; /// Fill an initfile from a file with filename fn void Initfile::read(std::string fn) { // read file if its not parsed already if (fn_include_list.find(fn) == fn_include_list.end()) { std::ifstream inputFile; inputFile.open(fn.c_str(), std::ios::in); if (!inputFile.is_open()) throw runtime_error("init-file '" + fn + "' cannot be opened for reading"); fn_include_list.insert(fn); read(inputFile); } }; /// Fill an initfile from an input stream void Initfile::read(istream& in) { unsigned line_length = 512; char swap[line_length]; in.getline(swap, line_length); while (in.good()) { std::string whitespaces = " \t\r\f"; std::string sw(swap); size_t pos0 = sw.find_first_not_of(whitespaces); if (pos0 != std::string::npos && sw[pos0] != '%' && sw[pos0] != '#' && sw[pos0] != 0) { // parse line and extract map: tag->value Parser parser(sw); // add parameter to map after variable replacement operator[](variableReplacement(InitfileInternal::trim(parser.name))) = variableReplacement(InitfileInternal::trim(parser.value)); } else if (sw[pos0] == '#' && static_cast(sw.find("#include")) == pos0) { // include file by '#include "filename"' or '#include ' size_t pos = sw.find_first_not_of(whitespaces, std::string("#include").size() + 1); size_t epos = 0; std::string fn = ""; std::stringstream errorMsg; switch (char c= swap[pos++]) { case '<': c= '>'; case '\"': whitespaces += c; epos = sw.find_first_of(whitespaces, pos); fn = sw.substr(pos, epos - pos); if (sw[epos]!=c) { errorMsg << "filename in #include not terminated by " << c; throw std::runtime_error(errorMsg.str()); } break; default: throw std::runtime_error("no filename given for #include"); } read(fn); } in.getline(swap, line_length); } }; std::string Initfile::variableReplacement(const std::string& input) const { std::string whitespaces = " \t\r\f"; std::string inputSwap = input; size_t posVar = inputSwap.find_first_of('$'); while (posVar != string::npos) { size_t posVarBegin, posVarEnd; if(inputSwap[posVar+1] == '{') { posVarEnd = inputSwap.find_first_of('}',posVar + 2); posVarBegin = posVar + 1; } else { posVarEnd = inputSwap.find_first_of(whitespaces, posVar + 1); posVarBegin = posVar; } std::string varName = inputSwap.substr(posVarBegin + 1 , posVarEnd - posVarBegin - 1); std::string varParam = checkedGet(varName); // if varname is found in parameter list then replace variable by value // otherwise throw tagNotFound exception std::string replaceName = inputSwap.substr(posVar , posVarEnd - posVar + (posVarBegin - posVar)); inputSwap.replace(inputSwap.find(replaceName), replaceName.length(), varParam); posVar = inputSwap.find_first_of('$'); } return inputSwap; }; void Initfile::readArgv(int argc, char **argv) { for (int i = 0; i < argc; i++) { if (strcmp("-rs", argv[i]) == 0) { std::string input(argv[i + 1]); add("argv->rs", input, 0); } } } /// read standard values for output and information of parameter-values void Initfile::getInternalParameters() { int val = 0; get("level of information", val, 0); msgInfo = val; val = 1; get("WAIT", val, 0); msgWait = val; val = 1; get("parameter information", val, 0); paramInfo = val; val = 0; get("break on missing tag", val, 0); breakOnMissingTag = val; if (msgInfo == 0) paramInfo = 0; }; /// print all parameters to std::cout void Initfile::printParameters() { initIntern(); for (Initfile::iterator it = singlett->begin(); it != singlett->end(); it++) std::cout << (*it).first << " => " << (*it).second << std::endl; }; /// Write data-map to initfile void Initfile::write(ostream& out) { for (Initfile::iterator it = begin() ; it!=end(); it++) out << (*it).first << ": " << (*it).second << std::endl; } /// Write data-map to initfile void Initfile::write(std::string fn) { std::ofstream outFile; outFile.open(fn.c_str(), std::ios::out); if (!outFile.is_open()) throw runtime_error("init-file cannot be opened for writing"); write(outFile); } } // end namespace AMDiS