aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-06-21 11:30:39 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-21 15:37:28 +0200
commit51358757c709f9c489aa6b13b34141edf84183fa (patch)
treea1649e684229819cd5bab9a0ed0f195adb737957
parentac4786ba002620eb4c046c847e69d6a12ea0e322 (diff)
downloadbusybox-w32-51358757c709f9c489aa6b13b34141edf84183fa.tar.gz
busybox-w32-51358757c709f9c489aa6b13b34141edf84183fa.tar.bz2
busybox-w32-51358757c709f9c489aa6b13b34141edf84183fa.zip
vi: fix backward search with GNU regex
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 <andrey.dobrovolsky.odessa@gmail.com> Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c33
1 files changed, 13 insertions, 20 deletions
diff --git a/editors/vi.c b/editors/vi.c
index b06270dfd..0baea615b 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -2376,9 +2376,7 @@ static char *char_search(char *p, const char *pat, int dir_and_range)
2376 struct re_pattern_buffer preg; 2376 struct re_pattern_buffer preg;
2377 const char *err; 2377 const char *err;
2378 char *q; 2378 char *q;
2379 int i; 2379 int i, size, range, start;
2380 int size;
2381 int range;
2382 2380
2383 re_syntax_options = RE_SYNTAX_POSIX_EXTENDED; 2381 re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
2384 if (ignorecase) 2382 if (ignorecase)
@@ -2403,31 +2401,26 @@ static char *char_search(char *p, const char *pat, int dir_and_range)
2403 2401
2404 // RANGE could be negative if we are searching backwards 2402 // RANGE could be negative if we are searching backwards
2405 range = q - p; 2403 range = q - p;
2406 q = p;
2407 size = range;
2408 if (range < 0) { 2404 if (range < 0) {
2409 size = -size; 2405 size = -range;
2410 q = p - size; 2406 start = size;
2411 if (q < text) 2407 } else {
2412 q = text; 2408 size = range;
2409 start = 0;
2413 } 2410 }
2411 q = p - start;
2412 if (q < text)
2413 q = text;
2414 // search for the compiled pattern, preg, in p[] 2414 // search for the compiled pattern, preg, in p[]
2415 // range < 0: search backward 2415 // range < 0, start == size: search backward
2416 // range > 0: search forward 2416 // range > 0, start == 0: search forward
2417 // 0 < start < size
2418 // re_search() < 0: not found or error 2417 // re_search() < 0: not found or error
2419 // re_search() >= 0: index of found pattern 2418 // re_search() >= 0: index of found pattern
2420 // struct pattern char int int int struct reg 2419 // struct pattern char int int int struct reg
2421 // re_search(*pattern_buffer, *string, size, start, range, *regs) 2420 // re_search(*pattern_buffer, *string, size, start, range, *regs)
2422 i = re_search(&preg, q, size, /*start:*/ 0, range, /*struct re_registers*:*/ NULL); 2421 i = re_search(&preg, q, size, start, range, /*struct re_registers*:*/ NULL);
2423 regfree(&preg); 2422 regfree(&preg);
2424 if (i < 0) 2423 return i < 0 ? NULL : q + i;
2425 return NULL;
2426 if (dir_and_range > 0) // FORWARD?
2427 p = p + i;
2428 else
2429 p = p - i;
2430 return p;
2431} 2424}
2432# else 2425# else
2433# if ENABLE_FEATURE_VI_SETOPTS 2426# if ENABLE_FEATURE_VI_SETOPTS