]> git.lyx.org Git - lyx.git/blobdiff - src/lyxfind.cpp
Vietnamese no longer requires any special handling.
[lyx.git] / src / lyxfind.cpp
index 57a25e929f38ee911c0c27e4389a4eb0af680db0..4b8da77ac0c33ff572c4af9904d64b7d0609d7b0 100644 (file)
@@ -303,7 +303,7 @@ pair<bool, int> 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("(<?!\\\\\\\\textbackslash)\\{", "\\\\\\{"));
                escape_map.push_back(P("(<?!\\\\\\\\textbackslash\\\\\\{)\\}", "\\\\\\}"));
                escape_map.push_back(P("\\[", "\\{\\[\\}"));
                escape_map.push_back(P("\\]", "\\{\\]\\}"));
-               escape_map.push_back(P("\\^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)"));
+               escape_map.push_back(P("\\^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\textasciicircum|\\\\mathcircumflex)"));
                escape_map.push_back(P("%", "\\\\\\%"));
        }
        return escape_map;
@@ -672,7 +672,7 @@ 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);
+       lyx::regex e(searchstr, regex_constants::ECMAScript);
        ostringstream oss;
        ostream_iterator<char, char> 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 = &regexp;
+               } else {
+                       flags = regex_constants::match_default;
+                       p_regexp = &regexp2;
+               }
+               sregex_iterator re_it(str.begin(), str.end(), *p_regexp, flags);
+               if (re_it == sregex_iterator())
+                       return 0;
                match_results<string::const_iterator> 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