commit 1cd80ff6c8c2509f014c10c5e7840933e1d8e126
Author: Kornel Benko <[email protected]>
Date:   Tue Nov 27 19:10:27 2018 +0100

    FindAdv: Eliminate a corner case in the binary search
    
    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 |   42 ++++++++++++++++++++++--------------------
 1 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp
index 35be0d0..378b1c1 100644
--- a/src/lyxfind.cpp
+++ b/src/lyxfind.cpp
@@ -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;
 }
 

Reply via email to