Mercurial > code
diff C++/Parser.cpp @ 203:1ffe6d4937b7
Update parser for more convenience and types security #224
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 23 Jan 2014 14:56:50 +0100 |
parents | 600754c27c88 |
children | 9f22ce5f1b39 706f861c4c6d |
line wrap: on
line diff
--- a/C++/Parser.cpp Sat Jan 04 18:02:06 2014 +0100 +++ b/C++/Parser.cpp Thu Jan 23 14:56:50 2014 +0100 @@ -16,22 +16,14 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <cstring> +#include <cerrno> #include <iostream> #include <fstream> #include "Parser.h" /* -------------------------------------------------------- - * Option public members - * -------------------------------------------------------- */ - -bool operator==(const Option &o1, const Option &o2) -{ - return o1.m_key == o2.m_key && - o1.m_value == o2.m_value; -} - -/* -------------------------------------------------------- * Section public members * -------------------------------------------------------- */ @@ -40,108 +32,50 @@ { } +Section::Section(const std::string &name) + : m_name(name) + , m_allowed(true) +{ + +} + const std::string &Section::getName() const { return m_name; } -const std::string Section::findOption(const std::string &name) const +bool Section::hasOption(const std::string &name) const { - std::string ret; - - for (const Option &o : m_options) - if (o.m_key == name) { - ret = o.m_value; - break; - } - - return ret; + return m_options.count(name) >= 1; } -template <> -bool Section::getValue(const std::string &name) const +Section::Map::iterator Section::begin() { - bool result = false; - - if (hasOption(name)) { - std::string value = findOption(name); - - if (value == "yes" || value == "true"|| value == "1") - result = true; - else if (value == "no" || value == "false" || value == "0") - result = false; - } - - return result; + return m_options.begin(); } -template <> -int Section::getValue(const std::string &name) const +Section::Map::const_iterator Section::cbegin() const { - int result = -1; - - if (hasOption(name)) - result = atoi(findOption(name).c_str()); - - return result; + return m_options.cbegin(); } -template <> -std::string Section::getValue(const std::string &name) const +Section::Map::iterator Section::end() { - std::string result; - - if (hasOption(name)) - result = findOption(name); - - return result; -} - -const std::vector<Option> &Section::getOptions() const -{ - return m_options; + return m_options.end(); } -bool Section::hasOption(const std::string &name) const +Section::Map::const_iterator Section::cend() const { - for (const Option &o : m_options) - if (o.m_key == name) - return true; - - return false; -} - -bool operator==(const Section &s1, const Section &s2) -{ - if (s1.m_name != s2.m_name) - return false; - - return s1.m_options == s2.m_options; + return m_options.end(); } /* -------------------------------------------------------- * Parser private members * -------------------------------------------------------- */ -void Parser::addSection(const std::string &name) -{ - Section section; - - section.m_name = name; - section.m_allowed = true; - - m_sections.push_back(section); -} - void Parser::addOption(const std::string &key, const std::string &value) { - Option option; - Section ¤t = m_sections.back(); - - option.m_key = key; - option.m_value = value; - - current.m_options.push_back(option); + m_sections.back().m_options.insert(std::make_pair(key, value)); } void Parser::readSection(int lineno, const std::string &line) @@ -150,7 +84,7 @@ if ((end = line.find_first_of(']')) != std::string::npos) { if (end > 1) { - std::string name = line.substr(1, end - 1); + auto name = line.substr(1, end - 1); /* * Check if we can add a section, if redefinition is @@ -162,8 +96,9 @@ if (!(m_tuning & DisableVerbosity)) log(lineno, name, "redefinition not allowed"); m_sections.back().m_allowed = false; - } else - addSection(name); + } else { + m_sections.push_back(Section(name)); + } } else if (!(m_tuning & DisableVerbosity)) { /* * Do not add options at this step because it will @@ -177,9 +112,9 @@ void Parser::readOption(int lineno, const std::string &line) { + auto ¤t = m_sections.back(); size_t epos; std::string key, value; - Section ¤t = m_sections.back(); // Error on last section? if (!current.m_allowed) { @@ -267,6 +202,22 @@ const char Parser::DEFAULT_COMMENT_CHAR = '#'; +void Parser::open() +{ + std::ifstream file; + std::string line; + int lineno = 1; + + file.open(m_path.c_str()); + if (!file.is_open()) + throw std::runtime_error(m_path + std::string(std::strerror(errno))); + + while (std::getline(file, line)) + readLine(lineno++, line); + + file.close(); +} + Parser::Parser() { } @@ -276,60 +227,48 @@ , m_tuning(tuning) , m_commentChar(commentToken) { - Section root; + Section s(""); - // Add a default root section - root.m_name = ""; - root.m_allowed = (tuning & DisableRootSection) ? false : true; + s.m_allowed = (tuning & DisableRootSection) ? false : true; - m_sections.push_back(root); + m_sections.push_back(s); + open(); } Parser::~Parser() { } -bool Parser::open() +Parser::List::iterator Parser::begin() { - std::ifstream file; - std::string line; - int lineno = 1; - - file.open(m_path.c_str()); - if (!file.is_open()) { - m_error = "could not open file " + m_path; // XXX: add a real error - return false; - } - - // Avoid use of C getline - while (std::getline(file, line)) - readLine(lineno++, line); - - file.close(); - - return true; + return m_sections.begin(); } -const std::string &Parser::getError() const +Parser::List::const_iterator Parser::cbegin() const { - return m_error; + return m_sections.cbegin(); } -const std::vector<Section> &Parser::getSections() const +Parser::List::iterator Parser::end() { - return m_sections; + return m_sections.end(); +} + +Parser::List::const_iterator Parser::cend() const +{ + return m_sections.end(); } void Parser::findSections(const std::string &name, FindFunc func) const { - for (const Section &s : m_sections) + for (const auto &s : m_sections) if (s.m_name == name) func(s); } bool Parser::hasSection(const std::string &name) const { - for (const Section &s : m_sections) + for (const auto &s : m_sections) if (s.m_name == name) return true; @@ -338,34 +277,14 @@ const Section &Parser::getSection(const std::string &name) const { - for (const Section &s : m_sections) + for (const auto &s : m_sections) if (s.m_name == name) return s; - throw NotFoundException(name); + throw std::out_of_range(name + " not found"); } void Parser::log(int number, const std::string &, const std::string &message) { std::cout << "line " << number << ": " << message << std::endl; } - -void Parser::dump() -{ - for (auto s : m_sections) { - dumpSection(s); - - for (auto o : s.m_options) - dumpOption(o); - } -} - -void Parser::dumpSection(const Section §ion) -{ - std::cout << "Section " << section.m_name << std::endl; -} - -void Parser::dumpOption(const Option &option) -{ - std::cout << " Option " << option.m_key << " = " << option.m_value << std::endl; -}