Skip to content

Commit d563883

Browse files
committed
patch 7.4.2354
Problem: The example that explains nested backreferences does not work properly with the new regexp engine. (Harm te Hennepe) Solution: Also save the end position when adding a state. (closes #990)
1 parent 2931f2a commit d563883

3 files changed

Lines changed: 24 additions & 17 deletions

File tree

src/regexp_nfa.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4354,7 +4354,7 @@ addstate(
43544354
{
43554355
int subidx;
43564356
nfa_thread_T *thread;
4357-
lpos_T save_lpos;
4357+
struct multipos save_multipos;
43584358
int save_in_use;
43594359
char_u *save_ptr;
43604360
int i;
@@ -4572,17 +4572,15 @@ addstate(
45724572

45734573
/* avoid compiler warnings */
45744574
save_ptr = NULL;
4575-
save_lpos.lnum = 0;
4576-
save_lpos.col = 0;
4575+
vim_memset(&save_multipos, 0, sizeof(save_multipos));
45774576

45784577
/* Set the position (with "off" added) in the subexpression. Save
45794578
* and restore it when it was in use. Otherwise fill any gap. */
45804579
if (REG_MULTI)
45814580
{
45824581
if (subidx < sub->in_use)
45834582
{
4584-
save_lpos.lnum = sub->list.multi[subidx].start_lnum;
4585-
save_lpos.col = sub->list.multi[subidx].start_col;
4583+
save_multipos = sub->list.multi[subidx];
45864584
save_in_use = -1;
45874585
}
45884586
else
@@ -4640,10 +4638,7 @@ addstate(
46404638
if (save_in_use == -1)
46414639
{
46424640
if (REG_MULTI)
4643-
{
4644-
sub->list.multi[subidx].start_lnum = save_lpos.lnum;
4645-
sub->list.multi[subidx].start_col = save_lpos.col;
4646-
}
4641+
sub->list.multi[subidx] = save_multipos;
46474642
else
46484643
sub->list.line[subidx].start = save_ptr;
46494644
}
@@ -4707,8 +4702,7 @@ addstate(
47074702
sub->in_use = subidx + 1;
47084703
if (REG_MULTI)
47094704
{
4710-
save_lpos.lnum = sub->list.multi[subidx].end_lnum;
4711-
save_lpos.col = sub->list.multi[subidx].end_col;
4705+
save_multipos = sub->list.multi[subidx];
47124706
if (off == -1)
47134707
{
47144708
sub->list.multi[subidx].end_lnum = reglnum + 1;
@@ -4728,8 +4722,7 @@ addstate(
47284722
save_ptr = sub->list.line[subidx].end;
47294723
sub->list.line[subidx].end = reginput + off;
47304724
/* avoid compiler warnings */
4731-
save_lpos.lnum = 0;
4732-
save_lpos.col = 0;
4725+
vim_memset(&save_multipos, 0, sizeof(save_multipos));
47334726
}
47344727

47354728
subs = addstate(l, state->out, subs, pim, off);
@@ -4742,10 +4735,7 @@ addstate(
47424735
sub = &subs->norm;
47434736

47444737
if (REG_MULTI)
4745-
{
4746-
sub->list.multi[subidx].end_lnum = save_lpos.lnum;
4747-
sub->list.multi[subidx].end_col = save_lpos.col;
4748-
}
4738+
sub->list.multi[subidx] = save_multipos;
47494739
else
47504740
sub->list.line[subidx].end = save_ptr;
47514741
sub->in_use = save_in_use;

src/testdir/test_regexp_latin.vim

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,18 @@ func Test_recursive_substitute()
3838
call setwinvar(1, 'myvar', 1)
3939
bwipe!
4040
endfunc
41+
42+
func Test_nested_backrefs()
43+
" Check example in change.txt.
44+
new
45+
for re in range(0, 2)
46+
exe 'set re=' . re
47+
call setline(1, 'aa ab x')
48+
1s/\(\(a[a-d] \)*\)\(x\)/-\1- -\2- -\3-/
49+
call assert_equal('-aa ab - -ab - -x-', getline(1))
50+
51+
call assert_equal('-aa ab - -ab - -x-', substitute('aa ab x', '\(\(a[a-d] \)*\)\(x\)', '-\1- -\2- -\3-', ''))
52+
endfor
53+
bwipe!
54+
set re=0
55+
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+
2354,
766768
/**/
767769
2353,
768770
/**/

0 commit comments

Comments
 (0)