To: vim_dev@googlegroups.com Subject: Patch 7.4.2355 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.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. Files: src/regexp_nfa.c, src/testdir/test_regexp_latin.vim *** ../vim-7.4.2354/src/regexp_nfa.c 2016-09-09 17:59:46.689781750 +0200 --- src/regexp_nfa.c 2016-09-09 20:26:46.959522104 +0200 *************** *** 4340,4345 **** --- 4340,4348 ---- 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,4358 **** 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 subidx; nfa_thread_T *thread; struct multipos save_multipos; int save_in_use; --- 4353,4366 ---- nfa_state_T *state, /* state to update */ regsubs_T *subs_arg, /* pointers to subexpressions */ nfa_pim_T *pim, /* postponed look-behind match */ ! 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,4370 **** --- 4373,4385 ---- 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,4460 **** if (!nfa_has_backref && pim == NULL && !l->has_pim && state->c != NFA_MATCH) { 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); #endif ! return subs; } /* Do not add the state again when it exists with the same --- 4463,4490 ---- 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 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; ! } } /* Do not add the state again when it exists with the same *************** *** 4519,4532 **** case NFA_SPLIT: /* order matters here */ ! subs = addstate(l, state->out, subs, pim, off); ! subs = addstate(l, state->out1, subs, pim, off); break; case NFA_EMPTY: case NFA_NOPEN: case NFA_NCLOSE: ! subs = addstate(l, state->out, subs, pim, off); break; case NFA_MOPEN: --- 4549,4562 ---- case NFA_SPLIT: /* order matters here */ ! 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_arg); break; case NFA_MOPEN: *************** *** 4626,4632 **** sub->list.line[subidx].start = reginput + off; } ! subs = addstate(l, state->out, subs, pim, off); /* "subs" may have changed, need to set "sub" again */ #ifdef FEAT_SYN_HL if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) --- 4656,4662 ---- sub->list.line[subidx].start = reginput + 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,4658 **** : subs->norm.list.line[0].end != NULL)) { /* Do not overwrite the position set by \ze. */ ! subs = addstate(l, state->out, subs, pim, off); break; } case NFA_MCLOSE1: --- 4682,4688 ---- : subs->norm.list.line[0].end != NULL)) { /* Do not overwrite the position set by \ze. */ ! subs = addstate(l, state->out, subs, pim, off_arg); break; } case NFA_MCLOSE1: *************** *** 4725,4731 **** vim_memset(&save_multipos, 0, sizeof(save_multipos)); } ! subs = addstate(l, state->out, subs, pim, off); /* "subs" may have changed, need to set "sub" again */ #ifdef FEAT_SYN_HL if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) --- 4755,4761 ---- vim_memset(&save_multipos, 0, sizeof(save_multipos)); } ! 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,4769 **** 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); /* when "*ip" was at the end of the list, nothing to do */ if (listidx + 1 == tlen) --- 4792,4801 ---- int count; int listidx = *ip; ! /* 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) *** ../vim-7.4.2354/src/testdir/test_regexp_latin.vim 2016-09-09 17:59:46.689781750 +0200 --- src/testdir/test_regexp_latin.vim 2016-09-09 20:18:47.402040284 +0200 *************** *** 53,55 **** --- 53,64 ---- 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 *** ../vim-7.4.2354/src/version.c 2016-09-09 17:59:46.693781693 +0200 --- src/version.c 2016-09-09 20:24:12.401624348 +0200 *************** *** 765,766 **** --- 765,768 ---- { /* Add new patch number below this line */ + /**/ + 2355, /**/ -- 'Psychologist' -- Someone who looks at everyone else when an attractive woman enters the room. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///