src/lib/INIReader.cpp
branchv_0
changeset 28 596a724fbb83
parent 27 e9aad9dd823a
child 34 7eb3dcacba7b
--- a/src/lib/INIReader.cpp	Sat Nov 28 18:10:47 2020 +0100
+++ b/src/lib/INIReader.cpp	Sat Nov 28 20:59:29 2020 +0100
@@ -21,6 +21,7 @@
 #include <stdexcept>
 
 #include "INIReader.h"
+#include "uri.h"
 
 namespace relpipe {
 namespace in {
@@ -45,6 +46,18 @@
 
 	std::vector<ConfiguredUnescapingProcessor> unescapingProcessors;
 
+	class ConfiguredDialect {
+	public:
+		std::shared_ptr<Dialect> dialect;
+		const std::string uri;
+
+		ConfiguredDialect(std::shared_ptr<Dialect> dialect, const std::string uri) : dialect(dialect), uri(uri) {
+		}
+
+	};
+
+	std::vector<ConfiguredDialect> dialects;
+
 	/** 
 	 * By default, we ignore all leading whitespace on continuing lines.
 	 * If there should be some spaces or tabs, they should be placed on the previous line before the „\“.
@@ -270,21 +283,14 @@
 		else throw std::invalid_argument(std::string("Unable to parse boolean value: ") + value + " (expecting true or false)");
 	}
 
-	void setDialect(const std::string& name) {
-		if (name == "default-ini") {
-			// already set
-		} else if (name == "java-properties") {
-			trimLeadingSpacesOnContinuingLines = true;
-			allowSections = false;
-			allowSectionTags = false;
-			allowSubKeys = false;
-			commentSeparators = "#";
-			keyValueSeparators = "=:";
-			quotes = "";
-			// TODO: enable unicode unescaping
-		} else {
-			throw std::invalid_argument(std::string("Unsupported INI dialect: ") + name);
+	void setDialect(const std::string& uri) {
+		for (ConfiguredDialect& d : dialects) {
+			if (d.uri == uri) {
+				d.dialect->apply(*this);
+				return;
+			}
 		}
+		throw std::invalid_argument(std::string("Unsupported INI dialect: ") + uri);
 	}
 
 	bool setUnescaping(const std::string& uri, const std::string& value) {
@@ -303,14 +309,14 @@
 	}
 
 	void setOption(const std::string& uri, const std::string& value) override {
-		if (uri == "trim-continuing-lines") trimLeadingSpacesOnContinuingLines = parseBoolean(value); // TODO: continuing lines modes (enum), not just boolean
-		else if (uri == "allow-sections") allowSections = parseBoolean(value);
-		else if (uri == "allow-section-tags") allowSectionTags = parseBoolean(value);
-		else if (uri == "allow-sub-keys") allowSubKeys = parseBoolean(value);
-		else if (uri == "comment-separators") commentSeparators = value;
-		else if (uri == "key-value-separators") keyValueSeparators = value;
-		else if (uri == "quotes") quotes = value;
-		else if (uri == "dialect") setDialect(value);
+		if (uri == option::TrimContinuingLines) trimLeadingSpacesOnContinuingLines = parseBoolean(value); // TODO: continuing lines modes (enum), not just boolean
+		else if (uri == option::AllowSections) allowSections = parseBoolean(value);
+		else if (uri == option::AllowSectionTags) allowSectionTags = parseBoolean(value);
+		else if (uri == option::AllowSubKeys) allowSubKeys = parseBoolean(value);
+		else if (uri == option::CommentSeparators) commentSeparators = value;
+		else if (uri == option::KeyValueSeparators) keyValueSeparators = value;
+		else if (uri == option::Quotes) quotes = value;
+		else if (uri == option::Dialect) setDialect(value);
 		else if (setUnescaping(uri, value));
 		else throw std::invalid_argument(std::string("Invalid parser option: „") + uri + "“ with value: „" + value + "“");
 	}
@@ -323,6 +329,11 @@
 		unescapingProcessors.push_back({processor, uri, enabledByDefault});
 	}
 
+	void addDialect(std::shared_ptr<Dialect> dialect, const std::string uri, bool enabledByDefault) override {
+		dialects.push_back({dialect, uri});
+		if (enabledByDefault) dialect->apply(*this);
+	}
+
 	void process() override {
 		for (INIContentHandler* handler : handlers) handler->startDocument();