diff options
author | Ron Yorston <rmy@pobox.com> | 2021-06-21 11:30:39 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-21 15:37:28 +0200 |
commit | 51358757c709f9c489aa6b13b34141edf84183fa (patch) | |
tree | a1649e684229819cd5bab9a0ed0f195adb737957 | |
parent | ac4786ba002620eb4c046c847e69d6a12ea0e322 (diff) | |
download | busybox-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.c | 33 |
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 |