summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <bram@vim.org>2013-09-25 18:16:38 +0200
committerBram Moolenaar <bram@vim.org>2013-09-25 18:16:38 +0200
commit15789234b4c837eda8ccab8401cb194f1dcff993 (patch)
treeea70331b6ddef8cfe9cbeb40a5919b7403b9ca94
parent4c72aa300ab2dbfd33ba18b211a90a08e1a0144f (diff)
downloadvim-15789234b4c837eda8ccab8401cb194f1dcff993.tar.gz
updated for version 7.4.037v7.4.037v7-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.
-rw-r--r--src/regexp_nfa.c28
-rw-r--r--src/testdir/test64.in1
-rw-r--r--src/testdir/test64.ok3
-rw-r--r--src/version.c2
4 files changed, 34 insertions, 0 deletions
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
index cd58b618..216459c4 100644
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -3822,6 +3822,7 @@ static void copy_pim __ARGS((nfa_pim_T *to, nfa_pim_T *from));
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, match_text)
* 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
diff --git a/src/testdir/test64.in b/src/testdir/test64.in
index ef04ba26..2df9a6b6 100644
--- a/src/testdir/test64.in
+++ b/src/testdir/test64.in
@@ -425,6 +425,7 @@ STARTTEST
:"
:" complicated look-behind match
:call add(tl, [2, '\(r\@<=\|\w\@<!\)\/', 'x = /word/;', '/'])
+:call add(tl, [2, '^[a-z]\+\ze \&\(asdf\)\@<!', 'foo bar', 'foo'])
:"
:""""" \@>
:call add(tl, [2, '\(a*\)\@>a', 'aaaa'])
diff --git a/src/testdir/test64.ok b/src/testdir/test64.ok
index a1c3f56e..401da407 100644
--- a/src/testdir/test64.ok
+++ b/src/testdir/test64.ok
@@ -983,6 +983,9 @@ OK 2 - \(foo\)\@<=.*
OK 0 - \(r\@<=\|\w\@<!\)\/
OK 1 - \(r\@<=\|\w\@<!\)\/
OK 2 - \(r\@<=\|\w\@<!\)\/
+OK 0 - ^[a-z]\+\ze \&\(asdf\)\@<!
+OK 1 - ^[a-z]\+\ze \&\(asdf\)\@<!
+OK 2 - ^[a-z]\+\ze \&\(asdf\)\@<!
OK 0 - \(a*\)\@>a
OK 1 - \(a*\)\@>a
OK 2 - \(a*\)\@>a
diff --git a/src/version.c b/src/version.c
index 2a4bc9c8..08220ef8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 37,
+/**/
36,
/**/
35,