diff src/regexp_nfa.c @ 5372:c3d379c2a115 v7.4.037

updated for version 7.4.037 Problem: Using "\ze" in a sub-pattern does not result in the end of the match to be set. (Axel Bender) Solution: Copy the end of match position when a recursive match was successful.
author Bram Moolenaar <bram@vim.org>
date Wed, 25 Sep 2013 18:16:38 +0200
parents 90e2f0729a0d
children e7a2f217a385
line wrap: on
line diff
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -3822,6 +3822,7 @@ static void copy_pim __ARGS((nfa_pim_T *
 static void clear_sub __ARGS((regsub_T *sub));
 static void copy_sub __ARGS((regsub_T *to, regsub_T *from));
 static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from));
+static void copy_ze_off __ARGS((regsub_T *to, regsub_T *from));
 static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2));
 static int match_backref __ARGS((regsub_T *sub, int subidx, int *bytelen));
 static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim));
@@ -3909,6 +3910,29 @@ copy_sub_off(to, from)
 }
 
 /*
+ * Like copy_sub() but only do the end of the main match if \ze is present.
+ */
+    static void
+copy_ze_off(to, from)
+    regsub_T	*to;
+    regsub_T	*from;
+{
+    if (nfa_has_zend)
+    {
+	if (REG_MULTI)
+	{
+	    if (from->list.multi[0].end.lnum >= 0)
+		to->list.multi[0].end = from->list.multi[0].end;
+	}
+	else
+	{
+	    if (from->list.line[0].end != NULL)
+		to->list.line[0].end = from->list.line[0].end;
+	}
+    }
+}
+
+/*
  * Return TRUE if "sub1" and "sub2" have the same start positions.
  */
     static int
@@ -5308,6 +5332,7 @@ find_match_text(startcol, regstart, matc
  * When "nfa_endp" is not NULL it is a required end-of-match position.
  *
  * Return TRUE if there is a match, FALSE otherwise.
+ * When there is a match "submatch" contains the positions.
  * Note: Caller must ensure that: start != NULL.
  */
     static int
@@ -5633,6 +5658,9 @@ nfa_regmatch(prog, start, submatch, m)
 			    if (nfa_has_zsubexpr)
 				copy_sub_off(&t->subs.synt, &m->synt);
 #endif
+			    /* If the pattern has \ze and it matched in the
+			     * sub pattern, use it. */
+			    copy_ze_off(&t->subs.norm, &m->norm);
 
 			    /* t->state->out1 is the corresponding
 			     * END_INVISIBLE node; Add its out to the current