diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-09-09 20:29:50 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-09-09 20:29:50 +0200 |
commit | 16b3578f355282846f2600ce77fb344950f0b9ce (patch) | |
tree | 2e0c8306d33dfbb9e904510e3dea3a5bcb50512a /src | |
parent | d563883a1fb5ec6cf4a2758c5e36ac1ff4e9bb3d (diff) | |
download | vim-git-16b3578f355282846f2600ce77fb344950f0b9ce.tar.gz |
patch 7.4.2355v7.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.
Diffstat (limited to 'src')
-rw-r--r-- | src/regexp_nfa.c | 58 | ||||
-rw-r--r-- | src/testdir/test_regexp_latin.vim | 9 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 56 insertions, 13 deletions
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index f8ce4e99a..1f331aed4 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -4340,6 +4340,9 @@ state_in_list( return FALSE; } +/* Offset used for "off" by addstate_here(). */ +#define ADDSTATE_HERE_OFFSET 10 + /* * Add "state" and possibly what follows to state list ".". * Returns "subs_arg", possibly copied into temp_subs. @@ -4350,9 +4353,14 @@ addstate( nfa_state_T *state, /* state to update */ regsubs_T *subs_arg, /* pointers to subexpressions */ nfa_pim_T *pim, /* postponed look-behind match */ - int off) /* byte offset, when -1 go to next line */ + int off_arg) /* byte offset, when -1 go to next line */ { int subidx; + int off = off_arg; + int add_here = FALSE; + int listindex = 0; + int k; + int found = FALSE; nfa_thread_T *thread; struct multipos save_multipos; int save_in_use; @@ -4365,6 +4373,13 @@ addstate( int did_print = FALSE; #endif + if (off_arg <= -ADDSTATE_HERE_OFFSET) + { + add_here = TRUE; + off = 0; + listindex = -(off_arg + ADDSTATE_HERE_OFFSET); + } + switch (state->c) { case NFA_NCLOSE: @@ -4448,13 +4463,28 @@ addstate( if (!nfa_has_backref && pim == NULL && !l->has_pim && state->c != NFA_MATCH) { + /* When called from addstate_here() do insert before + * existing states. */ + if (add_here) + { + for (k = 0; k < l->n && k < listindex; ++k) + if (l->t[k].state->id == state->id) + { + found = TRUE; + break; + } + } + if (!add_here || found) + { skip_add: #ifdef ENABLE_LOG - nfa_set_code(state->c); - fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n", - abs(state->id), l->id, state->c, code); + nfa_set_code(state->c); + fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s pim: %s has_pim: %d found: %d\n", + abs(state->id), l->id, state->c, code, + pim == NULL ? "NULL" : "yes", l->has_pim, found); #endif - return subs; + return subs; + } } /* Do not add the state again when it exists with the same @@ -4519,14 +4549,14 @@ skip_add: case NFA_SPLIT: /* order matters here */ - subs = addstate(l, state->out, subs, pim, off); - subs = addstate(l, state->out1, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off_arg); + subs = addstate(l, state->out1, subs, pim, off_arg); break; case NFA_EMPTY: case NFA_NOPEN: case NFA_NCLOSE: - subs = addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off_arg); break; case NFA_MOPEN: @@ -4626,7 +4656,7 @@ skip_add: sub->list.line[subidx].start = reginput + off; } - subs = addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off_arg); /* "subs" may have changed, need to set "sub" again */ #ifdef FEAT_SYN_HL if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) @@ -4652,7 +4682,7 @@ skip_add: : subs->norm.list.line[0].end != NULL)) { /* Do not overwrite the position set by \ze. */ - subs = addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off_arg); break; } case NFA_MCLOSE1: @@ -4725,7 +4755,7 @@ skip_add: vim_memset(&save_multipos, 0, sizeof(save_multipos)); } - subs = addstate(l, state->out, subs, pim, off); + subs = addstate(l, state->out, subs, pim, off_arg); /* "subs" may have changed, need to set "sub" again */ #ifdef FEAT_SYN_HL if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) @@ -4762,8 +4792,10 @@ addstate_here( int count; int listidx = *ip; - /* first add the state(s) at the end, so that we know how many there are */ - addstate(l, state, subs, pim, 0); + /* First add the state(s) at the end, so that we know how many there are. + * Pass the listidx as offset (avoids adding another argument to + * addstate(). */ + addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET); /* when "*ip" was at the end of the list, nothing to do */ if (listidx + 1 == tlen) diff --git a/src/testdir/test_regexp_latin.vim b/src/testdir/test_regexp_latin.vim index 15ff4f9e4..247e5e65a 100644 --- a/src/testdir/test_regexp_latin.vim +++ b/src/testdir/test_regexp_latin.vim @@ -53,3 +53,12 @@ func Test_nested_backrefs() bwipe! set re=0 endfunc + +func Test_eow_with_optional() + let expected = ['abc def', 'abc', 'def', '', '', '', '', '', '', ''] + for re in range(0, 2) + exe 'set re=' . re + let actual = matchlist('abc def', '\(abc\>\)\?\s*\(def\)') + call assert_equal(expected, actual) + endfor +endfunc diff --git a/src/version.c b/src/version.c index ff5076fc3..f332e43e9 100644 --- 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 */ /**/ + 2355, +/**/ 2354, /**/ 2353, |