src/lib/INIReader.cpp
branchv_0
changeset 2 f031a4dc7c52
parent 1 3876a9c56a66
child 3 4313e91da50b
--- a/src/lib/INIReader.cpp	Sat Nov 21 20:09:18 2020 +0100
+++ b/src/lib/INIReader.cpp	Sun Nov 22 00:44:00 2020 +0100
@@ -40,30 +40,43 @@
 		std::regex whitespacePattrern("\\s*");
 		std::regex commentPattrern("\\s*(;|#)\\s*(.*)");
 		std::regex sectionPattrern("\\s*\\[\\s*([^\\]]+)\\s*\\]\\s*");
-		std::regex entryQuotesPattrern("\\s*([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?\\s*=\\s*\"([^']+)\"\\s*((;|#)\\s*(.*))?");
-		std::regex entryApostrophesPattrern("\\s*([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?\\s*=\\s*'([^']+)'\\s*((;|#)\\s*(.*))?");
-		std::regex entryPlainPattrern("\\s*([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?\\s*=\\s*(.*)");
+		std::regex entryQuotesPattrern(/***/"\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*\"([^']+)\"\\s*((;|#)\\s*(.*))?");
+		std::regex entryApostrophesPattrern("\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*'([^']+)'\\s*((;|#)\\s*(.*))?");
+		std::regex entryPlainPattrern("\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*(.*)");
 
 		std::smatch match;
-		std::string section;
+		bool inSection = false;
 		std::string line;
+		int lineNumber = 0;
+		int eventNumber = 0;
+
 
 		while (std::getline(input, line)) {
+			lineNumber++;
 
 			if (std::regex_match(line, match, whitespacePattrern)) {
 				// TODO: support also whitespace
 			} else if (std::regex_match(line, match, commentPattrern)) {
 				// TODO: support also comments + emit also the comment style (;/#)
 			} else if (std::regex_match(line, match, sectionPattrern)) {
-				if (section.size()) for (INIContentHandler* handler : handlers) handler->endSection();
-				section = match[1];
-				for (INIContentHandler* handler : handlers) handler->startSection(section);
-			} else if (std::regex_match(line, match, entryQuotesPattrern) || std::regex_match(line, match, entryApostrophesPattrern)) {
+				if (inSection) for (INIContentHandler* handler : handlers) handler->endSection();
+				INIContentHandler::SectionStartEvent event;
+				event.lineNumber = lineNumber;
+				event.eventNumber = ++eventNumber;
+				event.name = match[1];
 				// TODO: support also comments + emit also the comment style (;/#)
+				for (INIContentHandler* handler : handlers) handler->startSection(event);
+			} else if (std::regex_match(line, match, entryQuotesPattrern) || std::regex_match(line, match, entryApostrophesPattrern) || std::regex_match(line, match, entryPlainPattrern)) {
+				INIContentHandler::EntryEvent event;
+				event.lineNumber = lineNumber;
+				event.eventNumber = ++eventNumber;
+				event.key = match[2];
+				event.subKey = match[4];
+				event.fullKey = match[1];
+				event.value = match[5];
+				if (match.size() == 9) event.comment = match[8];
 				// TODO: emit also the quote style ('/"/) and surrounding whitespace
-				for (INIContentHandler* handler : handlers) handler->entry(match[1], match[3], match[4]);
-			} else if (std::regex_match(line, match, entryPlainPattrern)) {
-				for (INIContentHandler* handler : handlers) handler->entry(match[1], match[3], match[4]);
+				for (INIContentHandler* handler : handlers) handler->entry(event);
 			} else {
 				// TODO: warning, error, or support unknown content
 			}
@@ -77,10 +90,9 @@
 			// TODO: support also nested sections – hierarchy
 			// TODO: support also option for alternative key-value separator (: instead of =)
 			// TODO: support also other encodings (currently only UTF-8 is supported)
-			// TODO: emit line numbers and/or event order?
 		}
 
-		if (section.size()) for (INIContentHandler* handler : handlers) handler->endSection();
+		if (inSection) for (INIContentHandler* handler : handlers) handler->endSection();
 
 		for (INIContentHandler* handler : handlers) handler->endDocument();
 	}