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 GTS::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");
91 std::string::iterator begin = text.begin();
92 std::string::iterator end = text.end();
95 IniGrammar<std::string::iterator> parser; // Our parser
97 if (!qi::parse(begin, end, parser, data)) {
98 throw std::runtime_error("Parse error");
102 _settings._isDaemon = fieldExists(data, "general", "daemon");
103 _settings._isDebug = fieldExists(data, "general", "debug");
104 if (fieldValue(data, "general", "log_file", res)){
105 _settings._logFile = res;
107 if (fieldValue(data, "general", "pid_file", res)){
108 _settings._PIDFile = res;
110 if (fieldValue(data, "sync", "switch_interval", res)){
111 _settings._switchSyncInterval = boost::lexical_cast<time_t>(res);
113 if (fieldValue(data, "sync", "info_interval", res)){
114 _settings._infoSyncInterval = boost::lexical_cast<time_t>(res);
116 if (fieldValue(data, "sync", "up_profile_id", res)){
117 _settings._upProfileId = boost::lexical_cast<unsigned>(res);
119 if (fieldValue(data, "sync", "down_profile_id", res)){
120 _settings._downProfileId = boost::lexical_cast<unsigned>(res);
122 if (fieldValue(data, "sync", "data_url", res)){
123 _settings._dataURL = res;