From 664798128a9e4ca2d5c4aec0d2d9c475c39f6ddd Mon Sep 17 00:00:00 2001 From: Tommaso Cucinotta Date: Sun, 16 Apr 2017 23:10:17 +0200 Subject: [PATCH] findadv: almost all test cases, including \regex[{}, back to working with std::regex. --- development/autotests/run-tests.sh | 2 +- src/lyxfind.cpp | 47 +++++++++++++++++++++--------- src/support/regex.h | 10 +++++++ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/development/autotests/run-tests.sh b/development/autotests/run-tests.sh index 3dd001aa67..25d29340e8 100755 --- a/development/autotests/run-tests.sh +++ b/development/autotests/run-tests.sh @@ -63,7 +63,7 @@ echo if [ ! -d $LYX_HOME ]; then mkdir -p $LYX_HOME -# mkdir -p $LYX_USERDIR + mkdir -p $LYX_USERDIR # cp preferences $LYX_USERDIR cd $LYX_HOME echo "Initializing testing environment . . ." diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index 7f275e3508..363172a4c0 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -672,13 +672,23 @@ string escape_for_regex(string s, bool match_latex) bool regex_replace(string const & s, string & t, string const & searchstr, string const & replacestr) { - lyx::regex e(searchstr); + LYXERR(Debug::FIND, "regex_replace() - s='" << s + << "', searchstr='" << searchstr + << "', replacestr='" << replacestr); +#if LYX_USE_STD_REGEX + // this is the default anyway + lyx::regex e(searchstr, regex_constants::ECMAScript); +#else + // TBD: check + lyx::regex e(searchstr, regex_constants::ECMAScript); +#endif ostringstream oss; ostream_iterator it(oss); lyx::regex_replace(it, s.begin(), s.end(), e, replacestr); // tolerate t and s be references to the same variable bool rv = (s != oss.str()); t = oss.str(); + LYXERR(Debug::FIND, "regex_replace() - t='" << t << "', rv=" << rv); return rv; } @@ -841,11 +851,11 @@ static size_t identifyLeading(string const & s) { string t = s; // @TODO Support \item[text] - while (regex_replace(t, t, "^\\\\(emph|textbf|subsubsection|subsection|section|subparagraph|paragraph|part)\\*?\\{", "") - || regex_replace(t, t, "^\\$", "") - || regex_replace(t, t, "^\\\\\\[ ", "") - || regex_replace(t, t, "^\\\\item ", "") - || regex_replace(t, t, "^\\\\begin\\{[a-zA-Z_]*\\*?\\} ", "")) + while (regex_replace(t, t, REGEX_BOS "\\\\(emph|textbf|subsubsection|subsection|section|subparagraph|paragraph|part)\\*?\\{", "") + || regex_replace(t, t, REGEX_BOS "\\$", "") + || regex_replace(t, t, REGEX_BOS "\\\\\\[ ", "") + || regex_replace(t, t, REGEX_BOS "\\\\item ", "") + || regex_replace(t, t, REGEX_BOS "\\\\begin\\{[a-zA-Z_]*\\*?\\} ", "")) LYXERR(Debug::FIND, " after removing leading $, \\[ , \\emph{, \\textbf{, etc.: '" << t << "'"); return s.find(t); } @@ -857,13 +867,13 @@ static int identifyClosing(string & t) int open_braces = 0; do { LYXERR(Debug::FIND, "identifyClosing(): t now is '" << t << "'"); - if (regex_replace(t, t, "(.*[^\\\\])\\$\\'", "$1")) + if (regex_replace(t, t, "(.*[^\\\\])\\$" REGEX_EOS, "$1")) continue; - if (regex_replace(t, t, "(.*[^\\\\]) \\\\\\]\\'", "$1")) + if (regex_replace(t, t, "(.*[^\\\\]) \\\\\\]" REGEX_EOS, "$1")) continue; - if (regex_replace(t, t, "(.*[^\\\\]) \\\\end\\{[a-zA-Z_]*\\*?\\}\\'", "$1")) + if (regex_replace(t, t, "(.*[^\\\\]) \\\\end\\{[a-zA-Z_]*\\*?\\}" REGEX_EOS, "$1")) continue; - if (regex_replace(t, t, "(.*[^\\\\])\\}\\'", "$1")) { + if (regex_replace(t, t, "(.*[^\\\\])\\}" REGEX_EOS, "$1")) { ++open_braces; continue; } @@ -933,13 +943,14 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & LYXERR(Debug::FIND, "Open braces: " << open_braces); LYXERR(Debug::FIND, "Close .*? : " << close_wildcards); LYXERR(Debug::FIND, "Replaced text (to be used as regex): " << par_as_string); + // If entered regexp must match at begin of searched string buffer - string regexp_str = string("\\`") + lead_as_regexp + par_as_string; + string regexp_str = lead_as_regexp + par_as_string; LYXERR(Debug::FIND, "Setting regexp to : '" << regexp_str << "'"); regexp = lyx::regex(regexp_str); // If entered regexp may match wherever in searched string buffer - string regexp2_str = string("\\`.*") + lead_as_regexp + ".*" + par_as_string; + string regexp2_str = lead_as_regexp + ".*" + par_as_string; LYXERR(Debug::FIND, "Setting regexp2 to: '" << regexp2_str << "'"); regexp2 = lyx::regex(regexp2_str); } @@ -959,8 +970,16 @@ int MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_begin) con if (use_regexp) { LYXERR(Debug::FIND, "Searching in regexp mode: at_begin=" << at_begin); - regex const & p_regexp = at_begin ? regexp : regexp2; - sregex_iterator re_it(str.begin(), str.end(), p_regexp); + regex const *p_regexp; + regex_constants::match_flag_type flags; + if (at_begin) { + flags = regex_constants::match_continuous; + p_regexp = ®exp; + } else { + flags = regex_constants::match_default; + p_regexp = ®exp2; + } + sregex_iterator re_it(str.begin(), str.end(), *p_regexp, flags); if (re_it == sregex_iterator()) return 0; match_results const & m = *re_it; diff --git a/src/support/regex.h b/src/support/regex.h index d99242a11d..615fe4f2d2 100644 --- a/src/support/regex.h +++ b/src/support/regex.h @@ -43,4 +43,14 @@ using LR_NS::regex_constants::match_flag_type; #undef LR_NS +#ifdef LYX_USE_STD_REGEX +// Match Begin and End of String when using ECMAScript (default std::regex) +#define REGEX_BOS "^" +#define REGEX_EOS "$" +#else +// Match Begin and End of String when using Perl RE (default boost::regex) +#define REGEX_BOS "\\`" +#define REGEX_EOS "\\'" +#endif + #endif -- 2.39.2