]> git.lyx.org Git - features.git/blobdiff - src/lyxfind.cpp
FindAdv: Fix expression checking for 'int' as if it were bool
[features.git] / src / lyxfind.cpp
index 480d4d18bab54e8248d2faca06952f0128a83cb0..ac6366c2620e4ad655b03063078a2d32f9247dd8 100644 (file)
@@ -1066,13 +1066,19 @@ public:
         ** constructor as opt.search, under the opt.* options settings.
         **
         ** @param at_begin
-        **     If set, then match is searched only against beginning of text starting at cur.
-        **     If unset, then match is searched anywhere in text starting at cur.
+        **     If set to MatchStringAdv::MatchFromStart,
+        **       then match is searched only against beginning of text starting at cur.
+        **     Otherwise the match is searched anywhere in text starting at cur.
         **
         ** @return
         ** The length of the matching text, or zero if no match was found.
         **/
-       MatchResult operator()(DocIterator const & cur, int len = -1, bool at_begin = true) const;
+       enum matchType {
+               MatchAnyPlace,
+               MatchFromStart
+       };
+       string matchTypeAsString(matchType const x) const { return (x == MatchFromStart ? "MatchFromStart" : "MatchAnyPlace"); }
+       MatchResult operator()(DocIterator const & cur, int len, matchType at_begin) const;
 #if QTSEARCH
        bool regexIsValid;
        string regexError;
@@ -1088,7 +1094,7 @@ public:
 
 private:
        /// Auxiliary find method (does not account for opt.matchword)
-       MatchResult findAux(DocIterator const & cur, int len = -1, bool at_begin = true) const;
+       MatchResult findAux(DocIterator const & cur, int len, matchType at_begin) const;
        void CreateRegexp(FindAndReplaceOptions const & opt, string regexp_str, string regexp2_str, string par_as_string = "");
 
        /** Normalize a stringified or latexified LyX paragraph.
@@ -1428,8 +1434,8 @@ public:
        string par;
        int ignoreidx;
        static vector<Border> borders;
-       int depts[MAXOPENED];
-       int closes[MAXOPENED];
+       static vector<int> depts;
+       static vector<int> closes;
        int actualdeptindex;
        int previousNotIgnored(int) const;
        int nextNotIgnored(int) const;
@@ -1454,6 +1460,8 @@ public:
 };
 
 vector<Border> Intervall::borders = vector<Border>(30);
+vector<int> Intervall::depts = vector<int>(30);
+vector<int> Intervall::closes = vector<int>(30);
 
 int Intervall::isOpeningPar(int pos) const
 {
@@ -1487,6 +1495,8 @@ void Intervall::setForDefaultLang(KeyInfo const & defLang) const
        }
 }
 
+#if 0
+// Not needed, because dpts and closes are now dynamically expanded
 static void checkDepthIndex(int val)
 {
        static int maxdepthidx = MAXOPENED-2;
@@ -1500,6 +1510,7 @@ static void checkDepthIndex(int val)
                LYXERR(Debug::INFO, "maxdepthidx now " << val);
        }
 }
+#endif
 
 #if 0
 // Not needed, because borders are now dynamically expanded
@@ -2049,7 +2060,8 @@ void Intervall::removeAccents()
        if (accents.empty())
                buildAccentsMap();
        static regex const accre("\\\\("
-                                "([\\S]|[A-Za-z]+)\\{[^\\{\\}]+\\}"
+                                "([\\S]|[A-Za-z]+)\\{[^\\\\\\{\\}]+\\}"
+                                "|([\\S]|[A-Za-z]+)\\{\\\\[ij](math)?\\}"
                                 "|("
                                 "(backslash ([lL]y[xX]|[tT]e[xX]|[lL]a[tT]e[xX]e?|lyxarrow))"
                                 "|[A-Za-z]+"
@@ -2085,9 +2097,13 @@ void Intervall::removeAccents()
 void Intervall::handleOpenP(int i)
 {
        actualdeptindex++;
+       if ((size_t) actualdeptindex >= depts.size()) {
+               depts.resize(actualdeptindex + 30);
+               closes.resize(actualdeptindex + 30);
+       }
        depts[actualdeptindex] = i+1;
        closes[actualdeptindex] = -1;
-       checkDepthIndex(actualdeptindex);
+       // checkDepthIndex(actualdeptindex);
 }
 
 void Intervall::handleCloseP(int i, bool closingAllowed)
@@ -2763,7 +2779,8 @@ void LatexInfo::buildKeys(bool isPatternString)
        if (keysBuilt && !isPatternString) return;
 
        // Keys to ignore in any case
-       makeKey("text|textcyrillic|lyxmathsym|ensuremath", KeyInfo(KeyInfo::headRemove, 1, true), true);
+       makeKey("text|lyxmathsym|ensuremath", KeyInfo(KeyInfo::headRemove, 1, true), true);
+       makeKey("nonumber|notag", KeyInfo(KeyInfo::headRemove, 0, true), true);
        // Known standard keys with 1 parameter.
        // Split is done, if not at start of region
        makeKey("textsf|textss|texttt", KeyInfo(KeyInfo::isStandard, 1, ignoreFormats.getFamily()), isPatternString);
@@ -3641,7 +3658,7 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions & opt)
                CreateRegexp(opt, "", "", "");
                return;
        }
-       use_regexp = lyx::to_utf8(ds).find("\\regexp{") != std::string::npos;
+       use_regexp = ds.find(from_utf8("\\regexp{")) != std::string::npos;
        if (opt.replace_all && previous_single_replace) {
                previous_single_replace = false;
                num_replaced = 0;
@@ -3730,7 +3747,7 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions & opt)
                                        break;
                        }
                        if (lng < par_as_string.size())
-                               par_as_string = par_as_string.substr(0,lng);
+                               par_as_string.resize(lng);
                }
                LYXERR(Debug::FINDVERBOSE, "par_as_string after correctRegex is '" << par_as_string << "'");
                if ((lng > 0) && (par_as_string[0] == '^')) {
@@ -3768,14 +3785,11 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions & opt)
        }
 }
 
-MatchResult MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_begin) const
+MatchResult MatchStringAdv::findAux(DocIterator const & cur, int len, MatchStringAdv::matchType at_begin) const
 {
        MatchResult mres;
 
        mres.searched_size = len;
-       if (at_begin &&
-                       (opt.restr == FindAndReplaceOptions::R_ONLY_MATHS && !cur.inMathed()) )
-               return mres;
 
        docstring docstr = stringifyFromForSearch(opt, cur, len);
        string str;
@@ -3802,12 +3816,12 @@ MatchResult MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_be
        LASSERT(use_regexp, /**/);
        {
                // use_regexp always true
-               LYXERR(Debug::FINDVERBOSE, "Searching in regexp mode: at_begin=" << at_begin);
+               LYXERR(Debug::FINDVERBOSE, "Searching in regexp mode: at_begin=" << matchTypeAsString(at_begin));
 #if QTSEARCH
                QString qstr = QString::fromStdString(str);
                QRegularExpression const *p_regexp;
                QRegularExpression::MatchType flags = QRegularExpression::NormalMatch;
-               if (at_begin) {
+               if (at_begin == MatchStringAdv::MatchFromStart) {
                        p_regexp = &regexp;
                } else {
                        p_regexp = &regexp2;
@@ -3818,7 +3832,7 @@ MatchResult MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_be
 #else
                regex const *p_regexp;
                regex_constants::match_flag_type flags;
-               if (at_begin) {
+               if (at_begin == MatchStringAdv::MatchFromStart) {
                        flags = regex_constants::match_continuous;
                        p_regexp = &regexp;
                } else {
@@ -3932,12 +3946,12 @@ MatchResult MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_be
 }
 
 
-MatchResult MatchStringAdv::operator()(DocIterator const & cur, int len, bool at_begin) const
+MatchResult MatchStringAdv::operator()(DocIterator const & cur, int len, MatchStringAdv::matchType at_begin) const
 {
        MatchResult mres = findAux(cur, len, at_begin);
        int res = mres.match_len;
        LYXERR(Debug::FINDVERBOSE,
-              "res=" << res << ", at_begin=" << at_begin
+              "res=" << res << ", at_begin=" << matchTypeAsString(at_begin)
               << ", matchAtStart=" << opt.matchAtStart
               << ", inTexted=" << cur.inTexted());
        if (opt.matchAtStart) {
@@ -4010,20 +4024,25 @@ static string convertLF2Space(docstring const &s, bool ignore_format)
                                if ((pos > start + 2) &&
                                    (s[pos+1] == '~' || isSpace(s[pos+1]) ||
                                     s[pos-3] == '~' || isSpace(s[pos-3]))) {
-                                       // discard '\n'
+                                       // discard "\\\\\n", do not replace with space
                                        dospace = false;
                                }
                        }
-                       else if ((pos > start) &&
-                            s[pos-1] == '%') {
-                               skip = 1;
-                               while ((pos > start+skip) && (s[pos-1-skip] == '%'))
-                                       skip++;
-                               if ((pos > start+skip) &&
-                                   (s[pos+1] == '~' || isSpace(s[pos+1]) ||
-                                    s[pos-1-skip] == '~' || isSpace(s[pos-1-skip]))) {
-                                       // discard '%%%%%\n'
+                       else if (pos > start) {
+                               if (s[pos-1] == '%') {
+                                       skip = 1;
+                                       while ((pos > start+skip) && (s[pos-1-skip] == '%'))
+                                               skip++;
+                                       if ((pos > start+skip) &&
+                                           (s[pos+1] == '~' || isSpace(s[pos+1]) ||
+                                            s[pos-1-skip] == '~' || isSpace(s[pos-1-skip]))) {
+                                               // discard '%%%%%\n'
+                                               dospace = false;
+                                       }
+                               }
+                               else if (!isAlnumASCII(s[pos+1]) || !isAlnumASCII(s[pos-1])) {
                                        dospace = false;
+                                       skip = 0;       // remove the '\n' only
                                }
                        }
                }
@@ -4290,13 +4309,13 @@ MatchResult findAdvFinalize(DocIterator & cur, MatchStringAdv const & match, Mat
        // either one sees "http://www.bla.bla" or nothing
        // so the search for "www" gives prefix_len = 7 (== sizeof("http://")
        // and although we search for only 3 chars, we find the whole hyperlink inset
-       bool at_begin = (expected.match_prefix == 0);
+       MatchStringAdv::matchType at_begin = (expected.match_prefix == 0) ? MatchStringAdv::MatchFromStart : MatchStringAdv::MatchAnyPlace;
        if (!match.opt.forward && match.opt.ignoreformat) {
                if (expected.pos > 0)
                        return fail;
        }
-       LASSERT(at_begin, /**/);
-       if (expected.match_len > 0 && at_begin) {
+       LASSERT(at_begin == MatchStringAdv::MatchFromStart, /**/);
+       if (expected.match_len > 0 && at_begin == MatchStringAdv::MatchFromStart) {
                // Search for deepest match
                old_cur = cur;
                max_match = expected;
@@ -4328,11 +4347,14 @@ MatchResult findAdvFinalize(DocIterator & cur, MatchStringAdv const & match, Mat
        }
        else {
                // (expected.match_len <= 0)
-               mres = match(cur);      /* match valid only if not searching whole words */
+               mres = match(cur, -1, MatchStringAdv::MatchFromStart);      /* match valid only if not searching whole words */
                displayMres(mres, "Start with negative match", cur);
                max_match = mres;
        }
-       if (max_match.match_len <= 0) return fail;
+       // Only now we are really at_begin
+       if ((max_match.match_len <= 0) ||
+           (match.opt.restr == FindAndReplaceOptions::R_ONLY_MATHS && !cur.inMathed()))
+               return fail;
        LYXERR(Debug::FINDVERBOSE, "Ok");
 
        // Compute the match length
@@ -4430,7 +4452,7 @@ int findForwardAdv(DocIterator & cur, MatchStringAdv & match)
        while (!theApp()->longOperationCancelled() && cur) {
                //(void) findAdvForwardInnermost(cur);
                LYXERR(Debug::FINDVERBOSE, "findForwardAdv() cur: " << cur);
-               MatchResult mres = match(cur, -1, false);
+               MatchResult mres = match(cur, -1, MatchStringAdv::MatchAnyPlace);
                string msg = "Starting";
                if (repeat)
                        msg = "Repeated";
@@ -4468,7 +4490,7 @@ int findForwardAdv(DocIterator & cur, MatchStringAdv & match)
                                        continue;
                                }
                                cur.pos() = cur.pos() + increment;
-                               MatchResult mres2 = match(cur, -1, false);
+                               MatchResult mres2 = match(cur, -1, MatchStringAdv::MatchAnyPlace);
                                displayMres(mres2, "findForwardAdv loop", cur)
                                                switch (interpretMatch(mres, mres2)) {
                                        case MatchResult::newIsTooFar:
@@ -4544,7 +4566,8 @@ MatchResult findMostBackwards(DocIterator & cur, MatchStringAdv const & match, M
                LYXERR(Debug::FINDVERBOSE, "findMostBackwards(): cur=" << cur);
                DocIterator new_cur = cur;
                new_cur.backwardPos();
-               if (new_cur == cur || &new_cur.inset() != &inset || !match(new_cur).match_len)
+               if (new_cur == cur || &new_cur.inset() != &inset
+                   || match(new_cur, -1, MatchStringAdv::MatchFromStart).match_len <= 0)
                        break;
                MatchResult new_mr = findAdvFinalize(new_cur, match, expected);
                if (new_mr.match_len == mr.match_len)
@@ -4570,7 +4593,7 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match)
        bool pit_changed = false;
        do {
                cur.pos() = 0;
-               MatchResult found_match = match(cur, -1, false);
+               MatchResult found_match = match(cur, -1, MatchStringAdv::MatchAnyPlace);
 
                if (found_match.match_len > 0) {
                        if (pit_changed)
@@ -4580,7 +4603,7 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match)
                        LYXERR(Debug::FINDVERBOSE, "findBackAdv2: cur: " << cur);
                        DocIterator cur_prev_iter;
                        do {
-                               found_match = match(cur);
+                               found_match = match(cur, -1, MatchStringAdv::MatchFromStart);
                                LYXERR(Debug::FINDVERBOSE, "findBackAdv3: found_match="
                                       << (found_match.match_len > 0) << ", cur: " << cur);
                                if (found_match.match_len > 0) {
@@ -4742,7 +4765,7 @@ static int findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, Ma
                return 0;
        LASSERT(sel_len > 0, return 0);
 
-       if (!matchAdv(sel_beg, sel_len).match_len)
+       if (matchAdv(sel_beg, sel_len, MatchStringAdv::MatchFromStart).match_len <= 0)
                return 0;
 
        // Build a copy of the replace buffer, adapted to the KeepCase option