diff src/regexp_nfa.c @ 4661:0dce3d812e7a v7.3.1078

updated for version 7.3.1078 Problem: New regexp engine: \@! doesn't work. Solution: Implement the negated version of \@=.
author Bram Moolenaar <bram@vim.org>
date Thu, 30 May 2013 22:44:02 +0200
parents 93b7ed814bec
children 9e7ef781d494
line wrap: on
line diff
--- 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;