regexp_nfa.c: Speed up find_match_text()

An extra test in commit 0a116c828d was
introduced, to check for end of string with a call to strlen(). This was
necessary, because an incorrect length for invalid byte sequences was
used to step through the string. This slowed down find_match_text()
compared to vim's version.

To speed up things, the extra check was removed and a sequence length
of 1 for invalid byte sequences is used.

Fixes issue #3486
This commit is contained in:
oni-link 2016-01-24 22:18:44 +01:00
parent e1d81178cc
commit 291495a7b0

View File

@ -4762,48 +4762,54 @@ static int skip_to_start(int c, colnr_T *colp)
*/ */
static long find_match_text(colnr_T startcol, int regstart, char_u *match_text) static long find_match_text(colnr_T startcol, int regstart, char_u *match_text)
{ {
colnr_T col = startcol; #define PTR2LEN(x) enc_utf8 ? utf_ptr2len(x) : MB_PTR2LEN(x)
int c1, c2;
int len1, len2;
int match;
for (;; ) { colnr_T col = startcol;
match = TRUE; int regstart_len = PTR2LEN(regline + startcol);
len2 = MB_CHAR2LEN(regstart); /* skip regstart */
for (len1 = 0; match_text[len1] != NUL; len1 += MB_CHAR2LEN(c1)) { for (;;) {
c1 = PTR2CHAR(match_text + len1); bool match = true;
c2 = PTR2CHAR(regline + col + len2); char_u *s1 = match_text;
if (c1 != c2 && (!ireg_ic || vim_tolower(c1) != vim_tolower(c2))) { char_u *s2 = regline + col + regstart_len; // skip regstart
match = FALSE; while (*s1) {
int c1_len = PTR2LEN(s1);
int c1 = PTR2CHAR(s1);
int c2_len = PTR2LEN(s2);
int c2 = PTR2CHAR(s2);
if ((c1 != c2 && (!ireg_ic || vim_tolower(c1) != vim_tolower(c2))) ||
c1_len != c2_len) {
match = false;
break; break;
} }
len2 += MB_CHAR2LEN(c2); s1 += c1_len;
s2 += c2_len;
} }
if (match if (match
/* check that no composing char follows */ // check that no composing char follows
&& !(enc_utf8 && !(enc_utf8 && utf_iscomposing(PTR2CHAR(s2)))) {
&& STRLEN(regline) > (size_t)(col + len2)
&& utf_iscomposing(PTR2CHAR(regline + col + len2)))
) {
cleanup_subexpr(); cleanup_subexpr();
if (REG_MULTI) { if (REG_MULTI) {
reg_startpos[0].lnum = reglnum; reg_startpos[0].lnum = reglnum;
reg_startpos[0].col = col; reg_startpos[0].col = col;
reg_endpos[0].lnum = reglnum; reg_endpos[0].lnum = reglnum;
reg_endpos[0].col = col + len2; reg_endpos[0].col = s2 - regline;
} else { } else {
reg_startp[0] = regline + col; reg_startp[0] = regline + col;
reg_endp[0] = regline + col + len2; reg_endp[0] = s2;
} }
return 1L; return 1L;
} }
/* Try finding regstart after the current match. */ // Try finding regstart after the current match.
col += MB_CHAR2LEN(regstart); /* skip regstart */ col += regstart_len; // skip regstart
if (skip_to_start(regstart, &col) == FAIL) if (skip_to_start(regstart, &col) == FAIL) {
break; break;
}
} }
return 0L; return 0L;
#undef PTR2LEN
} }
/* /*