]> git.lyx.org Git - features.git/commitdiff
FindAdv: Eliminate a corner case in the binary search
authorKornel Benko <kornel@lyx.org>
Tue, 27 Nov 2018 18:10:27 +0000 (19:10 +0100)
committerKornel Benko <kornel@lyx.org>
Tue, 27 Nov 2018 18:10:27 +0000 (19:10 +0100)
Given the regex 'r.*r\b' and a string
"abc regular something cursor currently"
we expect to find "regular something cursor".
But while searching we may be confronted with input
"regular something cursor curr"
and so the searched string would be seen longer.

src/lyxfind.cpp

index 35be0d0143aed2e1a199ed1a4dca8676c60d7c3d..378b1c1d0203a2766f423da437d6863e4b74ea88 100644 (file)
@@ -2679,26 +2679,28 @@ int findAdvFinalize(DocIterator & cur, MatchStringAdv const & match)
             len = 0;
         }
        else {
-          int minl = 1;
-          int maxl = cur.lastpos() - cur.pos();
-          // Greedy behaviour while matching regexps
-          while (maxl > minl) {
-            int actual_match = match(cur, len);
-            if (actual_match == max_match) {
-              maxl = len;
-              len = (int)((maxl + minl)/2);
-            }
-            else if (actual_match < max_match) {
-              minl = len + 1;
-              len = (int)((maxl + minl)/2);
-            }
-            else {
-              // cannot happen, but in case of
-              LYXERR0("????");
-              max_match = actual_match;
-            }
-          }
-        }
+         int minl = 1;
+         int maxl = cur.lastpos() - cur.pos();
+         // Greedy behaviour while matching regexps
+         while (maxl > minl) {
+           int actual_match = match(cur, len);
+           if (actual_match >= max_match) {
+             // actual_match > max_match _can_ happen,
+             // if the search area splits
+             // some following word so that the regex
+             // (e.g. 'r.*r\b' matches 'r' from the middle of the
+             // splitted word)
+             // This means, the len value is too big
+             maxl = len;
+             len = (int)((maxl + minl)/2);
+           }
+           else {
+             // (actual_match < max_match)
+             minl = len + 1;
+             len = (int)((maxl + minl)/2);
+           }
+         }
+       }
        return len;
 }