forked from aniani/vim
updated for version 7.3.1117
Problem: New regexp engine: \%[abc] not supported. Solution: Implement \%[abc]. Add tests.
This commit is contained in:
@@ -61,6 +61,7 @@ enum
|
|||||||
NFA_COMPOSING, /* Next nodes in NFA are part of the
|
NFA_COMPOSING, /* Next nodes in NFA are part of the
|
||||||
composing multibyte char */
|
composing multibyte char */
|
||||||
NFA_END_COMPOSING, /* End of a composing char in the NFA */
|
NFA_END_COMPOSING, /* End of a composing char in the NFA */
|
||||||
|
NFA_OPT_CHARS, /* \%[abc] */
|
||||||
|
|
||||||
/* The following are used only in the postfix form, not in the NFA */
|
/* The following are used only in the postfix form, not in the NFA */
|
||||||
NFA_PREV_ATOM_NO_WIDTH, /* Used for \@= */
|
NFA_PREV_ATOM_NO_WIDTH, /* Used for \@= */
|
||||||
@@ -972,8 +973,21 @@ nfa_regatom()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
/* TODO: \%[abc] not supported yet */
|
{
|
||||||
return FAIL;
|
int n;
|
||||||
|
|
||||||
|
/* \%[abc] */
|
||||||
|
for (n = 0; (c = getchr()) != ']'; ++n)
|
||||||
|
{
|
||||||
|
if (c == NUL)
|
||||||
|
EMSG2_RET_FAIL(_(e_missing_sb),
|
||||||
|
reg_magic == MAGIC_ALL);
|
||||||
|
EMIT(c);
|
||||||
|
}
|
||||||
|
EMIT(NFA_OPT_CHARS);
|
||||||
|
EMIT(n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@@ -989,7 +1003,6 @@ nfa_regatom()
|
|||||||
}
|
}
|
||||||
if (c == 'l' || c == 'c' || c == 'v')
|
if (c == 'l' || c == 'c' || c == 'v')
|
||||||
{
|
{
|
||||||
EMIT(n);
|
|
||||||
if (c == 'l')
|
if (c == 'l')
|
||||||
/* \%{n}l \%{n}<l \%{n}>l */
|
/* \%{n}l \%{n}<l \%{n}>l */
|
||||||
EMIT(cmp == '<' ? NFA_LNUM_LT :
|
EMIT(cmp == '<' ? NFA_LNUM_LT :
|
||||||
@@ -1002,14 +1015,15 @@ nfa_regatom()
|
|||||||
/* \%{n}v \%{n}<v \%{n}>v */
|
/* \%{n}v \%{n}<v \%{n}>v */
|
||||||
EMIT(cmp == '<' ? NFA_VCOL_LT :
|
EMIT(cmp == '<' ? NFA_VCOL_LT :
|
||||||
cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
|
cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
|
||||||
|
EMIT(n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (c == '\'' && n == 0)
|
else if (c == '\'' && n == 0)
|
||||||
{
|
{
|
||||||
/* \%'m \%<'m \%>'m */
|
/* \%'m \%<'m \%>'m */
|
||||||
EMIT(getchr());
|
|
||||||
EMIT(cmp == '<' ? NFA_MARK_LT :
|
EMIT(cmp == '<' ? NFA_MARK_LT :
|
||||||
cmp == '>' ? NFA_MARK_GT : NFA_MARK);
|
cmp == '>' ? NFA_MARK_GT : NFA_MARK);
|
||||||
|
EMIT(getchr());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1885,6 +1899,7 @@ nfa_set_code(c)
|
|||||||
|
|
||||||
case NFA_COMPOSING: STRCPY(code, "NFA_COMPOSING"); break;
|
case NFA_COMPOSING: STRCPY(code, "NFA_COMPOSING"); break;
|
||||||
case NFA_END_COMPOSING: STRCPY(code, "NFA_END_COMPOSING"); break;
|
case NFA_END_COMPOSING: STRCPY(code, "NFA_END_COMPOSING"); break;
|
||||||
|
case NFA_OPT_CHARS: STRCPY(code, "NFA_OPT_CHARS"); break;
|
||||||
|
|
||||||
case NFA_MOPEN:
|
case NFA_MOPEN:
|
||||||
case NFA_MOPEN1:
|
case NFA_MOPEN1:
|
||||||
@@ -2558,10 +2573,49 @@ post2nfa(postfix, end, nfa_calc_size)
|
|||||||
PUSH(frag(s, list1(&s->out)));
|
PUSH(frag(s, list1(&s->out)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NFA_OPT_CHARS:
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
/* \%[abc] */
|
||||||
|
n = *++p; /* get number of characters */
|
||||||
|
if (nfa_calc_size == TRUE)
|
||||||
|
{
|
||||||
|
nstate += n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
e1.out = NULL; /* stores list with out1's */
|
||||||
|
s1 = NULL; /* previous NFA_SPLIT to connect to */
|
||||||
|
while (n-- > 0)
|
||||||
|
{
|
||||||
|
e = POP(); /* get character */
|
||||||
|
s = alloc_state(NFA_SPLIT, e.start, NULL);
|
||||||
|
if (s == NULL)
|
||||||
|
goto theend;
|
||||||
|
if (e1.out == NULL)
|
||||||
|
e1 = e;
|
||||||
|
patch(e.out, s1);
|
||||||
|
append(e1.out, list1(&s->out1));
|
||||||
|
s1 = s;
|
||||||
|
}
|
||||||
|
PUSH(frag(s, e1.out));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case NFA_PREV_ATOM_NO_WIDTH:
|
case NFA_PREV_ATOM_NO_WIDTH:
|
||||||
case NFA_PREV_ATOM_NO_WIDTH_NEG:
|
case NFA_PREV_ATOM_NO_WIDTH_NEG:
|
||||||
case NFA_PREV_ATOM_JUST_BEFORE:
|
case NFA_PREV_ATOM_JUST_BEFORE:
|
||||||
case NFA_PREV_ATOM_JUST_BEFORE_NEG:
|
case NFA_PREV_ATOM_JUST_BEFORE_NEG:
|
||||||
|
{
|
||||||
|
int neg = (*p == NFA_PREV_ATOM_NO_WIDTH_NEG
|
||||||
|
|| *p == NFA_PREV_ATOM_JUST_BEFORE_NEG);
|
||||||
|
int before = (*p == NFA_PREV_ATOM_JUST_BEFORE
|
||||||
|
|| *p == NFA_PREV_ATOM_JUST_BEFORE_NEG);
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (before)
|
||||||
|
n = *++p; /* get the count */
|
||||||
|
|
||||||
/* The \@= operator: match the preceding atom with zero width.
|
/* The \@= operator: match the preceding atom with zero width.
|
||||||
* The \@! operator: no match for the preceding atom.
|
* The \@! operator: no match for the preceding atom.
|
||||||
* The \@<= operator: match for the preceding atom.
|
* The \@<= operator: match for the preceding atom.
|
||||||
@@ -2583,21 +2637,20 @@ post2nfa(postfix, end, nfa_calc_size)
|
|||||||
s = alloc_state(NFA_START_INVISIBLE, e.start, s1);
|
s = alloc_state(NFA_START_INVISIBLE, e.start, s1);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
goto theend;
|
goto theend;
|
||||||
if (*p == NFA_PREV_ATOM_NO_WIDTH_NEG
|
if (neg)
|
||||||
|| *p == NFA_PREV_ATOM_JUST_BEFORE_NEG)
|
|
||||||
{
|
{
|
||||||
s->negated = TRUE;
|
s->negated = TRUE;
|
||||||
s1->negated = TRUE;
|
s1->negated = TRUE;
|
||||||
}
|
}
|
||||||
if (*p == NFA_PREV_ATOM_JUST_BEFORE
|
if (before)
|
||||||
|| *p == NFA_PREV_ATOM_JUST_BEFORE_NEG)
|
|
||||||
{
|
{
|
||||||
s->val = *++p; /* get the count */
|
s->val = n; /* store the count */
|
||||||
++s->c; /* NFA_START_INVISIBLE -> NFA_START_INVISIBLE_BEFORE */
|
++s->c; /* NFA_START_INVISIBLE -> NFA_START_INVISIBLE_BEFORE */
|
||||||
}
|
}
|
||||||
|
|
||||||
PUSH(frag(s, list1(&s1->out)));
|
PUSH(frag(s, list1(&s1->out)));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
case NFA_COMPOSING: /* char with composing char */
|
case NFA_COMPOSING: /* char with composing char */
|
||||||
@@ -2750,18 +2803,21 @@ post2nfa(postfix, end, nfa_calc_size)
|
|||||||
case NFA_MARK:
|
case NFA_MARK:
|
||||||
case NFA_MARK_GT:
|
case NFA_MARK_GT:
|
||||||
case NFA_MARK_LT:
|
case NFA_MARK_LT:
|
||||||
|
{
|
||||||
|
int n = *++p; /* lnum, col or mark name */
|
||||||
|
|
||||||
if (nfa_calc_size == TRUE)
|
if (nfa_calc_size == TRUE)
|
||||||
{
|
{
|
||||||
nstate += 1;
|
nstate += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e1 = POP();
|
s = alloc_state(p[-1], NULL, NULL);
|
||||||
s = alloc_state(*p, NULL, NULL);
|
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
goto theend;
|
goto theend;
|
||||||
s->val = e1.start->c; /* lnum, col or mark name */
|
s->val = n;
|
||||||
PUSH(frag(s, list1(&s->out)));
|
PUSH(frag(s, list1(&s->out)));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case NFA_ZSTART:
|
case NFA_ZSTART:
|
||||||
case NFA_ZEND:
|
case NFA_ZEND:
|
||||||
|
@@ -352,6 +352,19 @@ STARTTEST
|
|||||||
:call add(tl, [2, '\%u0020', 'yes no', ' '])
|
:call add(tl, [2, '\%u0020', 'yes no', ' '])
|
||||||
:call add(tl, [2, '\%U00000020', 'yes no', ' '])
|
:call add(tl, [2, '\%U00000020', 'yes no', ' '])
|
||||||
:"
|
:"
|
||||||
|
:""""" \%[abc]
|
||||||
|
:call add(tl, [2, 'foo\%[bar]', 'fobar'])
|
||||||
|
:call add(tl, [2, 'foo\%[bar]', 'foobar', 'foobar'])
|
||||||
|
:call add(tl, [2, 'foo\%[bar]', 'fooxx', 'foo'])
|
||||||
|
:call add(tl, [2, 'foo\%[bar]', 'foobxx', 'foob'])
|
||||||
|
:call add(tl, [2, 'foo\%[bar]', 'foobaxx', 'fooba'])
|
||||||
|
:call add(tl, [2, 'foo\%[bar]', 'foobarxx', 'foobar'])
|
||||||
|
:call add(tl, [2, 'foo\%[bar]x', 'foobxx', 'foobx'])
|
||||||
|
:call add(tl, [2, 'foo\%[bar]x', 'foobarxx', 'foobarx'])
|
||||||
|
:call add(tl, [2, '\%[bar]x', 'barxx', 'barx'])
|
||||||
|
:call add(tl, [2, '\%[bar]x', 'bxx', 'bx'])
|
||||||
|
:call add(tl, [2, '\%[bar]x', 'xxx', 'x'])
|
||||||
|
:"
|
||||||
:"""" Alternatives, must use first longest match
|
:"""" Alternatives, must use first longest match
|
||||||
:call add(tl, [2, 'goo\|go', 'google', 'goo'])
|
:call add(tl, [2, 'goo\|go', 'google', 'goo'])
|
||||||
:call add(tl, [2, '\<goo\|\<go', 'google', 'goo'])
|
:call add(tl, [2, '\<goo\|\<go', 'google', 'goo'])
|
||||||
|
@@ -797,6 +797,39 @@ OK 2 - \%u0020
|
|||||||
OK 0 - \%U00000020
|
OK 0 - \%U00000020
|
||||||
OK 1 - \%U00000020
|
OK 1 - \%U00000020
|
||||||
OK 2 - \%U00000020
|
OK 2 - \%U00000020
|
||||||
|
OK 0 - foo\%[bar]
|
||||||
|
OK 1 - foo\%[bar]
|
||||||
|
OK 2 - foo\%[bar]
|
||||||
|
OK 0 - foo\%[bar]
|
||||||
|
OK 1 - foo\%[bar]
|
||||||
|
OK 2 - foo\%[bar]
|
||||||
|
OK 0 - foo\%[bar]
|
||||||
|
OK 1 - foo\%[bar]
|
||||||
|
OK 2 - foo\%[bar]
|
||||||
|
OK 0 - foo\%[bar]
|
||||||
|
OK 1 - foo\%[bar]
|
||||||
|
OK 2 - foo\%[bar]
|
||||||
|
OK 0 - foo\%[bar]
|
||||||
|
OK 1 - foo\%[bar]
|
||||||
|
OK 2 - foo\%[bar]
|
||||||
|
OK 0 - foo\%[bar]
|
||||||
|
OK 1 - foo\%[bar]
|
||||||
|
OK 2 - foo\%[bar]
|
||||||
|
OK 0 - foo\%[bar]x
|
||||||
|
OK 1 - foo\%[bar]x
|
||||||
|
OK 2 - foo\%[bar]x
|
||||||
|
OK 0 - foo\%[bar]x
|
||||||
|
OK 1 - foo\%[bar]x
|
||||||
|
OK 2 - foo\%[bar]x
|
||||||
|
OK 0 - \%[bar]x
|
||||||
|
OK 1 - \%[bar]x
|
||||||
|
OK 2 - \%[bar]x
|
||||||
|
OK 0 - \%[bar]x
|
||||||
|
OK 1 - \%[bar]x
|
||||||
|
OK 2 - \%[bar]x
|
||||||
|
OK 0 - \%[bar]x
|
||||||
|
OK 1 - \%[bar]x
|
||||||
|
OK 2 - \%[bar]x
|
||||||
OK 0 - goo\|go
|
OK 0 - goo\|go
|
||||||
OK 1 - goo\|go
|
OK 1 - goo\|go
|
||||||
OK 2 - goo\|go
|
OK 2 - goo\|go
|
||||||
|
@@ -728,6 +728,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1117,
|
||||||
/**/
|
/**/
|
||||||
1116,
|
1116,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user