X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfind.cpp;h=4b8da77ac0c33ff572c4af9904d64b7d0609d7b0;hb=7e121117bb320368a9164d3a39432a4b54789538;hp=57a25e929f38ee911c0c27e4389a4eb0af680db0;hpb=bda9d95fad3ab0c8a90c2681f5cd7dc09628a2cc;p=lyx.git diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index 57a25e929f..4b8da77ac0 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -303,7 +303,7 @@ pair replaceOne(BufferView * bv, docstring searchstr, return make_pair(true, 1); } -} // namespace anon +} // namespace docstring const find2string(docstring const & search, @@ -517,7 +517,7 @@ bool findChange(BufferView * bv, bool forward) return selectChange(cur, forward); } -} +} // namespace bool findNextChange(BufferView * bv) { @@ -556,7 +556,7 @@ Escapes const & get_regexp_escapes() escape_map.push_back(P(".", "_x_.")); escape_map.push_back(P("\\", "(?:\\\\|\\\\backslash)")); escape_map.push_back(P("~", "(?:\\\\textasciitilde|\\\\sim)")); - escape_map.push_back(P("^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)")); + escape_map.push_back(P("^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\textasciicircum|\\\\mathcircumflex)")); escape_map.push_back(P("_x_", "\\")); } return escape_map; @@ -589,12 +589,12 @@ Escapes const & get_regexp_latex_escapes() static Escapes escape_map; if (escape_map.empty()) { - escape_map.push_back(P("\\\\", "(?:\\\\\\\\|\\\\backslash|\\\\textbackslash\\{\\})")); + escape_map.push_back(P("\\\\", "(?:\\\\\\\\|\\\\backslash|\\\\textbackslash\\{\\}|\\\\textbackslash)")); escape_map.push_back(P("( it(oss); lyx::regex_replace(it, s.begin(), s.end(), e, replacestr); @@ -841,11 +841,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 +857,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 +933,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,21 +960,31 @@ 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; // Check braces on the segment that matched the entire regexp expression, // plus the last subexpression, if a (.*?) was inserted in the constructor. if (!braces_match(m[0].first, m[0].second, open_braces)) return 0; - + // Check braces on segments that matched all (.*?) subexpressions, // except the last "padding" one inserted by lyx. for (size_t i = 1; i < m.size() - 1; ++i) if (!braces_match(m[i].first, m[i].second)) return false; - + // Exclude from the returned match length any length // due to close wildcards added at end of regexp if (close_wildcards == 0) @@ -1327,7 +1338,7 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) } -} // anonym namespace +} // namespace docstring stringifyFromForSearch(FindAndReplaceOptions const & opt, @@ -1408,13 +1419,15 @@ static void changeFirstCase(Buffer & buffer, TextCase first_case, TextCase other pit->changeCase(buffer.params(), pos_type(1), right, others_case); } -} // anon namespace +} // namespace /// static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, MatchStringAdv & matchAdv) { Cursor & cur = bv->cursor(); - if (opt.repl_buf_name == docstring()) + if (opt.repl_buf_name == docstring() + || theBufferList().getBuffer(FileName(to_utf8(opt.repl_buf_name)), true) == 0 + || theBufferList().getBuffer(FileName(to_utf8(opt.find_buf_name)), true) == 0) return; DocIterator sel_beg = cur.selectionBegin(); @@ -1475,10 +1488,8 @@ static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, M docstring repl_latex = ods.str(); LYXERR(Debug::FIND, "Latexified replace_buffer: '" << repl_latex << "'"); string s; - // false positive from coverity - // coverity[CHECKED_RETURN] - regex_replace(to_utf8(repl_latex), s, "\\$(.*)\\$", "$1"); - regex_replace(s, s, "\\\\\\[(.*)\\\\\\]", "$1"); + (void)regex_replace(to_utf8(repl_latex), s, "\\$(.*)\\$", "$1"); + (void)regex_replace(s, s, "\\\\\\[(.*)\\\\\\]", "$1"); repl_latex = from_utf8(s); LYXERR(Debug::FIND, "Replacing by insert()ing latex: '" << repl_latex << "' cur=" << cur << " with depth=" << cur.depth()); MathData ar(cur.buffer()); @@ -1503,6 +1514,11 @@ bool findAdv(BufferView * bv, FindAndReplaceOptions const & opt) DocIterator cur; int match_len = 0; + // e.g., when invoking word-findadv from mini-buffer wither with + // wrong options syntax or before ever opening advanced F&R pane + if (theBufferList().getBuffer(FileName(to_utf8(opt.find_buf_name)), true) == 0) + return false; + try { MatchStringAdv matchAdv(bv->buffer(), opt); int length = bv->cursor().selectionEnd().pos() - bv->cursor().selectionBegin().pos(); @@ -1596,4 +1612,4 @@ istringstream & operator>>(istringstream & is, FindAndReplaceOptions & opt) return is; } -} // lyx namespace +} // namespace lyx