From f95b5b872cc63bb5e21b0d74c8927b61149c2f85 Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 10 Jun 2018 13:32:22 +1000 Subject: Backport: Updated the code and comment for running a regex over multiple lines at once instead of breaking up into lines. Using the preprocessor to hide the multiline code instead of comments so that it is easier to experiment with. Backport of changeset 7028:9227461c9330. --- src/Document.cxx | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Document.cxx b/src/Document.cxx index b7dc4c8d1..c98118986 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -2963,14 +2963,19 @@ bool MatchOnLines(const Document *doc, const Regex ®exp, const RESearchRange bool matched = false; std::match_results match; - // MSVC and libc++ have problems with ^ and $ matching line ends inside a range - // If they didn't then the line by line iteration could be removed for the forwards - // case and replaced with the following 4 lines: - // Iterator uiStart(doc, startPos); - // Iterator uiEnd(doc, endPos); - // flagsMatch = MatchFlags(doc, startPos, endPos); - // matched = std::regex_search(uiStart, uiEnd, match, regexp, flagsMatch); - + // MSVC and libc++ have problems with ^ and $ matching line ends inside a range. + // CRLF line ends are also a problem as ^ and $ only treat LF as a line end. + // The std::regex::multiline option was added to C++17 to improve behaviour but + // has not been implemented by compiler runtimes with MSVC always in multiline + // mode and libc++ and libstdc++ always in single-line mode. + // If multiline regex worked well then the line by line iteration could be removed + // for the forwards case and replaced with the following 4 lines: +#ifdef REGEX_MULTILINE + Iterator itStart(doc, resr.startPos); + Iterator itEnd(doc, resr.endPos); + const std::regex_constants::match_flag_type flagsMatch = MatchFlags(doc, resr.startPos, resr.endPos); + matched = std::regex_search(itStart, itEnd, match, regexp, flagsMatch); +#else // Line by line. for (Sci::Line line = resr.lineRangeStart; line != resr.lineRangeBreak; line += resr.increment) { const Range lineRange = resr.LineRange(line); @@ -2999,6 +3004,7 @@ bool MatchOnLines(const Document *doc, const Regex ®exp, const RESearchRange break; } } +#endif if (matched) { for (size_t co = 0; co < match.size(); co++) { search.bopat[co] = match[co].first.Pos(); -- cgit v1.2.3