Karsten Hopp e73c54
To: vim_dev@googlegroups.com
Karsten Hopp e73c54
Subject: Patch 7.3.1169
Karsten Hopp e73c54
Fcc: outbox
Karsten Hopp e73c54
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp e73c54
Mime-Version: 1.0
Karsten Hopp e73c54
Content-Type: text/plain; charset=UTF-8
Karsten Hopp e73c54
Content-Transfer-Encoding: 8bit
Karsten Hopp e73c54
------------
Karsten Hopp e73c54
Karsten Hopp e73c54
Patch 7.3.1169
Karsten Hopp e73c54
Problem:    New regexp engine: some work is done while executing a pattern,
Karsten Hopp e73c54
	    even though the result is predictable.
Karsten Hopp e73c54
Solution:   Do the work while compiling the pattern.
Karsten Hopp e73c54
Files:	    src/regexp_nfa.c
Karsten Hopp e73c54
Karsten Hopp e73c54
Karsten Hopp e73c54
*** ../vim-7.3.1168/src/regexp_nfa.c	2013-06-11 18:42:28.000000000 +0200
Karsten Hopp e73c54
--- src/regexp_nfa.c	2013-06-11 22:40:12.000000000 +0200
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 64,72 ****
Karsten Hopp e73c54
--- 64,76 ----
Karsten Hopp e73c54
      NFA_NOPEN,			    /* Start of subexpression marked with \%( */
Karsten Hopp e73c54
      NFA_NCLOSE,			    /* End of subexpr. marked with \%( ... \) */
Karsten Hopp e73c54
      NFA_START_INVISIBLE,
Karsten Hopp e73c54
+     NFA_START_INVISIBLE_FIRST,
Karsten Hopp e73c54
      NFA_START_INVISIBLE_NEG,
Karsten Hopp e73c54
+     NFA_START_INVISIBLE_NEG_FIRST,
Karsten Hopp e73c54
      NFA_START_INVISIBLE_BEFORE,
Karsten Hopp e73c54
+     NFA_START_INVISIBLE_BEFORE_FIRST,
Karsten Hopp e73c54
      NFA_START_INVISIBLE_BEFORE_NEG,
Karsten Hopp e73c54
+     NFA_START_INVISIBLE_BEFORE_NEG_FIRST,
Karsten Hopp e73c54
      NFA_START_PATTERN,
Karsten Hopp e73c54
      NFA_END_INVISIBLE,
Karsten Hopp e73c54
      NFA_END_INVISIBLE_NEG,
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 286,291 ****
Karsten Hopp e73c54
--- 290,296 ----
Karsten Hopp e73c54
  static int *re2post __ARGS((void));
Karsten Hopp e73c54
  static nfa_state_T *alloc_state __ARGS((int c, nfa_state_T *out, nfa_state_T *out1));
Karsten Hopp e73c54
  static nfa_state_T *post2nfa __ARGS((int *postfix, int *end, int nfa_calc_size));
Karsten Hopp e73c54
+ static void nfa_postprocess __ARGS((nfa_regprog_T *prog));
Karsten Hopp e73c54
  static int check_char_class __ARGS((int class, int c));
Karsten Hopp e73c54
  static void st_error __ARGS((int *postfix, int *end, int *p));
Karsten Hopp e73c54
  static void nfa_save_listids __ARGS((nfa_regprog_T *prog, int *list));
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 297,302 ****
Karsten Hopp e73c54
--- 302,309 ----
Karsten Hopp e73c54
  static void nfa_regfree __ARGS((regprog_T *prog));
Karsten Hopp e73c54
  static int nfa_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
Karsten Hopp e73c54
  static long nfa_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col, proftime_T *tm));
Karsten Hopp e73c54
+ static int match_follows __ARGS((nfa_state_T *startstate, int depth));
Karsten Hopp e73c54
+ static int failure_chance __ARGS((nfa_state_T *state, int depth));
Karsten Hopp e73c54
  
Karsten Hopp e73c54
  /* helper functions used when doing re2post() ... regatom() parsing */
Karsten Hopp e73c54
  #define EMIT(c)	do {				\
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 2040,2051 ****
Karsten Hopp e73c54
--- 2047,2066 ----
Karsten Hopp e73c54
  	case NFA_NOPEN:		    STRCPY(code, "NFA_NOPEN"); break;
Karsten Hopp e73c54
  	case NFA_NCLOSE:	    STRCPY(code, "NFA_NCLOSE"); break;
Karsten Hopp e73c54
  	case NFA_START_INVISIBLE:   STRCPY(code, "NFA_START_INVISIBLE"); break;
Karsten Hopp e73c54
+ 	case NFA_START_INVISIBLE_FIRST:
Karsten Hopp e73c54
+ 			     STRCPY(code, "NFA_START_INVISIBLE_FIRST"); break;
Karsten Hopp e73c54
  	case NFA_START_INVISIBLE_NEG:
Karsten Hopp e73c54
  			       STRCPY(code, "NFA_START_INVISIBLE_NEG"); break;
Karsten Hopp e73c54
+ 	case NFA_START_INVISIBLE_NEG_FIRST:
Karsten Hopp e73c54
+ 			 STRCPY(code, "NFA_START_INVISIBLE_NEG_FIRST"); break;
Karsten Hopp e73c54
  	case NFA_START_INVISIBLE_BEFORE:
Karsten Hopp e73c54
  			    STRCPY(code, "NFA_START_INVISIBLE_BEFORE"); break;
Karsten Hopp e73c54
+ 	case NFA_START_INVISIBLE_BEFORE_FIRST:
Karsten Hopp e73c54
+ 		      STRCPY(code, "NFA_START_INVISIBLE_BEFORE_FIRST"); break;
Karsten Hopp e73c54
  	case NFA_START_INVISIBLE_BEFORE_NEG:
Karsten Hopp e73c54
  			STRCPY(code, "NFA_START_INVISIBLE_BEFORE_NEG"); break;
Karsten Hopp e73c54
+ 	case NFA_START_INVISIBLE_BEFORE_NEG_FIRST:
Karsten Hopp e73c54
+ 		  STRCPY(code, "NFA_START_INVISIBLE_BEFORE_NEG_FIRST"); break;
Karsten Hopp e73c54
  	case NFA_START_PATTERN:   STRCPY(code, "NFA_START_PATTERN"); break;
Karsten Hopp e73c54
  	case NFA_END_INVISIBLE:	    STRCPY(code, "NFA_END_INVISIBLE"); break;
Karsten Hopp e73c54
  	case NFA_END_INVISIBLE_NEG: STRCPY(code, "NFA_END_INVISIBLE_NEG"); break;
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 3318,3323 ****
Karsten Hopp e73c54
--- 3333,3395 ----
Karsten Hopp e73c54
  #undef PUSH
Karsten Hopp e73c54
  }
Karsten Hopp e73c54
  
Karsten Hopp e73c54
+ /*
Karsten Hopp e73c54
+  * After building the NFA program, inspect it to add optimization hints.
Karsten Hopp e73c54
+  */
Karsten Hopp e73c54
+     static void
Karsten Hopp e73c54
+ nfa_postprocess(prog)
Karsten Hopp e73c54
+     nfa_regprog_T   *prog;
Karsten Hopp e73c54
+ {
Karsten Hopp e73c54
+     int i;
Karsten Hopp e73c54
+     int c;
Karsten Hopp e73c54
+ 
Karsten Hopp e73c54
+     for (i = 0; i < prog->nstate; ++i)
Karsten Hopp e73c54
+     {
Karsten Hopp e73c54
+ 	c = prog->state[i].c;
Karsten Hopp e73c54
+ 	if (c == NFA_START_INVISIBLE
Karsten Hopp e73c54
+ 		|| c == NFA_START_INVISIBLE_NEG
Karsten Hopp e73c54
+ 		|| c == NFA_START_INVISIBLE_BEFORE
Karsten Hopp e73c54
+ 		|| c == NFA_START_INVISIBLE_BEFORE_NEG)
Karsten Hopp e73c54
+ 	{
Karsten Hopp e73c54
+ 	    int directly;
Karsten Hopp e73c54
+ 
Karsten Hopp e73c54
+ 	    /* Do it directly when what follows is possibly the end of the
Karsten Hopp e73c54
+ 	     * match. */
Karsten Hopp e73c54
+ 	    if (match_follows(prog->state[i].out1->out, 0))
Karsten Hopp e73c54
+ 		directly = TRUE;
Karsten Hopp e73c54
+ 	    else
Karsten Hopp e73c54
+ 	    {
Karsten Hopp e73c54
+ 		int ch_invisible = failure_chance(prog->state[i].out, 0);
Karsten Hopp e73c54
+ 		int ch_follows = failure_chance(prog->state[i].out1->out, 0);
Karsten Hopp e73c54
+ 
Karsten Hopp e73c54
+ 		/* Postpone when the invisible match is expensive or has a
Karsten Hopp e73c54
+ 		 * lower chance of failing. */
Karsten Hopp e73c54
+ 		if (c == NFA_START_INVISIBLE_BEFORE
Karsten Hopp e73c54
+ 		     || c == NFA_START_INVISIBLE_BEFORE_NEG)
Karsten Hopp e73c54
+ 		{
Karsten Hopp e73c54
+ 		    /* "before" matches are very expensive when
Karsten Hopp e73c54
+ 		     * unbounded, always prefer what follows then,
Karsten Hopp e73c54
+ 		     * unless what follows will always match.
Karsten Hopp e73c54
+ 		     * Otherwise strongly prefer what follows. */
Karsten Hopp e73c54
+ 		    if (prog->state[i].val <= 0 && ch_follows > 0)
Karsten Hopp e73c54
+ 			directly = FALSE;
Karsten Hopp e73c54
+ 		    else
Karsten Hopp e73c54
+ 			directly = ch_follows * 10 < ch_invisible;
Karsten Hopp e73c54
+ 		}
Karsten Hopp e73c54
+ 		else
Karsten Hopp e73c54
+ 		{
Karsten Hopp e73c54
+ 		    /* normal invisible, first do the one with the
Karsten Hopp e73c54
+ 		     * highest failure chance */
Karsten Hopp e73c54
+ 		    directly = ch_follows < ch_invisible;
Karsten Hopp e73c54
+ 		}
Karsten Hopp e73c54
+ 	    }
Karsten Hopp e73c54
+ 	    if (directly)
Karsten Hopp e73c54
+ 		/* switch to the _FIRST state */
Karsten Hopp e73c54
+ 		++prog->state[i].c;
Karsten Hopp e73c54
+ 	}
Karsten Hopp e73c54
+     }
Karsten Hopp e73c54
+ }
Karsten Hopp e73c54
+ 
Karsten Hopp e73c54
  /****************************************************************
Karsten Hopp e73c54
   * NFA execution code.
Karsten Hopp e73c54
   ****************************************************************/
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 3457,3463 ****
Karsten Hopp e73c54
  static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from));
Karsten Hopp e73c54
  static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2));
Karsten Hopp e73c54
  static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
Karsten Hopp e73c54
- static int match_follows __ARGS((nfa_state_T *startstate, int depth));
Karsten Hopp e73c54
  static int state_in_list __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
Karsten Hopp e73c54
  static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int off));
Karsten Hopp e73c54
  static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int *ip));
Karsten Hopp e73c54
--- 3529,3534 ----
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 3703,3711 ****
Karsten Hopp e73c54
--- 3774,3786 ----
Karsten Hopp e73c54
  				     || match_follows(state->out1, depth + 1);
Karsten Hopp e73c54
  
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE:
Karsten Hopp e73c54
+ 	    case NFA_START_INVISIBLE_FIRST:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_BEFORE:
Karsten Hopp e73c54
+ 	    case NFA_START_INVISIBLE_BEFORE_FIRST:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_NEG:
Karsten Hopp e73c54
+ 	    case NFA_START_INVISIBLE_NEG_FIRST:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_BEFORE_NEG:
Karsten Hopp e73c54
+ 	    case NFA_START_INVISIBLE_BEFORE_NEG_FIRST:
Karsten Hopp e73c54
  	    case NFA_COMPOSING:
Karsten Hopp e73c54
  		/* skip ahead to next state */
Karsten Hopp e73c54
  		state = state->out1->out;
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 4440,4446 ****
Karsten Hopp e73c54
      }
Karsten Hopp e73c54
  
Karsten Hopp e73c54
      if (state->c == NFA_START_INVISIBLE_BEFORE
Karsten Hopp e73c54
!         || state->c == NFA_START_INVISIBLE_BEFORE_NEG)
Karsten Hopp e73c54
      {
Karsten Hopp e73c54
  	/* The recursive match must end at the current position. When "pim" is
Karsten Hopp e73c54
  	 * not NULL it specifies the current position. */
Karsten Hopp e73c54
--- 4515,4523 ----
Karsten Hopp e73c54
      }
Karsten Hopp e73c54
  
Karsten Hopp e73c54
      if (state->c == NFA_START_INVISIBLE_BEFORE
Karsten Hopp e73c54
!         || state->c == NFA_START_INVISIBLE_BEFORE_FIRST
Karsten Hopp e73c54
!         || state->c == NFA_START_INVISIBLE_BEFORE_NEG
Karsten Hopp e73c54
!         || state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)
Karsten Hopp e73c54
      {
Karsten Hopp e73c54
  	/* The recursive match must end at the current position. When "pim" is
Karsten Hopp e73c54
  	 * not NULL it specifies the current position. */
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 4581,4587 ****
Karsten Hopp e73c54
      return result;
Karsten Hopp e73c54
  }
Karsten Hopp e73c54
  
Karsten Hopp e73c54
- static int failure_chance __ARGS((nfa_state_T *state, int depth));
Karsten Hopp e73c54
  static int skip_to_start __ARGS((int c, colnr_T *colp));
Karsten Hopp e73c54
  static long find_match_text __ARGS((colnr_T startcol, int regstart, char_u *match_text));
Karsten Hopp e73c54
  
Karsten Hopp e73c54
--- 4658,4663 ----
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 5093,5142 ****
Karsten Hopp e73c54
  		break;
Karsten Hopp e73c54
  
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_NEG:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_BEFORE:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_BEFORE_NEG:
Karsten Hopp e73c54
  		{
Karsten Hopp e73c54
- 		    int directly = FALSE;
Karsten Hopp e73c54
- 
Karsten Hopp e73c54
  #ifdef ENABLE_LOG
Karsten Hopp e73c54
  		    fprintf(log_fd, "Failure chance invisible: %d, what follows: %d\n",
Karsten Hopp e73c54
  			    failure_chance(t->state->out, 0),
Karsten Hopp e73c54
  			    failure_chance(t->state->out1->out, 0));
Karsten Hopp e73c54
  #endif
Karsten Hopp e73c54
! 		    /* Do it directly when what follows is possibly the end of
Karsten Hopp e73c54
! 		     * the match.
Karsten Hopp e73c54
! 		     * Do it directly if there already is a PIM.
Karsten Hopp e73c54
! 		     * Postpone when the invisible match is expensive or has a
Karsten Hopp e73c54
! 		     * lower chance of failing. */
Karsten Hopp e73c54
! 		    if (match_follows(t->state->out1->out, 0)
Karsten Hopp e73c54
! 					   || t->pim.result != NFA_PIM_UNUSED)
Karsten Hopp e73c54
! 			directly = TRUE;
Karsten Hopp e73c54
! 		    else
Karsten Hopp e73c54
! 		    {
Karsten Hopp e73c54
! 			int ch_invisible = failure_chance(t->state->out, 0);
Karsten Hopp e73c54
! 			int ch_follows = failure_chance(t->state->out1->out, 0);
Karsten Hopp e73c54
! 
Karsten Hopp e73c54
! 			if (t->state->c == NFA_START_INVISIBLE_BEFORE
Karsten Hopp e73c54
! 			     || t->state->c == NFA_START_INVISIBLE_BEFORE_NEG)
Karsten Hopp e73c54
! 			{
Karsten Hopp e73c54
! 			    /* "before" matches are very expensive when
Karsten Hopp e73c54
! 			     * unbounded, always prefer what follows then,
Karsten Hopp e73c54
! 			     * unless what follows will always match.
Karsten Hopp e73c54
! 			     * Otherwise strongly prefer what follows. */
Karsten Hopp e73c54
! 			    if (t->state->val <= 0 && ch_follows > 0)
Karsten Hopp e73c54
! 				directly = FALSE;
Karsten Hopp e73c54
! 			    else
Karsten Hopp e73c54
! 				directly = ch_follows * 10 < ch_invisible;
Karsten Hopp e73c54
! 			}
Karsten Hopp e73c54
! 			else
Karsten Hopp e73c54
! 			{
Karsten Hopp e73c54
! 			    /* normal invisible, first do the one with the
Karsten Hopp e73c54
! 			     * highest failure chance */
Karsten Hopp e73c54
! 			    directly = ch_follows < ch_invisible;
Karsten Hopp e73c54
! 			}
Karsten Hopp e73c54
! 		    }
Karsten Hopp e73c54
! 		    if (directly)
Karsten Hopp e73c54
  		    {
Karsten Hopp e73c54
  			/*
Karsten Hopp e73c54
  			 * First try matching the invisible match, then what
Karsten Hopp e73c54
--- 5169,5194 ----
Karsten Hopp e73c54
  		break;
Karsten Hopp e73c54
  
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE:
Karsten Hopp e73c54
+ 	    case NFA_START_INVISIBLE_FIRST:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_NEG:
Karsten Hopp e73c54
+ 	    case NFA_START_INVISIBLE_NEG_FIRST:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_BEFORE:
Karsten Hopp e73c54
+ 	    case NFA_START_INVISIBLE_BEFORE_FIRST:
Karsten Hopp e73c54
  	    case NFA_START_INVISIBLE_BEFORE_NEG:
Karsten Hopp e73c54
+ 	    case NFA_START_INVISIBLE_BEFORE_NEG_FIRST:
Karsten Hopp e73c54
  		{
Karsten Hopp e73c54
  #ifdef ENABLE_LOG
Karsten Hopp e73c54
  		    fprintf(log_fd, "Failure chance invisible: %d, what follows: %d\n",
Karsten Hopp e73c54
  			    failure_chance(t->state->out, 0),
Karsten Hopp e73c54
  			    failure_chance(t->state->out1->out, 0));
Karsten Hopp e73c54
  #endif
Karsten Hopp e73c54
! 		    /* Do it directly if there already is a PIM or when
Karsten Hopp e73c54
! 		     * nfa_postprocess() detected it will work better. */
Karsten Hopp e73c54
! 		    if (t->pim.result != NFA_PIM_UNUSED
Karsten Hopp e73c54
! 			 || t->state->c == NFA_START_INVISIBLE_FIRST
Karsten Hopp e73c54
! 			 || t->state->c == NFA_START_INVISIBLE_NEG_FIRST
Karsten Hopp e73c54
! 			 || t->state->c == NFA_START_INVISIBLE_BEFORE_FIRST
Karsten Hopp e73c54
! 			 || t->state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)
Karsten Hopp e73c54
  		    {
Karsten Hopp e73c54
  			/*
Karsten Hopp e73c54
  			 * First try matching the invisible match, then what
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 5148,5155 ****
Karsten Hopp e73c54
  			/* for \@! and \@
Karsten Hopp e73c54
  			 * FALSE */
Karsten Hopp e73c54
  			if (result != (t->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp e73c54
! 			            || t->state->c
Karsten Hopp e73c54
! 					   == NFA_START_INVISIBLE_BEFORE_NEG))
Karsten Hopp e73c54
  			{
Karsten Hopp e73c54
  			    /* Copy submatch info from the recursive call */
Karsten Hopp e73c54
  			    copy_sub_off(&t->subs.norm, &m->norm);
Karsten Hopp e73c54
--- 5200,5210 ----
Karsten Hopp e73c54
  			/* for \@! and \@
Karsten Hopp e73c54
  			 * FALSE */
Karsten Hopp e73c54
  			if (result != (t->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp e73c54
! 			       || t->state->c == NFA_START_INVISIBLE_NEG_FIRST
Karsten Hopp e73c54
! 			       || t->state->c
Karsten Hopp e73c54
! 					   == NFA_START_INVISIBLE_BEFORE_NEG
Karsten Hopp e73c54
! 			       || t->state->c
Karsten Hopp e73c54
! 				     == NFA_START_INVISIBLE_BEFORE_NEG_FIRST))
Karsten Hopp e73c54
  			{
Karsten Hopp e73c54
  			    /* Copy submatch info from the recursive call */
Karsten Hopp e73c54
  			    copy_sub_off(&t->subs.norm, &m->norm);
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 5920,5927 ****
Karsten Hopp e73c54
  			/* for \@! and \@
Karsten Hopp e73c54
  			 * FALSE */
Karsten Hopp e73c54
  			if (result != (pim->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp e73c54
! 			            || pim->state->c
Karsten Hopp e73c54
! 					   == NFA_START_INVISIBLE_BEFORE_NEG))
Karsten Hopp e73c54
  			{
Karsten Hopp e73c54
  			    /* Copy submatch info from the recursive call */
Karsten Hopp e73c54
  			    copy_sub_off(&pim->subs.norm, &m->norm);
Karsten Hopp e73c54
--- 5975,5985 ----
Karsten Hopp e73c54
  			/* for \@! and \@
Karsten Hopp e73c54
  			 * FALSE */
Karsten Hopp e73c54
  			if (result != (pim->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp e73c54
! 			     || pim->state->c == NFA_START_INVISIBLE_NEG_FIRST
Karsten Hopp e73c54
! 			     || pim->state->c
Karsten Hopp e73c54
! 					   == NFA_START_INVISIBLE_BEFORE_NEG
Karsten Hopp e73c54
! 			     || pim->state->c
Karsten Hopp e73c54
! 				     == NFA_START_INVISIBLE_BEFORE_NEG_FIRST))
Karsten Hopp e73c54
  			{
Karsten Hopp e73c54
  			    /* Copy submatch info from the recursive call */
Karsten Hopp e73c54
  			    copy_sub_off(&pim->subs.norm, &m->norm);
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 5944,5951 ****
Karsten Hopp e73c54
  
Karsten Hopp e73c54
  		    /* for \@! and \@
Karsten Hopp e73c54
  		    if (result != (pim->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp e73c54
! 			        || pim->state->c
Karsten Hopp e73c54
! 					   == NFA_START_INVISIBLE_BEFORE_NEG))
Karsten Hopp e73c54
  		    {
Karsten Hopp e73c54
  			/* Copy submatch info from the recursive call */
Karsten Hopp e73c54
  			copy_sub_off(&t->subs.norm, &pim->subs.norm);
Karsten Hopp e73c54
--- 6002,6012 ----
Karsten Hopp e73c54
  
Karsten Hopp e73c54
  		    /* for \@! and \@
Karsten Hopp e73c54
  		    if (result != (pim->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp e73c54
! 			     || pim->state->c == NFA_START_INVISIBLE_NEG_FIRST
Karsten Hopp e73c54
! 			     || pim->state->c
Karsten Hopp e73c54
! 					   == NFA_START_INVISIBLE_BEFORE_NEG
Karsten Hopp e73c54
! 			     || pim->state->c
Karsten Hopp e73c54
! 				     == NFA_START_INVISIBLE_BEFORE_NEG_FIRST))
Karsten Hopp e73c54
  		    {
Karsten Hopp e73c54
  			/* Copy submatch info from the recursive call */
Karsten Hopp e73c54
  			copy_sub_off(&t->subs.norm, &pim->subs.norm);
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 6413,6421 ****
Karsten Hopp e73c54
      prog->has_backref = nfa_has_backref;
Karsten Hopp e73c54
      prog->nsubexp = regnpar;
Karsten Hopp e73c54
  
Karsten Hopp e73c54
      prog->reganch = nfa_get_reganch(prog->start, 0);
Karsten Hopp e73c54
      prog->regstart = nfa_get_regstart(prog->start, 0);
Karsten Hopp e73c54
- 
Karsten Hopp e73c54
      prog->match_text = nfa_get_match_text(prog->start);
Karsten Hopp e73c54
  
Karsten Hopp e73c54
  #ifdef ENABLE_LOG
Karsten Hopp e73c54
--- 6474,6483 ----
Karsten Hopp e73c54
      prog->has_backref = nfa_has_backref;
Karsten Hopp e73c54
      prog->nsubexp = regnpar;
Karsten Hopp e73c54
  
Karsten Hopp e73c54
+     nfa_postprocess(prog);
Karsten Hopp e73c54
+ 
Karsten Hopp e73c54
      prog->reganch = nfa_get_reganch(prog->start, 0);
Karsten Hopp e73c54
      prog->regstart = nfa_get_regstart(prog->start, 0);
Karsten Hopp e73c54
      prog->match_text = nfa_get_match_text(prog->start);
Karsten Hopp e73c54
  
Karsten Hopp e73c54
  #ifdef ENABLE_LOG
Karsten Hopp e73c54
*** ../vim-7.3.1168/src/version.c	2013-06-11 20:53:24.000000000 +0200
Karsten Hopp e73c54
--- src/version.c	2013-06-11 22:43:27.000000000 +0200
Karsten Hopp e73c54
***************
Karsten Hopp e73c54
*** 730,731 ****
Karsten Hopp e73c54
--- 730,733 ----
Karsten Hopp e73c54
  {   /* Add new patch number below this line */
Karsten Hopp e73c54
+ /**/
Karsten Hopp e73c54
+     1169,
Karsten Hopp e73c54
  /**/
Karsten Hopp e73c54
Karsten Hopp e73c54
-- 
Karsten Hopp e73c54
hundred-and-one symptoms of being an internet addict:
Karsten Hopp e73c54
156. You forget your friend's name but not her e-mail address.
Karsten Hopp e73c54
Karsten Hopp e73c54
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp e73c54
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp e73c54
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp e73c54
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///