diff -r e72546725c77 -r c9a158da6c32 src/lib/INIReader.cpp --- a/src/lib/INIReader.cpp Mon Nov 30 00:12:16 2020 +0100 +++ b/src/lib/INIReader.cpp Sun Oct 31 17:30:40 2021 +0100 @@ -58,6 +58,20 @@ std::vector dialects; + /** + * If there is a „\“ backspace at the end of a physical line, the logical line continues on the next physical line. + * + * Disabling this option makes sense only if we also disable the unescaping processors (unescape-basic, unescape-backspace). + * Otherwise they will complain about „Missing escape sequence“ because they got „\“ at the end of the value. + */ + bool allowLineContinuationsWithEscaping = true; + + /** + * If a line starts with a space, it is continuation of the previous line. + * This rule conflicts with default ignorance of such insignificant whitespace and is quite specific to the Java MANIFEST.MF dialect. + */ + bool allowLineContinuationsWithSpace = false; + /** * 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 „\“. @@ -188,8 +202,19 @@ std::string readUntil(const std::string& until, bool* found = nullptr) { std::stringstream result; - for (char ch = peek(); input.good() && !oneOf(ch, until); ch = peek()) { - if (ch == '\\') { + for (char ch = peek(); input.good(); ch = peek()) { + if (allowLineContinuationsWithSpace && ch == '\n') { + get(); + ch = peek(); + if (ch == ' ') get(); + else if (ch == std::istream::traits_type::eof()) break; + else { + if (found) *found = true; + return result.str(); + } + } else if (oneOf(ch, until)) { + break; + } else if (allowLineContinuationsWithEscaping && ch == '\\') { get(); ch = get(); if (oneOf(ch, until) && ch == '\n') processContinuingLine(result); @@ -309,7 +334,9 @@ } void setOption(const std::string& uri, const std::string& value) override { - if (uri == option::TrimContinuingLines) trimLeadingSpacesOnContinuingLines = parseBoolean(value); // TODO: continuing lines modes (enum), not just boolean + if (uri == option::AllowLineContinuationWithEscaping) allowLineContinuationsWithEscaping = parseBoolean(value); + else if (uri == option::AllowLineContinuationWithSpace) allowLineContinuationsWithSpace = parseBoolean(value); + else if (uri == option::TrimContinuingLines) trimLeadingSpacesOnContinuingLines = parseBoolean(value); else if (uri == option::AllowSections) allowSections = parseBoolean(value); else if (uri == option::AllowSectionTags) allowSectionTags = parseBoolean(value); else if (uri == option::AllowSubKeys) allowSubKeys = parseBoolean(value);