# HG changeset patch # User Bram Moolenaar # Date 1369946642 -7200 # Node ID 0dce3d812e7acc74c39b3d87d8bb5b3a4dbee878 # Parent 4dcc1a7d49a53155ee5d9f215c3a1076b275e3d4 updated for version 7.3.1078 Problem: New regexp engine: \@! doesn't work. Solution: Implement the negated version of \@=. diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -1390,6 +1390,9 @@ nfa_regpiece() case '=': EMIT(NFA_PREV_ATOM_NO_WIDTH); break; + case '!': + EMIT(NFA_PREV_ATOM_NO_WIDTH_NEG); + break; case '0': case '1': case '2': @@ -1400,7 +1403,6 @@ nfa_regpiece() case '7': case '8': case '9': - case '!': case '<': case '>': /* Not supported yet */ @@ -2373,7 +2375,9 @@ post2nfa(postfix, end, nfa_calc_size) break; case NFA_PREV_ATOM_NO_WIDTH: + case NFA_PREV_ATOM_NO_WIDTH_NEG: /* The \@= operator: match the preceding atom with zero width. + * The \@! operator: no match for the preceding atom. * Surrounds the preceding atom with START_INVISIBLE and * END_INVISIBLE, similarly to MOPEN. */ @@ -2391,6 +2395,12 @@ post2nfa(postfix, end, nfa_calc_size) s = new_state(NFA_START_INVISIBLE, e.start, s1); if (s == NULL) goto theend; + if (*p == NFA_PREV_ATOM_NO_WIDTH_NEG) + { + s->negated = TRUE; + s1->negated = TRUE; + } + PUSH(frag(s, list1(&s1->out))); break; @@ -3541,8 +3551,10 @@ nfa_regmatch(start, submatch, m) addstate_here(thislist, t->state->out, &t->sub, &listidx); else { - /* TODO: only copy positions in use. */ - *m = t->sub; + /* do not set submatches for \@! */ + if (!t->state->negated) + /* TODO: only copy positions in use. */ + *m = t->sub; nfa_match = TRUE; } break; @@ -3593,7 +3605,8 @@ nfa_regmatch(start, submatch, m) log_fd = stderr; } #endif - if (result == TRUE) + /* for \@! it is a match when result is FALSE */ + if (result != t->state->negated) { int j; diff --git a/src/testdir/test64.in b/src/testdir/test64.in --- a/src/testdir/test64.in +++ b/src/testdir/test64.in @@ -303,13 +303,20 @@ STARTTEST :" will never match :call add(tl, [2, 'abcd\@=e', 'any text in here ... ']) :call add(tl, [2, '\v(abc)@=..', 'xabcd', 'ab', 'abc']) -:" no match :call add(tl, [2, '\(.*John\)\@=.*Bob', 'here is John, and here is B']) :call add(tl, [2, '\(John.*\)\@=.*Bob', 'John is Bobs friend', 'John is Bob', 'John is Bobs friend']) -:" no match :call add(tl, [2, '.*John\&.*Bob', 'here is John, and here is B']) :call add(tl, [2, '.*John\&.*Bob', 'John is Bobs friend', 'John is Bob']) :call add(tl, [2, '\v(test1)@=.*yep', 'this is a test1, yep it is', 'test1, yep', 'test1']) +:call add(tl, [2, 'foo\(bar\)\@!', 'foobar']) +:call add(tl, [2, 'foo\(bar\)\@!', 'foo bar', 'foo']) +:call add(tl, [2, 'if \(\(then\)\@!.\)*$', ' if then else']) +:call add(tl, [2, 'if \(\(then\)\@!.\)*$', ' if else ', 'if else ', ' ']) +:call add(tl, [2, '\(foo\)\@!bar', 'foobar', 'bar']) +:call add(tl, [2, '\(foo\)\@!...bar', 'foobar']) +:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' bar foo ']) +:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo bar ']) +:call add(tl, [2, '^\%(.*bar\)\@!.*\zsfoo', ' foo xxx ', 'foo']) :" :"""" Combining different tests and features :call add(tl, [2, '[[:alpha:]]\{-2,6}', '787abcdiuhsasiuhb4', 'ab']) diff --git a/src/testdir/test64.ok b/src/testdir/test64.ok --- a/src/testdir/test64.ok +++ b/src/testdir/test64.ok @@ -678,6 +678,33 @@ OK 2 - .*John\&.*Bob OK 0 - \v(test1)@=.*yep OK 1 - \v(test1)@=.*yep OK 2 - \v(test1)@=.*yep +OK 0 - foo\(bar\)\@! +OK 1 - foo\(bar\)\@! +OK 2 - foo\(bar\)\@! +OK 0 - foo\(bar\)\@! +OK 1 - foo\(bar\)\@! +OK 2 - foo\(bar\)\@! +OK 0 - if \(\(then\)\@!.\)*$ +OK 1 - if \(\(then\)\@!.\)*$ +OK 2 - if \(\(then\)\@!.\)*$ +OK 0 - if \(\(then\)\@!.\)*$ +OK 1 - if \(\(then\)\@!.\)*$ +OK 2 - if \(\(then\)\@!.\)*$ +OK 0 - \(foo\)\@!bar +OK 1 - \(foo\)\@!bar +OK 2 - \(foo\)\@!bar +OK 0 - \(foo\)\@!...bar +OK 1 - \(foo\)\@!...bar +OK 2 - \(foo\)\@!...bar +OK 0 - ^\%(.*bar\)\@!.*\zsfoo +OK 1 - ^\%(.*bar\)\@!.*\zsfoo +OK 2 - ^\%(.*bar\)\@!.*\zsfoo +OK 0 - ^\%(.*bar\)\@!.*\zsfoo +OK 1 - ^\%(.*bar\)\@!.*\zsfoo +OK 2 - ^\%(.*bar\)\@!.*\zsfoo +OK 0 - ^\%(.*bar\)\@!.*\zsfoo +OK 1 - ^\%(.*bar\)\@!.*\zsfoo +OK 2 - ^\%(.*bar\)\@!.*\zsfoo OK 0 - [[:alpha:]]\{-2,6} OK 1 - [[:alpha:]]\{-2,6} OK 2 - [[:alpha:]]\{-2,6} 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 */ /**/ + 1078, +/**/ 1077, /**/ 1076,