With FEATURE_VI_REGEX_SEARCH enabled backward searches don't work.
This is problematic on distros that enable regexes, such as Tiny
Core Linux and Fedora.

When calling GNU re_search() with a negative range parameter
(indicating a backward search) the start offset must be set to
the end of the area being searched.

The return value of re_search() is the offset of the matched pattern
from the start of the area being searched.  For a successful search
(positive return value) char_search() can return the pointer to
the start of the area plus the offset.

FEATURE_VI_REGEX_SEARCH isn't enabled by default but when it is:

function                                             old     new   delta
char_search                                          256     247      -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-9)               Total: -9 bytes

Signed-off-by: Andrey Dobrovolsky <[email protected]>
Signed-off-by: Ron Yorston <[email protected]>
---
 editors/vi.c | 33 +++++++++++++--------------------
 1 file changed, 13 insertions(+), 20 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index d85cdd98d..87d6a628e 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2371,9 +2371,7 @@ static char *char_search(char *p, const char *pat, int 
dir_and_range)
        struct re_pattern_buffer preg;
        const char *err;
        char *q;
-       int i;
-       int size;
-       int range;
+       int i, size, range, start;
 
        re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
        if (ignorecase)
@@ -2398,31 +2396,26 @@ static char *char_search(char *p, const char *pat, int 
dir_and_range)
 
        // RANGE could be negative if we are searching backwards
        range = q - p;
-       q = p;
-       size = range;
        if (range < 0) {
-               size = -size;
-               q = p - size;
-               if (q < text)
-                       q = text;
+               size = -range;
+               start = size;
+       } else {
+               size = range;
+               start = 0;
        }
+       q = p - start;
+       if (q < text)
+               q = text;
        // search for the compiled pattern, preg, in p[]
-       // range < 0: search backward
-       // range > 0: search forward
-       // 0 < start < size
+       // range < 0, start == size: search backward
+       // range > 0, start == 0: search forward
        // re_search() < 0: not found or error
        // re_search() >= 0: index of found pattern
        //           struct pattern   char     int   int    int    struct reg
        // re_search(*pattern_buffer, *string, size, start, range, *regs)
-       i = re_search(&preg, q, size, /*start:*/ 0, range, /*struct 
re_registers*:*/ NULL);
+       i = re_search(&preg, q, size, start, range, /*struct re_registers*:*/ 
NULL);
        regfree(&preg);
-       if (i < 0)
-               return NULL;
-       if (dir_and_range > 0) // FORWARD?
-               p = p + i;
-       else
-               p = p - i;
-       return p;
+       return i < 0 ? NULL : q + i;
 }
 # else
 #  if ENABLE_FEATURE_VI_SETOPTS
-- 
2.31.1

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to