--- a/src/lib/INIReader.cpp Sat Nov 28 00:46:40 2020 +0100
+++ b/src/lib/INIReader.cpp Sat Nov 28 18:10:47 2020 +0100
@@ -32,6 +32,19 @@
std::istream& input;
std::vector<INIContentHandler*> handlers;
+ class ConfiguredUnescapingProcessor {
+ public:
+ std::shared_ptr<UnescapingProcessor> processor;
+ const std::string uri;
+ bool enbaled;
+
+ ConfiguredUnescapingProcessor(std::shared_ptr<UnescapingProcessor> processor, const std::string uri, bool enbaled) : processor(processor), uri(uri), enbaled(enbaled) {
+ }
+
+ };
+
+ std::vector<ConfiguredUnescapingProcessor> unescapingProcessors;
+
/**
* 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 „\“.
@@ -221,6 +234,12 @@
return result;
}
+ std::string unescape(const std::string& value, UnescapingProcessor::TextType type) {
+ std::string result = value;
+ for (ConfiguredUnescapingProcessor p : unescapingProcessors) if (p.enbaled) result = p.processor->unescape(result, type);
+ return result;
+ }
+
bool isComment(char ch) {
return oneOf(ch, commentSeparators);
}
@@ -268,6 +287,16 @@
}
}
+ bool setUnescaping(const std::string& uri, const std::string& value) {
+ for (ConfiguredUnescapingProcessor& p : unescapingProcessors) {
+ if (p.uri == uri) {
+ p.enbaled = parseBoolean(value);
+ return true;
+ }
+ }
+ return false;
+ }
+
public:
INIReaderImpl(std::istream& input) : input(input) {
@@ -282,6 +311,7 @@
else if (uri == "key-value-separators") keyValueSeparators = value;
else if (uri == "quotes") quotes = value;
else if (uri == "dialect") setDialect(value);
+ else if (setUnescaping(uri, value));
else throw std::invalid_argument(std::string("Invalid parser option: „") + uri + "“ with value: „" + value + "“");
}
@@ -289,6 +319,10 @@
handlers.push_back(handler);
}
+ void addUnescapingProcessor(std::shared_ptr<UnescapingProcessor> processor, const std::string uri, bool enabledByDefault) override {
+ unescapingProcessors.push_back({processor, uri, enabledByDefault});
+ }
+
void process() override {
for (INIContentHandler* handler : handlers) handler->startDocument();
@@ -323,11 +357,13 @@
readAllWhitespace();
event.name = readTokenAndEatTerminator(']', "e, &found);
if (!quote) event.name = trim(event.name);
+ event.name = unescape(event.name, UnescapingProcessor::TextType::SectionName);
readSpacesAndTabs();
if (allowSectionTags && peek() == '[') {
get();
event.tag = readTokenAndEatTerminator(']', "e, &found);
+ event.tag = unescape(event.tag, UnescapingProcessor::TextType::SectionTag);
}
readSpacesAndTabs();
@@ -336,6 +372,7 @@
get();
readSpacesAndTabs();
event.comment = readUntil('\n', &found);
+ event.comment = unescape(event.comment, UnescapingProcessor::TextType::SectionComment);
} else if (ch == '\n') {
get();
} else {
@@ -350,6 +387,7 @@
get();
readSpacesAndTabs();
event.comment = readUntil('\n', &found);
+ event.comment = unescape(event.comment, UnescapingProcessor::TextType::Comment);
for (INIContentHandler* handler : handlers) handler->comment(event);
} else {
INIContentHandler::EntryEvent event;
@@ -380,9 +418,14 @@
event.key = match[1];
event.subKey = match[2];
event.fullKey = fullKey;
+ event.subKey = unescape(event.subKey, UnescapingProcessor::TextType::EntryKey);
}
}
+ event.key = unescape(event.key, UnescapingProcessor::TextType::EntryKey);
+ event.fullKey = unescape(event.fullKey, UnescapingProcessor::TextType::EntryKey);
+ event.value = unescape(event.value, UnescapingProcessor::TextType::EntryValue);
+
if (quote) {
readSpacesAndTabs();
ch = peek();
@@ -390,6 +433,7 @@
get();
readSpacesAndTabs();
event.comment = readUntil('\n', &found);
+ event.comment = unescape(event.comment, UnescapingProcessor::TextType::EntryComment);
} else if (ch == '\n') {
get();
} else {