mirror of
https://github.com/neovim/neovim.git
synced 2025-09-08 04:18:18 +00:00
vim-patch:8.2.0938: NFA regexp uses tolower ()to compare ignore-case
Problem: NFA regexp uses tolower() to compare ignore-case. (Thayne McCombs)
Solution: Use utf_fold() when possible. (ref. neovim vim/vim#12456)
59de417b90
This commit is contained in:
@@ -4960,7 +4960,7 @@ static long find_match_text(colnr_T startcol, int regstart, char_u *match_text)
|
|||||||
int c2_len = PTR2LEN(s2);
|
int c2_len = PTR2LEN(s2);
|
||||||
int c2 = PTR2CHAR(s2);
|
int c2 = PTR2CHAR(s2);
|
||||||
|
|
||||||
if ((c1 != c2 && (!rex.reg_ic || mb_tolower(c1) != mb_tolower(c2)))
|
if ((c1 != c2 && (!rex.reg_ic || utf_fold(c1) != utf_fold(c2)))
|
||||||
|| c1_len != c2_len) {
|
|| c1_len != c2_len) {
|
||||||
match = false;
|
match = false;
|
||||||
break;
|
break;
|
||||||
@@ -5682,11 +5682,11 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (rex.reg_ic) {
|
if (rex.reg_ic) {
|
||||||
int curc_low = mb_tolower(curc);
|
int curc_low = utf_fold(curc);
|
||||||
int done = false;
|
int done = false;
|
||||||
|
|
||||||
for (; c1 <= c2; c1++) {
|
for (; c1 <= c2; c1++) {
|
||||||
if (mb_tolower(c1) == curc_low) {
|
if (utf_fold(c1) == curc_low) {
|
||||||
result = result_if_matched;
|
result = result_if_matched;
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -5698,8 +5698,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
|
|||||||
}
|
}
|
||||||
} else if (state->c < 0 ? check_char_class(state->c, curc)
|
} else if (state->c < 0 ? check_char_class(state->c, curc)
|
||||||
: (curc == state->c
|
: (curc == state->c
|
||||||
|| (rex.reg_ic && mb_tolower(curc)
|
|| (rex.reg_ic
|
||||||
== mb_tolower(state->c)))) {
|
&& utf_fold(curc) == utf_fold(state->c)))) {
|
||||||
result = result_if_matched;
|
result = result_if_matched;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -6106,7 +6106,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
|
|||||||
result = (c == curc);
|
result = (c == curc);
|
||||||
|
|
||||||
if (!result && rex.reg_ic) {
|
if (!result && rex.reg_ic) {
|
||||||
result = mb_tolower(c) == mb_tolower(curc);
|
result = utf_fold(c) == utf_fold(curc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If rex.reg_icombine is not set only skip over the character
|
// If rex.reg_icombine is not set only skip over the character
|
||||||
@@ -6260,8 +6260,9 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
|
|||||||
// Checking if the required start character matches is
|
// Checking if the required start character matches is
|
||||||
// cheaper than adding a state that won't match.
|
// cheaper than adding a state that won't match.
|
||||||
c = PTR2CHAR(reginput + clen);
|
c = PTR2CHAR(reginput + clen);
|
||||||
if (c != prog->regstart && (!rex.reg_ic || mb_tolower(c)
|
if (c != prog->regstart
|
||||||
!= mb_tolower(prog->regstart))) {
|
&& (!rex.reg_ic
|
||||||
|
|| utf_fold(c) != utf_fold(prog->regstart))) {
|
||||||
#ifdef REGEXP_DEBUG
|
#ifdef REGEXP_DEBUG
|
||||||
fprintf(log_fd,
|
fprintf(log_fd,
|
||||||
" Skipping start state, regstart does not match\n");
|
" Skipping start state, regstart does not match\n");
|
||||||
|
@@ -332,4 +332,23 @@ func Test_ambiwidth()
|
|||||||
set regexpengine& ambiwidth&
|
set regexpengine& ambiwidth&
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Run_regexp_ignore_case()
|
||||||
|
call assert_equal('iIİ', substitute('iIİ', '\([iIİ]\)', '\1', 'g'))
|
||||||
|
|
||||||
|
call assert_equal('iIx', substitute('iIİ', '\c\([İ]\)', 'x', 'g'))
|
||||||
|
call assert_equal('xxİ', substitute('iIİ', '\(i\c\)', 'x', 'g'))
|
||||||
|
call assert_equal('iIx', substitute('iIİ', '\(İ\c\)', 'x', 'g'))
|
||||||
|
call assert_equal('iIx', substitute('iIİ', '\c\(\%u0130\)', 'x', 'g'))
|
||||||
|
call assert_equal('iIx', substitute('iIİ', '\c\([\u0130]\)', 'x', 'g'))
|
||||||
|
call assert_equal('iIx', substitute('iIİ', '\c\([\u012f-\u0131]\)', 'x', 'g'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_regexp_ignore_case()
|
||||||
|
set regexpengine=1
|
||||||
|
call Run_regexp_ignore_case()
|
||||||
|
set regexpengine=2
|
||||||
|
call Run_regexp_ignore_case()
|
||||||
|
set regexpengine&
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
Reference in New Issue
Block a user