6 #include <boost/spirit/include/qi.hpp>
7 #include <boost/fusion/include/std_pair.hpp>
11 namespace qi = boost::spirit::qi;
15 typedef std::map<std::string, std::string> PairsType;
16 typedef std::map<std::string, PairsType> SectionsType;
18 template <typename Iterator>
20 : qi::grammar<Iterator, SectionsType()>
23 : IniGrammar::base_type(query)
25 query = +(section | (comment >> eol) | (space >> eol));
26 section = sectionHeader >> -sectionContent;
27 sectionHeader = '[' >> space >> key >> space >> ']' >> eol;
28 sectionContent = +((line | comment | space) >> eol);
29 comment = (qi::char_(';') | '#') >> *qi::print;
30 line = space >> key >> space >> -('=' >> space >> value >> space);
31 key = qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9");
33 space = *qi::char_("\t ");
34 eol = qi::lit("\r\n") | '\r' | '\n';
37 qi::rule<Iterator, SectionsType()> query;
38 qi::rule<Iterator, std::pair<std::string, PairsType>()> section;
39 qi::rule<Iterator, PairsType()> sectionContent;
40 qi::rule<Iterator, std::pair<std::string, std::string>()> line;
41 qi::rule<Iterator, std::string()> key, value, sectionHeader;
42 qi::rule<Iterator> comment, space, eol;
46 bool sectionExists(const SectionsType & data, const std::string & sectionName) throw()
48 return data.find(sectionName) != data.end();
52 bool fieldExists(const SectionsType & data, const std::string & sectionName, const std::string & fieldName) throw()
54 const SectionsType::const_iterator sectionIterator(data.find(sectionName));
55 if (sectionIterator == data.end())
57 return sectionIterator->second.find(fieldName) != sectionIterator->second.end();
61 bool fieldValue(const SectionsType & data, const std::string & sectionName, const std::string & fieldName, std::string & value) throw()
63 const SectionsType::const_iterator sectionIterator(data.find(sectionName));
64 if (sectionIterator == data.end())
66 const PairsType::const_iterator pairIterator(sectionIterator->second.find(fieldName));
67 if (pairIterator == sectionIterator->second.end())
69 value = pairIterator->second;
75 using SSMD::SettingsParser;
77 void SettingsParser::parseFile(const std::string & fileName)
79 std::ifstream in(fileName.c_str());
81 throw std::runtime_error("Can't open file");
90 std::string::iterator begin = text.begin();
91 std::string::iterator end = text.end();
94 IniGrammar<std::string::iterator> parser; // Our parser
96 if (!qi::parse(begin, end, parser, data)) {
97 throw std::runtime_error("Parse error");
101 _settings._isDaemon = fieldExists(data, "general", "daemon");
102 _settings._isDebug = fieldExists(data, "general", "debug");
103 if (fieldValue(data, "general", "log_file", res))
104 _settings._logFile = res;
105 if (fieldValue(data, "general", "pid_file", res))
106 _settings._PIDFile = res;
107 if (fieldValue(data, "sync", "switch_interval", res))
108 _settings._switchSyncInterval = boost::lexical_cast<time_t>(res);
109 if (fieldValue(data, "sync", "info_interval", res))
110 _settings._infoSyncInterval = boost::lexical_cast<time_t>(res);
111 if (fieldValue(data, "sync", "up_profile_id", res))
112 _settings._upProfileId = boost::lexical_cast<unsigned>(res);
113 if (fieldValue(data, "sync", "down_profile_id", res))
114 _settings._downProfileId = boost::lexical_cast<unsigned>(res);
115 if (fieldValue(data, "sync", "max_acl_per_pdu", res))
116 _settings._maxACLPerPDU = boost::lexical_cast<size_t>(res);
117 if (fieldValue(data, "sync", "data_url", res))
118 _settings._dataURL = res;
119 if (fieldValue(data, "sync", "script_base", res))
120 _settings._scriptBase = res;
121 _settings._dumpScripts = fieldExists(data, "sync", "dump_scripts");