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>
This commit is contained in:
parent
ac4786ba00
commit
51358757c7
31
editors/vi.c
31
editors/vi.c
@ -2376,9 +2376,7 @@ static char *char_search(char *p, const char *pat, int dir_and_range)
|
|||||||
struct re_pattern_buffer preg;
|
struct re_pattern_buffer preg;
|
||||||
const char *err;
|
const char *err;
|
||||||
char *q;
|
char *q;
|
||||||
int i;
|
int i, size, range, start;
|
||||||
int size;
|
|
||||||
int range;
|
|
||||||
|
|
||||||
re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
|
re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
|
||||||
if (ignorecase)
|
if (ignorecase)
|
||||||
@ -2403,31 +2401,26 @@ static char *char_search(char *p, const char *pat, int dir_and_range)
|
|||||||
|
|
||||||
// RANGE could be negative if we are searching backwards
|
// RANGE could be negative if we are searching backwards
|
||||||
range = q - p;
|
range = q - p;
|
||||||
q = p;
|
|
||||||
size = range;
|
|
||||||
if (range < 0) {
|
if (range < 0) {
|
||||||
size = -size;
|
size = -range;
|
||||||
q = p - size;
|
start = size;
|
||||||
|
} else {
|
||||||
|
size = range;
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
q = p - start;
|
||||||
if (q < text)
|
if (q < text)
|
||||||
q = text;
|
q = text;
|
||||||
}
|
|
||||||
// search for the compiled pattern, preg, in p[]
|
// search for the compiled pattern, preg, in p[]
|
||||||
// range < 0: search backward
|
// range < 0, start == size: search backward
|
||||||
// range > 0: search forward
|
// range > 0, start == 0: search forward
|
||||||
// 0 < start < size
|
|
||||||
// re_search() < 0: not found or error
|
// re_search() < 0: not found or error
|
||||||
// re_search() >= 0: index of found pattern
|
// re_search() >= 0: index of found pattern
|
||||||
// struct pattern char int int int struct reg
|
// struct pattern char int int int struct reg
|
||||||
// re_search(*pattern_buffer, *string, size, start, range, *regs)
|
// 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);
|
regfree(&preg);
|
||||||
if (i < 0)
|
return i < 0 ? NULL : q + i;
|
||||||
return NULL;
|
|
||||||
if (dir_and_range > 0) // FORWARD?
|
|
||||||
p = p + i;
|
|
||||||
else
|
|
||||||
p = p - i;
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
# if ENABLE_FEATURE_VI_SETOPTS
|
# if ENABLE_FEATURE_VI_SETOPTS
|
||||||
|
Loading…
Reference in New Issue
Block a user