changeset 180:2bcdee0fe8d4

Update parser
author David Demelier <markand@malikania.fr>
date Thu, 26 Sep 2013 19:39:24 +0200
parents 3648e9e6935b
children 08af4f99c104
files C++/Parser.cpp C++/Parser.h
diffstat 2 files changed, 92 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/C++/Parser.cpp	Sun Sep 22 19:57:59 2013 +0200
+++ b/C++/Parser.cpp	Thu Sep 26 19:39:24 2013 +0200
@@ -36,19 +36,13 @@
  * -------------------------------------------------------- */
 
 Section::Section()
-	:m_allowed(true)
+	: m_allowed(true)
 {
 }
 
-Section::~Section()
+const std::string &Section::getName() const
 {
-}
-
-Section::Section(const Section &s)
-{
-	m_name = s.m_name;
-	m_options = s.m_options;
-	m_allowed = s.m_allowed;
+	return m_name;
 }
 
 const std::string Section::findOption(const std::string &name) const
@@ -56,7 +50,8 @@
 	std::string ret;
 
 	for (const Option &o : m_options)
-		if (o.m_key == name) {
+		if (o.m_key == name)
+		{
 			ret = o.m_value;
 			break;
 		}
@@ -64,11 +59,13 @@
 	return ret;
 }
 
-template <> bool Section::getOption(const std::string &name) const
+template <>
+bool Section::getValue(const std::string &name) const
 {
 	bool result = false;
 
-	if (hasOption(name)) {
+	if (hasOption(name))
+	{
 		std::string value = findOption(name);
 
 		if (value == "yes" || value == "true"|| value == "1")
@@ -80,18 +77,19 @@
 	return result;
 }
 
-template <> int Section::getOption(const std::string &name) const
+template <>
+int Section::getValue(const std::string &name) const
 {
 	int result = -1;
 
-	if (hasOption(name)) {
+	if (hasOption(name))
 		result = atoi(findOption(name).c_str());
-	}
 
 	return result;
 }
 
-template <> std::string Section::getOption(const std::string &name) const
+template <>
+std::string Section::getValue(const std::string &name) const
 {
 	std::string result;
 
@@ -101,12 +99,7 @@
 	return result;
 }
 
-const std::string & Section::getName() const
-{
-	return m_name;
-}
-
-const std::vector<Option> & Section::getOptions() const
+const std::vector<Option> &Section::getOptions() const
 {
 	return m_options;
 }
@@ -157,8 +150,10 @@
 {
 	size_t end;
 
-	if ((end = line.find_first_of(']')) != std::string::npos) {
-		if (end > 1) {
+	if ((end = line.find_first_of(']')) != std::string::npos)
+	{
+		if (end > 1)
+		{
 			std::string name = line.substr(1, end - 1);
 
 			/*
@@ -167,14 +162,17 @@
 			 * further read options should not be enabled until
 			 * a correct section is found again.
 			 */
-			if (hasSection(name) && (m_tuning & DisableRedefinition)) {
+			if (hasSection(name) && (m_tuning & DisableRedefinition))
+			{
 				if (!(m_tuning & DisableVerbosity))
 					log(lineno, name, "redefinition not allowed");
 				m_sections.back().m_allowed = false;
-			} else {
+			}
+			else
 				addSection(name);
-			}
-		} else if (!(m_tuning & DisableVerbosity)) {
+		}
+		else if (!(m_tuning & DisableVerbosity))
+		{
 			/*
 			 * Do not add options at this step because it will
 			 * corrupt the previous one.
@@ -192,7 +190,8 @@
 	Section &current = m_sections.back();
 
 	// Error on last section?
-	if (!current.m_allowed) {
+	if (!current.m_allowed)
+	{
 		/*
 		 * If it is the root section, this has been probably set by
 		 * DisableRootSection flag, otherwise an error has occured
@@ -204,13 +203,15 @@
 		return;
 	}
 
-	if ((epos = line.find_first_of('=')) == std::string::npos) {
+	if ((epos = line.find_first_of('=')) == std::string::npos)
+	{
 		if (!(m_tuning & DisableVerbosity))
 			log(lineno, current.m_name, "missing `=' keyword");
 		return;
 	}
 
-	if (epos > 0) {
+	if (epos > 0)
+	{
 		size_t i, begin, last;
 		char c;
 
@@ -229,13 +230,16 @@
 	
 		c = value[0];
 		begin = 0;
-		if (c == '\'' || c == '"') {
+		if (c == '\'' || c == '"')
+		{
 			for (last = begin = 1; value[last] != c && last < value.length(); ++last)
 				continue;
 			if (value[last] != c && !(m_tuning & DisableVerbosity))
 				if (!(m_tuning & DisableVerbosity))
 					log(lineno, current.m_name, "undisclosed std::string");
-		} else {
+		}
+		else
+		{
 			for (last = begin; !isspace(value[last]) && last < value.length(); ++last)
 				continue;
 		}
@@ -261,8 +265,10 @@
 		continue;
 
 	buffer = line.substr(i);
-	if (buffer.length() > 0) {
-		if (buffer[0] != m_commentChar) {
+	if (buffer.length() > 0)
+	{
+		if (buffer[0] != m_commentChar)
+		{
 			if (buffer[0] == '[')
 				readSection(lineno, buffer);
 			else
@@ -277,8 +283,14 @@
 
 const char Parser::DEFAULT_COMMENT_CHAR = '#';
 
+Parser::Parser()
+{
+}
+
 Parser::Parser(const std::string &path, int tuning, char commentToken)
-	:m_path(path), m_tuning(tuning), m_commentChar(commentToken)
+	: m_path(path)
+	, m_tuning(tuning)
+	, m_commentChar(commentToken)
 {
 	Section root;
 
@@ -289,10 +301,6 @@
 	m_sections.push_back(root);
 }
 
-Parser::Parser()
-{
-}
-
 Parser::~Parser()
 {
 }
@@ -304,43 +312,36 @@
 	int lineno = 1;
 
 	file.open(m_path.c_str());
-	if (!file.is_open()) {
+	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)) {
+	while (std::getline(file, line))
 		readLine(lineno++, line);
-	}
 
 	file.close();
 
 	return true;
 }
 
-const std::string & Parser::getError() const
+const std::string &Parser::getError() const
 {
 	return m_error;
 }
 
-const std::vector<Section> & Parser::getSections() const
+const std::vector<Section> &Parser::getSections() const
 {
 	return m_sections;
 }
 
-std::vector<Section> Parser::findSections(const std::string &name) const
+void Parser::findSections(const std::string &name, FindFunc func) const
 {
-	std::vector<Section> list;
-
-	for (const Section &s : m_sections) {
-		if (s.m_name == name) {
-			Section copy = s;
-			list.push_back(copy);
-		}
-	}
-
-	return list;
+	for (const Section &s : m_sections)
+		if (s.m_name == name)
+			func(s);
 }
 
 bool Parser::hasSection(const std::string &name) const
@@ -352,18 +353,16 @@
 	return false;
 }
 
-Section Parser::getSection(const std::string &name) const
+const Section &Parser::getSection(const std::string &name) const
 {
-	Section ret;	
-
 	for (const Section &s : m_sections)
 		if (s.m_name == name)
-			ret = s;
+			return s;
 
-	return ret;
+	throw NotFoundException(name);
 }
 
-Section Parser::requireSection(const std::string &name) const
+const Section &Parser::requireSection(const std::string &name) const
 {
 	if (!hasSection(name))
 		throw NotFoundException(name);
@@ -378,8 +377,10 @@
 
 void Parser::dump()
 {
-	for (auto s : m_sections) {
+	for (auto s : m_sections)
+	{
 		dumpSection(s);
+
 		for (auto o : s.m_options)
 			dumpOption(o);
 	}
--- a/C++/Parser.h	Sun Sep 22 19:57:59 2013 +0200
+++ b/C++/Parser.h	Thu Sep 26 19:39:24 2013 +0200
@@ -21,6 +21,7 @@
 
 #include <cstdlib>
 #include <exception>
+#include <functional>
 #include <iostream>
 #include <string>
 #include <vector>
@@ -35,7 +36,7 @@
 
 public:
 	NotFoundException(const std::string &key)
-		:m_key(key)
+		: m_key(key)
 	{
 	}
 
@@ -66,41 +67,34 @@
  * options are allowed (default behavior), the root
  * section is "".
  */
-struct Section
+class Section
 {
+private:
+	const std::string findOption(const std::string &name) const;
+
+public:
 	std::string m_name;		/*! name of section */
 	std::vector<Option> m_options;	/*! list of options inside */
 	bool m_allowed;			/*! is authorized to push */
 
+	/**
+	 * Default constructor.
+	 */
 	Section();
-	~Section();
-
-	/**
-	 * Copy constructor
-	 */
-	Section(const Section &s);
 
 	/**
 	 * Get the section name
 	 *
 	 * @return the section name
 	 */
-	const std::string & getName() const;
-
-	/**
-	 * Search an option value.
-	 *
-	 * @param name the option name
-	 * @return the value or "" if not found
-	 */
-	const std::string findOption(const std::string &name) const;
+	const std::string &getName() const;
 
 	/**
 	 * Get all options from that section.
 	 *
 	 * @return the list of options
 	 */
-	const std::vector<Option> & getOptions() const;
+	const std::vector<Option> &getOptions() const;
 
 	/**
 	 * Tells if that section has the specified option name.
@@ -117,7 +111,7 @@
 	 * @return the value if found
 	 */
 	template <typename T>
-	T getOption(const std::string &name) const;
+	T getValue(const std::string &name) const;
 
 	/**
 	 * Requires an option, this works like getOption except
@@ -125,16 +119,16 @@
 	 * thrown.
 	 *
 	 * @param name the name
+	 * @return the value
 	 * @throw NotFoundException if not found
-	 * @return the value
 	 */
 	template <typename T>
-	T requireOption(const std::string &name) const
+	T requireValue(const std::string &name) const
 	{
 		if (!hasOption(name))
 			throw NotFoundException(name);
 
-		return getOption<T>(name);
+		return getValue<T>(name);
 	}
 
 	friend std::ostream & operator<<(std::ostream & stream, const Section &section)
@@ -163,6 +157,8 @@
 		DisableVerbosity	= 4	/*! be verbose by method */
 	};
 
+	typedef std::function<void (const Section &)> FindFunc;
+
 private:
 	std::vector<Section> m_sections;	/*! list of sections found */
 	std::string m_error;			/*! if an error occured */
@@ -214,24 +210,23 @@
 	 *
 	 * @return the error message
 	 */
-	const std::string & getError() const;
+	const std::string &getError() const;
 
 	/**
 	 * Get all sections found
 	 *
 	 * @return all sections
 	 */
-	const std::vector<Section> & getSections() const;
+	const std::vector<Section> &getSections() const;
 
 	/**
-	 * Get a list of sections for config which multiple
-	 * definitions are allowed. This does a full copy of sections
-	 * and options.
+	 * Find all sections matching the name.
 	 *
 	 * @param name the sections name
+	 * @param func the function 
 	 * @return a list of section with the options
 	 */
-	std::vector<Section> findSections(const std::string &name) const;
+	void findSections(const std::string &name, FindFunc func) const;
 
 	/**
 	 * Tell if a section is existing.
@@ -245,18 +240,19 @@
 	 *
 	 * @param name the section name
 	 * @return a section
+	 * @throw NotFoundException if not found
 	 */
-	Section getSection(const std::string &name) const;
+	const Section &getSection(const std::string &name) const;
 
 	/**
 	 * Same as getSection except that throws an exception if
 	 * the section is not found.
 	 *
 	 * @param name the section name
+	 * @return the section
 	 * @throw NotFoundException if not found
-	 * @return the section
 	 */
-	Section requireSection(const std::string &name) const;
+	const Section &requireSection(const std::string &name) const;
 
 	/**
 	 * Logging function, used only if DisableVerbosity is not set. The
@@ -294,7 +290,7 @@
 	 */
 	virtual void dumpOption(const Option &option);
 
-	friend std::ostream & operator<<(std::ostream & stream, const Parser &parser)
+	friend std::ostream &operator<<(std::ostream & stream, const Parser &parser)
 	{
 		for (auto s : parser.m_sections)
 			stream << s;;