#include #include #include #include #include #include #include "settings.h" namespace qi = boost::spirit::qi; namespace { typedef std::map PairsType; typedef std::map SectionsType; template struct IniGrammar : qi::grammar { IniGrammar() : IniGrammar::base_type(query) { query = +(section | (comment >> eol) | (space >> eol)); section = sectionHeader >> -sectionContent; sectionHeader = '[' >> space >> key >> space >> ']' >> eol; sectionContent = +((line | comment | space) >> eol); comment = (qi::char_(';') | '#') >> *qi::print; line = space >> key >> space >> -('=' >> space >> value >> space); key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9"); value = +qi::print; space = *qi::char_("\t "); eol = qi::lit("\r\n") | '\r' | '\n'; } qi::rule query; qi::rule()> section; qi::rule sectionContent; qi::rule()> line; qi::rule key, value, sectionHeader; qi::rule comment, space, eol; }; inline bool sectionExists(const SectionsType & data, const std::string & sectionName) throw() { return data.find(sectionName) != data.end(); } inline bool fieldExists(const SectionsType & data, const std::string & sectionName, const std::string & fieldName) throw() { const SectionsType::const_iterator sectionIterator(data.find(sectionName)); if (sectionIterator == data.end()) return false; return sectionIterator->second.find(fieldName) != sectionIterator->second.end(); } inline bool fieldValue(const SectionsType & data, const std::string & sectionName, const std::string & fieldName, std::string & value) throw() { const SectionsType::const_iterator sectionIterator(data.find(sectionName)); if (sectionIterator == data.end()) return false; const PairsType::const_iterator pairIterator(sectionIterator->second.find(fieldName)); if (pairIterator == sectionIterator->second.end()) return false; value = pairIterator->second; return true; } } using GTS::SettingsParser; void SettingsParser::parseFile(const std::string & fileName) { std::ifstream in(fileName.c_str()); if (!in) { throw std::runtime_error("Can't open file"); } std::string text; while(!in.eof()) { std::string s; std::getline(in, s); text += s + "\n"; } std::string::iterator begin = text.begin(); std::string::iterator end = text.end(); SectionsType data; IniGrammar parser; // Our parser if (!qi::parse(begin, end, parser, data)) { throw std::runtime_error("Parse error"); } std::string res; _settings._isDaemon = fieldExists(data, "general", "daemon"); _settings._isDebug = fieldExists(data, "general", "debug"); if (fieldValue(data, "general", "log_file", res)){ _settings._logFile = res; } if (fieldValue(data, "general", "pid_file", res)){ _settings._PIDFile = res; } if (fieldValue(data, "sync", "switch_interval", res)){ _settings._switchSyncInterval = boost::lexical_cast(res); } if (fieldValue(data, "sync", "info_interval", res)){ _settings._infoSyncInterval = boost::lexical_cast(res); } if (fieldValue(data, "sync", "up_profile_id", res)){ _settings._upProfileId = boost::lexical_cast(res); } if (fieldValue(data, "sync", "down_profile_id", res)){ _settings._downProfileId = boost::lexical_cast(res); } if (fieldValue(data, "sync", "max_acl_per_pdu", res)){ _settings._maxACLPerPDU = boost::lexical_cast(res); } if (fieldValue(data, "sync", "data_url", res)){ _settings._dataURL = res; } }