# HG changeset patch # User Bram Moolenaar # Date 1369580248 -7200 # Node ID 7b835b2969af137f979b633977d59e13cc0960df # Parent 76e7397957922ea7efc1978e084f42f271e7b0b1 updated for version 7.3.1024 Problem: New regexp: End of matching pattern not set correctly. (Cesar Romani) Solution: Quit the loop after finding the match. Store nfa_has_zend in the program. diff --git a/src/regexp.h b/src/regexp.h --- a/src/regexp.h +++ b/src/regexp.h @@ -86,6 +86,7 @@ typedef struct regprog_T regprog; nfa_state_T *start; + int has_zend; /* pattern contains \ze */ int nstate; nfa_state_T state[0]; /* actually longer.. */ } nfa_regprog_T; diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -2651,7 +2651,7 @@ addstate(l, state, m, off, lid, match) break; case NFA_MCLOSE + 0: - if (nfa_has_zend == TRUE) + if (nfa_has_zend) { addstate(l, state->out, m, off, lid, match); break; @@ -3109,7 +3109,11 @@ nfa_regmatch(start, submatch, m) fprintf(log_fd, "\n"); #endif /* Found the left-most longest match, do not look at any other - * states at this position. */ + * states at this position. When the list of states is going + * to be empty quit without advancing, so that "reginput" is + * correct. */ + if (nextlist->n == 0 && neglist->n == 0) + clen = 0; goto nextchar; case NFA_END_INVISIBLE: @@ -3783,8 +3787,9 @@ nfa_regexec_both(line, col) regline = line; reglnum = 0; /* relative to line */ + nfa_has_zend = prog->has_zend; + nstate = prog->nstate; - for (i = 0; i < nstate; ++i) { prog->state[i].id = i; @@ -3871,6 +3876,7 @@ nfa_regcomp(expr, re_flags) prog->regflags = regflags; prog->engine = &nfa_regengine; prog->nstate = nstate; + prog->has_zend = nfa_has_zend; #ifdef ENABLE_LOG nfa_postfix_dump(expr, OK); nfa_dump(prog); diff --git a/src/testdir/test64.in b/src/testdir/test64.in --- a/src/testdir/test64.in +++ b/src/testdir/test64.in @@ -15,11 +15,11 @@ STARTTEST :" etc. :" When there is no match use only the first two items. :let tl = [] - +:" :"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" :"""" Previously written tests """""""""""""""""""""""""""""""" :"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - +:" :call add(tl, [2, 'ab', 'aab', 'ab']) :call add(tl, [2, 'b', 'abcdef', 'b']) :call add(tl, [2, 'bc*', 'abccccdef', 'bcccc']) @@ -138,16 +138,16 @@ STARTTEST :" :call add(tl, [2, '\v(a*)+', 'aaaa', 'aaaa', '']) :call add(tl, [2, 'x', 'abcdef']) - +:" :"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" :""""" Simple tests """"""""""""""""""""""""""""""""""""""""""" :"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - +:" :" Search single groups :call add(tl, [2, 'ab', 'aab', 'ab']) :call add(tl, [2, 'ab', 'baced']) :call add(tl, [2, 'ab', ' ab ', 'ab']) - +:" :" Search multi-modifiers :call add(tl, [2, 'x*', 'xcd', 'x']) :call add(tl, [2, 'x*', 'xxxxxxxxxxxxxxxxsofijiojgf', 'xxxxxxxxxxxxxxxx']) @@ -162,7 +162,7 @@ STARTTEST :call add(tl, [2, 'x\?', 'x sdfoij', 'x']) :call add(tl, [2, 'x\?', 'abc sfoij', '']) " empty match is good :call add(tl, [2, 'x\?', 'xxxxxxxxxx c', 'x']) - +:" :call add(tl, [2, 'a\{0,0}', 'abcdfdoij', '']) :call add(tl, [2, 'a\{0,1}', 'asiubid axxxaaa', 'a']) " same thing as 'a?' :call add(tl, [2, 'a\{1,0}', 'asiubid axxxaaa', 'a']) " same thing as 'a\{0,1}' @@ -182,7 +182,7 @@ STARTTEST :call add(tl, [2, 'a\{,5}', 'aaaaaaaaaa', 'aaaaa']) :call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', '']) " same thing as 'a*' :call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa']) - +:" :call add(tl, [2, 'a\{-0,0}', 'abcdfdoij', '']) :call add(tl, [2, 'a\{-0,1}', 'asiubid axxxaaa', '']) " anti-greedy version of 'a?' :call add(tl, [2, 'a\{-3,6}', 'aa siofuh']) @@ -200,7 +200,7 @@ STARTTEST :call add(tl, [2, 'a\{-,5}', 'aaaaaaaaaa', '']) :call add(tl, [0, 'a\{-}', 'bbbcddiuhfcd', '']) " anti-greedy version of 'a*' :call add(tl, [0, 'a\{-}', 'aaaaioudfh coisf jda', '']) - +:" :" Test groups of characters and submatches :call add(tl, [2, '\(abc\)*', 'abcabcabc', 'abcabcabc', 'abc']) :call add(tl, [2, '\(ab\)\+', 'abababaaaaa', 'ababab', 'ab']) @@ -213,7 +213,7 @@ STARTTEST :call add(tl, [2, '\v((ab)|c*)+', 'abcccaba', 'abcccab', '', 'ab']) :call add(tl, [2, '\v(a(c*)+b)+', 'acbababaaa', 'acbabab', 'ab', '']) :call add(tl, [2, '\v(a|b*)+', 'aaaa', 'aaaa', '']) - +:" :" Test greedy-ness and lazy-ness :call add(tl, [2, 'a\{-2,7}','aaaaaaaaaaaaa', 'aa']) :call add(tl, [2, 'a\{2,7}','aaaaaaaaaaaaaaaaaaaa', 'aaaaaaa']) @@ -221,10 +221,10 @@ STARTTEST :call add(tl, [2, '\vx(.*)yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz', 'ayxayzxayzxa','']) :call add(tl, [2, '\v(a{1,2}){-2,3}','aaaaaaa','aaaa','aa']) :call add(tl, [2, '\v(a{-1,3})+','aa','aa','a']) - +:" :" Test Character classes :call add(tl, [2, '\d\+e\d\d','test 10e23 fd','10e23']) - +:" :" Test collections and character range [] :call add(tl, [2, '\v[a]', 'abcd', 'a']) :call add(tl, [2, 'a[bcd]', 'abcd', 'ab']) @@ -250,8 +250,8 @@ STARTTEST :call add(tl, [2, 'abc[0-9]*ddd', 'adf abc44482ddd oijs', 'abc44482ddd']) :call add(tl, [2, '\_[0-9]\+', 'asfi9888u', '9888']) :call add(tl, [2, '[0-9\n]\+', 'asfi9888u', '9888']) - - +:" +:" :"""" Test recognition of some character classes :call add(tl, [2, '[0-9]', '8', '8']) :call add(tl, [2, '[^0-9]', '8']) @@ -262,7 +262,7 @@ STARTTEST :call add(tl, [2, '[a-zA-Z]', 'a', 'a']) :call add(tl, [2, '[A-Z]', 'a']) :call add(tl, [2, '\C[^A-Z]\+', 'ABCOIJDEOIFNSD jsfoij sa', ' jsfoij sa']) - +:" :"""" Tests for \z features :call add(tl, [2, 'xx \ze test', 'xx ']) " must match after \ze :call add(tl, [0, 'abc\zeend', 'oij abcend', 'abc']) @@ -271,7 +271,7 @@ STARTTEST :call add(tl, [0, 'abc \zsmatch\ze abc', 'abc abc abc match abc abc', 'match']) :call add(tl, [2, '\v(a \zsif .*){2}', 'a if then a if last', 'if last', 'a if last']) :call add(tl, [2, '\>\zs.', 'aword. ', '.']) - +:" :"""" Tests for \@ features :call add(tl, [0, 'abc\@=', 'abc', 'ab']) :call add(tl, [0, 'abc\@=cd', 'abcd', 'abcd']) @@ -284,7 +284,7 @@ STARTTEST :call add(tl, [2, '.*John\&.*Bob', 'here is John, and here is B']) " no match :call add(tl, [0, '.*John\&.*Bob', 'John is Bobs friend', 'John is Bob']) :call add(tl, [0, '\v(test1)@=.*yep', 'this is a test1, yep it is', 'test1, yep', 'test1']) - +:" :"""" Combining different tests and features :call add(tl, [2, '[[:alpha:]]\{-2,6}', '787abcdiuhsasiuhb4', 'ab']) :call add(tl, [2, '', 'abcd', '']) @@ -292,22 +292,22 @@ STARTTEST :call add(tl, [2, '\v%(ab(xyz)c)', ' abxyzc ', 'abxyzc', 'xyz']) :call add(tl, [2, '\v(test|)empty', 'tesempty', 'empty', '']) :call add(tl, [2, '\v(a|aa)(a|aa)', 'aaa', 'aa', 'a', 'a']) - +:" :"""" \%u and friends :call add(tl, [2, '\%d32', 'yes no', ' ']) :call add(tl, [2, '\%o40', 'yes no', ' ']) :call add(tl, [2, '\%x20', 'yes no', ' ']) :call add(tl, [2, '\%u0020', 'yes no', ' ']) :call add(tl, [2, '\%U00000020', 'yes no', ' ']) - +:" :"""" Alternatives, must use first longest match :call add(tl, [2, 'goo\|go', 'google', 'goo']) :call add(tl, [2, '\ :" This only works on a buffer line, not with expression evaluation /^Find this @@ -359,11 +359,25 @@ y$Gop:" /^Find this /\%#=2\<\(\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\.\)\{3\}\(25\_[0-5]\|2\_[0-4]\_[0-9]\|\_[01]\?\_[0-9]\_[0-9]\?\)\> y$Gop:" - +:" +:" Check that using a pattern on two lines doesn't get messed up by using +:" matchstr() with \ze in between. +:set re=0 +/^Substitute here +:.+1,.+2s/""/\='"'.matchstr(getline("."), '\d\+\ze<').'"' +/^Substitute here +:.+1,.+2yank +Gop:" +:" +:" :/\%#=1^Results/,$wq! test.out ENDTEST Find this: localnet/192.168.0.1 +Substitute here: +Ta 5 +Ac 7 + Results of test64: diff --git a/src/testdir/test64.ok b/src/testdir/test64.ok --- a/src/testdir/test64.ok +++ b/src/testdir/test64.ok @@ -693,3 +693,6 @@ OK 2 - \Ta 5 +Ac 7 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1024, +/**/ 1023, /**/ 1022,