changeset 10168:3c37899baa8d v7.4.2354

commit https://github.com/vim/vim/commit/d563883a1fb5ec6cf4a2758c5e36ac1ff4e9bb3d Author: Bram Moolenaar <Bram@vim.org> Date: Fri Sep 9 17:59:50 2016 +0200 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 https://github.com/vim/vim/issues/990)
author Christian Brabandt <cb@256bit.org>
date Fri, 09 Sep 2016 18:00:09 +0200
parents 39d411db50ee
children fbb82155b1e2
files src/regexp_nfa.c src/testdir/test_regexp_latin.vim src/version.c
diffstat 3 files changed, 24 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -4354,7 +4354,7 @@ addstate(
 {
     int			subidx;
     nfa_thread_T	*thread;
-    lpos_T		save_lpos;
+    struct multipos	save_multipos;
     int			save_in_use;
     char_u		*save_ptr;
     int			i;
@@ -4572,8 +4572,7 @@ skip_add:
 
 	    /* avoid compiler warnings */
 	    save_ptr = NULL;
-	    save_lpos.lnum = 0;
-	    save_lpos.col = 0;
+	    vim_memset(&save_multipos, 0, sizeof(save_multipos));
 
 	    /* Set the position (with "off" added) in the subexpression.  Save
 	     * and restore it when it was in use.  Otherwise fill any gap. */
@@ -4581,8 +4580,7 @@ skip_add:
 	    {
 		if (subidx < sub->in_use)
 		{
-		    save_lpos.lnum = sub->list.multi[subidx].start_lnum;
-		    save_lpos.col = sub->list.multi[subidx].start_col;
+		    save_multipos = sub->list.multi[subidx];
 		    save_in_use = -1;
 		}
 		else
@@ -4640,10 +4638,7 @@ skip_add:
 	    if (save_in_use == -1)
 	    {
 		if (REG_MULTI)
-                {
-		    sub->list.multi[subidx].start_lnum = save_lpos.lnum;
-		    sub->list.multi[subidx].start_col = save_lpos.col;
-                }
+		    sub->list.multi[subidx] = save_multipos;
 		else
 		    sub->list.line[subidx].start = save_ptr;
 	    }
@@ -4707,8 +4702,7 @@ skip_add:
 		sub->in_use = subidx + 1;
 	    if (REG_MULTI)
 	    {
-		save_lpos.lnum = sub->list.multi[subidx].end_lnum;
-		save_lpos.col = sub->list.multi[subidx].end_col;
+		save_multipos = sub->list.multi[subidx];
 		if (off == -1)
 		{
 		    sub->list.multi[subidx].end_lnum = reglnum + 1;
@@ -4728,8 +4722,7 @@ skip_add:
 		save_ptr = sub->list.line[subidx].end;
 		sub->list.line[subidx].end = reginput + off;
 		/* avoid compiler warnings */
-		save_lpos.lnum = 0;
-		save_lpos.col = 0;
+		vim_memset(&save_multipos, 0, sizeof(save_multipos));
 	    }
 
 	    subs = addstate(l, state->out, subs, pim, off);
@@ -4742,10 +4735,7 @@ skip_add:
 		sub = &subs->norm;
 
 	    if (REG_MULTI)
-            {
-		sub->list.multi[subidx].end_lnum = save_lpos.lnum;
-		sub->list.multi[subidx].end_col = save_lpos.col;
-            }
+		sub->list.multi[subidx] = save_multipos;
 	    else
 		sub->list.line[subidx].end = save_ptr;
 	    sub->in_use = save_in_use;
--- a/src/testdir/test_regexp_latin.vim
+++ b/src/testdir/test_regexp_latin.vim
@@ -38,3 +38,18 @@ func Test_recursive_substitute()
   call setwinvar(1, 'myvar', 1)
   bwipe!
 endfunc
+
+func Test_nested_backrefs()
+  " Check example in change.txt.
+  new
+  for re in range(0, 2)
+    exe 'set re=' . re
+    call setline(1, 'aa ab x')
+    1s/\(\(a[a-d] \)*\)\(x\)/-\1- -\2- -\3-/
+    call assert_equal('-aa ab - -ab - -x-', getline(1))
+
+    call assert_equal('-aa ab - -ab - -x-', substitute('aa ab x', '\(\(a[a-d] \)*\)\(x\)', '-\1- -\2- -\3-', ''))
+  endfor
+  bwipe!
+  set re=0
+endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -764,6 +764,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2354,
+/**/
     2353,
 /**/
     2352,