Skip to content

Commit 16b3578

Browse files
committed
patch 7.4.2355
Problem: Regexp fails to match when using "\>\)\?". (Ramel) Solution: When a state is already in the list, but addstate_here() is used and the existing state comes later, add the new state anyway.
1 parent d563883 commit 16b3578

3 files changed

Lines changed: 56 additions & 13 deletions

File tree

src/regexp_nfa.c

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4340,6 +4340,9 @@ state_in_list(
43404340
return FALSE;
43414341
}
43424342

4343+
/* Offset used for "off" by addstate_here(). */
4344+
#define ADDSTATE_HERE_OFFSET 10
4345+
43434346
/*
43444347
* Add "state" and possibly what follows to state list ".".
43454348
* Returns "subs_arg", possibly copied into temp_subs.
@@ -4350,9 +4353,14 @@ addstate(
43504353
nfa_state_T *state, /* state to update */
43514354
regsubs_T *subs_arg, /* pointers to subexpressions */
43524355
nfa_pim_T *pim, /* postponed look-behind match */
4353-
int off) /* byte offset, when -1 go to next line */
4356+
int off_arg) /* byte offset, when -1 go to next line */
43544357
{
43554358
int subidx;
4359+
int off = off_arg;
4360+
int add_here = FALSE;
4361+
int listindex = 0;
4362+
int k;
4363+
int found = FALSE;
43564364
nfa_thread_T *thread;
43574365
struct multipos save_multipos;
43584366
int save_in_use;
@@ -4365,6 +4373,13 @@ addstate(
43654373
int did_print = FALSE;
43664374
#endif
43674375

4376+
if (off_arg <= -ADDSTATE_HERE_OFFSET)
4377+
{
4378+
add_here = TRUE;
4379+
off = 0;
4380+
listindex = -(off_arg + ADDSTATE_HERE_OFFSET);
4381+
}
4382+
43684383
switch (state->c)
43694384
{
43704385
case NFA_NCLOSE:
@@ -4448,13 +4463,28 @@ addstate(
44484463
if (!nfa_has_backref && pim == NULL && !l->has_pim
44494464
&& state->c != NFA_MATCH)
44504465
{
4466+
/* When called from addstate_here() do insert before
4467+
* existing states. */
4468+
if (add_here)
4469+
{
4470+
for (k = 0; k < l->n && k < listindex; ++k)
4471+
if (l->t[k].state->id == state->id)
4472+
{
4473+
found = TRUE;
4474+
break;
4475+
}
4476+
}
4477+
if (!add_here || found)
4478+
{
44514479
skip_add:
44524480
#ifdef ENABLE_LOG
4453-
nfa_set_code(state->c);
4454-
fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n",
4455-
abs(state->id), l->id, state->c, code);
4481+
nfa_set_code(state->c);
4482+
fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s pim: %s has_pim: %d found: %d\n",
4483+
abs(state->id), l->id, state->c, code,
4484+
pim == NULL ? "NULL" : "yes", l->has_pim, found);
44564485
#endif
4457-
return subs;
4486+
return subs;
4487+
}
44584488
}
44594489

44604490
/* Do not add the state again when it exists with the same
@@ -4519,14 +4549,14 @@ addstate(
45194549

45204550
case NFA_SPLIT:
45214551
/* order matters here */
4522-
subs = addstate(l, state->out, subs, pim, off);
4523-
subs = addstate(l, state->out1, subs, pim, off);
4552+
subs = addstate(l, state->out, subs, pim, off_arg);
4553+
subs = addstate(l, state->out1, subs, pim, off_arg);
45244554
break;
45254555

45264556
case NFA_EMPTY:
45274557
case NFA_NOPEN:
45284558
case NFA_NCLOSE:
4529-
subs = addstate(l, state->out, subs, pim, off);
4559+
subs = addstate(l, state->out, subs, pim, off_arg);
45304560
break;
45314561

45324562
case NFA_MOPEN:
@@ -4626,7 +4656,7 @@ addstate(
46264656
sub->list.line[subidx].start = reginput + off;
46274657
}
46284658

4629-
subs = addstate(l, state->out, subs, pim, off);
4659+
subs = addstate(l, state->out, subs, pim, off_arg);
46304660
/* "subs" may have changed, need to set "sub" again */
46314661
#ifdef FEAT_SYN_HL
46324662
if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9)
@@ -4652,7 +4682,7 @@ addstate(
46524682
: subs->norm.list.line[0].end != NULL))
46534683
{
46544684
/* Do not overwrite the position set by \ze. */
4655-
subs = addstate(l, state->out, subs, pim, off);
4685+
subs = addstate(l, state->out, subs, pim, off_arg);
46564686
break;
46574687
}
46584688
case NFA_MCLOSE1:
@@ -4725,7 +4755,7 @@ addstate(
47254755
vim_memset(&save_multipos, 0, sizeof(save_multipos));
47264756
}
47274757

4728-
subs = addstate(l, state->out, subs, pim, off);
4758+
subs = addstate(l, state->out, subs, pim, off_arg);
47294759
/* "subs" may have changed, need to set "sub" again */
47304760
#ifdef FEAT_SYN_HL
47314761
if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9)
@@ -4762,8 +4792,10 @@ addstate_here(
47624792
int count;
47634793
int listidx = *ip;
47644794

4765-
/* first add the state(s) at the end, so that we know how many there are */
4766-
addstate(l, state, subs, pim, 0);
4795+
/* First add the state(s) at the end, so that we know how many there are.
4796+
* Pass the listidx as offset (avoids adding another argument to
4797+
* addstate(). */
4798+
addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET);
47674799

47684800
/* when "*ip" was at the end of the list, nothing to do */
47694801
if (listidx + 1 == tlen)

src/testdir/test_regexp_latin.vim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,12 @@ func Test_nested_backrefs()
5353
bwipe!
5454
set re=0
5555
endfunc
56+
57+
func Test_eow_with_optional()
58+
let expected = ['abc def', 'abc', 'def', '', '', '', '', '', '', '']
59+
for re in range(0, 2)
60+
exe 'set re=' . re
61+
let actual = matchlist('abc def', '\(abc\>\)\?\s*\(def\)')
62+
call assert_equal(expected, actual)
63+
endfor
64+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ static char *(features[]) =
763763

764764
static int included_patches[] =
765765
{ /* Add new patch number below this line */
766+
/**/
767+
2355,
766768
/**/
767769
2354,
768770
/**/

0 commit comments

Comments
 (0)