Karsten Hopp 031077
To: vim_dev@googlegroups.com
Karsten Hopp 031077
Subject: Patch 7.3.1153
Karsten Hopp 031077
Fcc: outbox
Karsten Hopp 031077
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 031077
Mime-Version: 1.0
Karsten Hopp 031077
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 031077
Content-Transfer-Encoding: 8bit
Karsten Hopp 031077
------------
Karsten Hopp 031077
Karsten Hopp 031077
Patch 7.3.1153
Karsten Hopp 031077
Problem:    New regexp engine: Some look-behind matches are very expensive.
Karsten Hopp 031077
Solution:   Pospone invisible matches further, until a match is almost found.
Karsten Hopp 031077
Files:	    src/regexp_nfa.c
Karsten Hopp 031077
Karsten Hopp 031077
Karsten Hopp 031077
*** ../vim-7.3.1152/src/regexp_nfa.c	2013-06-08 23:30:00.000000000 +0200
Karsten Hopp 031077
--- src/regexp_nfa.c	2013-06-09 16:11:41.000000000 +0200
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3354,3369 ****
Karsten Hopp 031077
  typedef struct nfa_pim_S nfa_pim_T;
Karsten Hopp 031077
  struct nfa_pim_S
Karsten Hopp 031077
  {
Karsten Hopp 031077
!     nfa_state_T	*state;
Karsten Hopp 031077
!     int		result;		/* NFA_PIM_TODO, NFA_PIM_[NO]MATCH */
Karsten Hopp 031077
!     nfa_pim_T	*pim;		/* another PIM at the same position */
Karsten Hopp 031077
      regsubs_T	subs;		/* submatch info, only party used */
Karsten Hopp 031077
  };
Karsten Hopp 031077
  
Karsten Hopp 031077
  /* Values for done in nfa_pim_T. */
Karsten Hopp 031077
! #define NFA_PIM_TODO    0
Karsten Hopp 031077
! #define NFA_PIM_MATCH   1
Karsten Hopp 031077
! #define NFA_PIM_NOMATCH -1
Karsten Hopp 031077
  
Karsten Hopp 031077
  
Karsten Hopp 031077
  /* nfa_thread_T contains execution information of a NFA state */
Karsten Hopp 031077
--- 3354,3374 ----
Karsten Hopp 031077
  typedef struct nfa_pim_S nfa_pim_T;
Karsten Hopp 031077
  struct nfa_pim_S
Karsten Hopp 031077
  {
Karsten Hopp 031077
!     int		result;		/* NFA_PIM_*, see below */
Karsten Hopp 031077
!     nfa_state_T	*state;		/* the invisible match start state */
Karsten Hopp 031077
      regsubs_T	subs;		/* submatch info, only party used */
Karsten Hopp 031077
+     union
Karsten Hopp 031077
+     {
Karsten Hopp 031077
+ 	lpos_T	pos;
Karsten Hopp 031077
+ 	char_u	*ptr;
Karsten Hopp 031077
+     } end;			/* where the match must end */
Karsten Hopp 031077
  };
Karsten Hopp 031077
  
Karsten Hopp 031077
  /* Values for done in nfa_pim_T. */
Karsten Hopp 031077
! #define NFA_PIM_UNUSED   0	/* pim not used */
Karsten Hopp 031077
! #define NFA_PIM_TODO     1	/* pim not done yet */
Karsten Hopp 031077
! #define NFA_PIM_MATCH    2	/* pim executed, matches */
Karsten Hopp 031077
! #define NFA_PIM_NOMATCH  3	/* pim executed, no match */
Karsten Hopp 031077
  
Karsten Hopp 031077
  
Karsten Hopp 031077
  /* nfa_thread_T contains execution information of a NFA state */
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3371,3377 ****
Karsten Hopp 031077
  {
Karsten Hopp 031077
      nfa_state_T	*state;
Karsten Hopp 031077
      int		count;
Karsten Hopp 031077
!     nfa_pim_T	*pim;		/* if not NULL: postponed invisible match */
Karsten Hopp 031077
      regsubs_T	subs;		/* submatch info, only party used */
Karsten Hopp 031077
  } nfa_thread_T;
Karsten Hopp 031077
  
Karsten Hopp 031077
--- 3376,3383 ----
Karsten Hopp 031077
  {
Karsten Hopp 031077
      nfa_state_T	*state;
Karsten Hopp 031077
      int		count;
Karsten Hopp 031077
!     nfa_pim_T	pim;		/* if pim.result != NFA_PIM_UNUSED: postponed
Karsten Hopp 031077
! 				 * invisible match */
Karsten Hopp 031077
      regsubs_T	subs;		/* submatch info, only party used */
Karsten Hopp 031077
  } nfa_thread_T;
Karsten Hopp 031077
  
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3424,3434 ****
Karsten Hopp 031077
--- 3430,3457 ----
Karsten Hopp 031077
  		    e == NULL ? "NULL" : e);
Karsten Hopp 031077
  	}
Karsten Hopp 031077
  }
Karsten Hopp 031077
+ 
Karsten Hopp 031077
+     static char *
Karsten Hopp 031077
+ pim_info(nfa_pim_T *pim)
Karsten Hopp 031077
+ {
Karsten Hopp 031077
+     static char buf[30];
Karsten Hopp 031077
+ 
Karsten Hopp 031077
+     if (pim == NULL || pim->result == NFA_PIM_UNUSED)
Karsten Hopp 031077
+ 	buf[0] = NUL;
Karsten Hopp 031077
+     else
Karsten Hopp 031077
+     {
Karsten Hopp 031077
+ 	sprintf(buf, " PIM col %d", REG_MULTI ? (int)pim->end.pos.col
Karsten Hopp 031077
+ 		: (int)(pim->end.ptr - reginput));
Karsten Hopp 031077
+     }
Karsten Hopp 031077
+     return buf;
Karsten Hopp 031077
+ }
Karsten Hopp 031077
+ 
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  
Karsten Hopp 031077
  /* Used during execution: whether a match has been found. */
Karsten Hopp 031077
  static int nfa_match;
Karsten Hopp 031077
  
Karsten Hopp 031077
+ static void copy_pim __ARGS((nfa_pim_T *to, nfa_pim_T *from));
Karsten Hopp 031077
  static void clear_sub __ARGS((regsub_T *sub));
Karsten Hopp 031077
  static void copy_sub __ARGS((regsub_T *to, regsub_T *from));
Karsten Hopp 031077
  static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from));
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3436,3444 ****
Karsten Hopp 031077
  static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
Karsten Hopp 031077
  static int match_follows __ARGS((nfa_state_T *startstate, int depth));
Karsten Hopp 031077
  static int state_in_list __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
Karsten Hopp 031077
! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, int off));
Karsten Hopp 031077
  static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int *ip));
Karsten Hopp 031077
  
Karsten Hopp 031077
      static void
Karsten Hopp 031077
  clear_sub(sub)
Karsten Hopp 031077
      regsub_T *sub;
Karsten Hopp 031077
--- 3459,3485 ----
Karsten Hopp 031077
  static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
Karsten Hopp 031077
  static int match_follows __ARGS((nfa_state_T *startstate, int depth));
Karsten Hopp 031077
  static int state_in_list __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs));
Karsten Hopp 031077
! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int off));
Karsten Hopp 031077
  static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim, int *ip));
Karsten Hopp 031077
  
Karsten Hopp 031077
+ /*
Karsten Hopp 031077
+  * Copy postponed invisible match info from "from" to "to".
Karsten Hopp 031077
+  */
Karsten Hopp 031077
+     static void
Karsten Hopp 031077
+ copy_pim(to, from)
Karsten Hopp 031077
+     nfa_pim_T *to;
Karsten Hopp 031077
+     nfa_pim_T *from;
Karsten Hopp 031077
+ {
Karsten Hopp 031077
+     to->result = from->result;
Karsten Hopp 031077
+     to->state = from->state;
Karsten Hopp 031077
+     copy_sub(&to->subs.norm, &from->subs.norm);
Karsten Hopp 031077
+ #ifdef FEAT_SYN_HL
Karsten Hopp 031077
+     if (nfa_has_zsubexpr)
Karsten Hopp 031077
+ 	copy_sub(&to->subs.synt, &from->subs.synt);
Karsten Hopp 031077
+ #endif
Karsten Hopp 031077
+     to->end = from->end;
Karsten Hopp 031077
+ }
Karsten Hopp 031077
+ 
Karsten Hopp 031077
      static void
Karsten Hopp 031077
  clear_sub(sub)
Karsten Hopp 031077
      regsub_T *sub;
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3583,3589 ****
Karsten Hopp 031077
  
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
      static void
Karsten Hopp 031077
! report_state(char *action, regsub_T *sub, nfa_state_T *state, int lid)
Karsten Hopp 031077
  {
Karsten Hopp 031077
      int col;
Karsten Hopp 031077
  
Karsten Hopp 031077
--- 3624,3634 ----
Karsten Hopp 031077
  
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
      static void
Karsten Hopp 031077
! report_state(char *action,
Karsten Hopp 031077
! 	     regsub_T *sub,
Karsten Hopp 031077
! 	     nfa_state_T *state,
Karsten Hopp 031077
! 	     int lid,
Karsten Hopp 031077
! 	     nfa_pim_T *pim)
Karsten Hopp 031077
  {
Karsten Hopp 031077
      int col;
Karsten Hopp 031077
  
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3594,3601 ****
Karsten Hopp 031077
      else
Karsten Hopp 031077
  	col = (int)(sub->list.line[0].start - regline);
Karsten Hopp 031077
      nfa_set_code(state->c);
Karsten Hopp 031077
!     fprintf(log_fd, "> %s state %d to list %d. char %d: %s (start col %d)\n",
Karsten Hopp 031077
! 	    action, abs(state->id), lid, state->c, code, col);
Karsten Hopp 031077
  }
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  
Karsten Hopp 031077
--- 3639,3647 ----
Karsten Hopp 031077
      else
Karsten Hopp 031077
  	col = (int)(sub->list.line[0].start - regline);
Karsten Hopp 031077
      nfa_set_code(state->c);
Karsten Hopp 031077
!     fprintf(log_fd, "> %s state %d to list %d. char %d: %s (start col %d)%s\n",
Karsten Hopp 031077
! 	    action, abs(state->id), lid, state->c, code, col,
Karsten Hopp 031077
! 	    pim_info(pim));
Karsten Hopp 031077
  }
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3646,3651 ****
Karsten Hopp 031077
--- 3692,3701 ----
Karsten Hopp 031077
  	switch (state->c)
Karsten Hopp 031077
  	{
Karsten Hopp 031077
  	    case NFA_MATCH:
Karsten Hopp 031077
+ 	    case NFA_MCLOSE:
Karsten Hopp 031077
+ 	    case NFA_END_INVISIBLE:
Karsten Hopp 031077
+ 	    case NFA_END_INVISIBLE_NEG:
Karsten Hopp 031077
+ 	    case NFA_END_PATTERN:
Karsten Hopp 031077
  		return TRUE;
Karsten Hopp 031077
  
Karsten Hopp 031077
  	    case NFA_SPLIT:
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3727,3736 ****
Karsten Hopp 031077
  }
Karsten Hopp 031077
  
Karsten Hopp 031077
      static void
Karsten Hopp 031077
! addstate(l, state, subs, off)
Karsten Hopp 031077
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp 031077
      nfa_state_T		*state;	/* state to update */
Karsten Hopp 031077
      regsubs_T		*subs;	/* pointers to subexpressions */
Karsten Hopp 031077
      int			off;	/* byte offset, when -1 go to next line */
Karsten Hopp 031077
  {
Karsten Hopp 031077
      int			subidx;
Karsten Hopp 031077
--- 3777,3787 ----
Karsten Hopp 031077
  }
Karsten Hopp 031077
  
Karsten Hopp 031077
      static void
Karsten Hopp 031077
! addstate(l, state, subs, pim, off)
Karsten Hopp 031077
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp 031077
      nfa_state_T		*state;	/* state to update */
Karsten Hopp 031077
      regsubs_T		*subs;	/* pointers to subexpressions */
Karsten Hopp 031077
+     nfa_pim_T		*pim;   /* postponed look-behind match */
Karsten Hopp 031077
      int			off;	/* byte offset, when -1 go to next line */
Karsten Hopp 031077
  {
Karsten Hopp 031077
      int			subidx;
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3856,3876 ****
Karsten Hopp 031077
  	    state->lastlist[nfa_ll_index] = l->id;
Karsten Hopp 031077
  	    thread = &l->t[l->n++];
Karsten Hopp 031077
  	    thread->state = state;
Karsten Hopp 031077
! 	    thread->pim = NULL;
Karsten Hopp 031077
  	    copy_sub(&thread->subs.norm, &subs->norm);
Karsten Hopp 031077
  #ifdef FEAT_SYN_HL
Karsten Hopp 031077
  	    if (nfa_has_zsubexpr)
Karsten Hopp 031077
  		copy_sub(&thread->subs.synt, &subs->synt);
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
! 	    report_state("Adding", &thread->subs.norm, state, l->id);
Karsten Hopp 031077
  	    did_print = TRUE;
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
      }
Karsten Hopp 031077
  
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
      if (!did_print)
Karsten Hopp 031077
! 	report_state("Processing", &subs->norm, state, l->id);
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
      switch (state->c)
Karsten Hopp 031077
      {
Karsten Hopp 031077
--- 3907,3930 ----
Karsten Hopp 031077
  	    state->lastlist[nfa_ll_index] = l->id;
Karsten Hopp 031077
  	    thread = &l->t[l->n++];
Karsten Hopp 031077
  	    thread->state = state;
Karsten Hopp 031077
! 	    if (pim == NULL)
Karsten Hopp 031077
! 		thread->pim.result = NFA_PIM_UNUSED;
Karsten Hopp 031077
! 	    else
Karsten Hopp 031077
! 		copy_pim(&thread->pim, pim);
Karsten Hopp 031077
  	    copy_sub(&thread->subs.norm, &subs->norm);
Karsten Hopp 031077
  #ifdef FEAT_SYN_HL
Karsten Hopp 031077
  	    if (nfa_has_zsubexpr)
Karsten Hopp 031077
  		copy_sub(&thread->subs.synt, &subs->synt);
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
! 	    report_state("Adding", &thread->subs.norm, state, l->id, pim);
Karsten Hopp 031077
  	    did_print = TRUE;
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
      }
Karsten Hopp 031077
  
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
      if (!did_print)
Karsten Hopp 031077
! 	report_state("Processing", &subs->norm, state, l->id, pim);
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
      switch (state->c)
Karsten Hopp 031077
      {
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3880,3893 ****
Karsten Hopp 031077
  
Karsten Hopp 031077
  	case NFA_SPLIT:
Karsten Hopp 031077
  	    /* order matters here */
Karsten Hopp 031077
! 	    addstate(l, state->out, subs, off);
Karsten Hopp 031077
! 	    addstate(l, state->out1, subs, off);
Karsten Hopp 031077
  	    break;
Karsten Hopp 031077
  
Karsten Hopp 031077
  	case NFA_SKIP_CHAR:
Karsten Hopp 031077
  	case NFA_NOPEN:
Karsten Hopp 031077
  	case NFA_NCLOSE:
Karsten Hopp 031077
! 	    addstate(l, state->out, subs, off);
Karsten Hopp 031077
  	    break;
Karsten Hopp 031077
  
Karsten Hopp 031077
  	case NFA_MOPEN:
Karsten Hopp 031077
--- 3934,3947 ----
Karsten Hopp 031077
  
Karsten Hopp 031077
  	case NFA_SPLIT:
Karsten Hopp 031077
  	    /* order matters here */
Karsten Hopp 031077
! 	    addstate(l, state->out, subs, pim, off);
Karsten Hopp 031077
! 	    addstate(l, state->out1, subs, pim, off);
Karsten Hopp 031077
  	    break;
Karsten Hopp 031077
  
Karsten Hopp 031077
  	case NFA_SKIP_CHAR:
Karsten Hopp 031077
  	case NFA_NOPEN:
Karsten Hopp 031077
  	case NFA_NCLOSE:
Karsten Hopp 031077
! 	    addstate(l, state->out, subs, pim, off);
Karsten Hopp 031077
  	    break;
Karsten Hopp 031077
  
Karsten Hopp 031077
  	case NFA_MOPEN:
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 3983,3989 ****
Karsten Hopp 031077
  		sub->list.line[subidx].start = reginput + off;
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  
Karsten Hopp 031077
! 	    addstate(l, state->out, subs, off);
Karsten Hopp 031077
  
Karsten Hopp 031077
  	    if (save_in_use == -1)
Karsten Hopp 031077
  	    {
Karsten Hopp 031077
--- 4037,4043 ----
Karsten Hopp 031077
  		sub->list.line[subidx].start = reginput + off;
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  
Karsten Hopp 031077
! 	    addstate(l, state->out, subs, pim, off);
Karsten Hopp 031077
  
Karsten Hopp 031077
  	    if (save_in_use == -1)
Karsten Hopp 031077
  	    {
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4001,4007 ****
Karsten Hopp 031077
  	    {
Karsten Hopp 031077
  		/* Do not overwrite the position set by \ze. If no \ze
Karsten Hopp 031077
  		 * encountered end will be set in nfa_regtry(). */
Karsten Hopp 031077
! 		addstate(l, state->out, subs, off);
Karsten Hopp 031077
  		break;
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  	case NFA_MCLOSE1:
Karsten Hopp 031077
--- 4055,4061 ----
Karsten Hopp 031077
  	    {
Karsten Hopp 031077
  		/* Do not overwrite the position set by \ze. If no \ze
Karsten Hopp 031077
  		 * encountered end will be set in nfa_regtry(). */
Karsten Hopp 031077
! 		addstate(l, state->out, subs, pim, off);
Karsten Hopp 031077
  		break;
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  	case NFA_MCLOSE1:
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4070,4076 ****
Karsten Hopp 031077
  		sub->list.line[subidx].end = reginput + off;
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  
Karsten Hopp 031077
! 	    addstate(l, state->out, subs, off);
Karsten Hopp 031077
  
Karsten Hopp 031077
  	    if (REG_MULTI)
Karsten Hopp 031077
  		sub->list.multi[subidx].end = save_lpos;
Karsten Hopp 031077
--- 4124,4130 ----
Karsten Hopp 031077
  		sub->list.line[subidx].end = reginput + off;
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  
Karsten Hopp 031077
! 	    addstate(l, state->out, subs, pim, off);
Karsten Hopp 031077
  
Karsten Hopp 031077
  	    if (REG_MULTI)
Karsten Hopp 031077
  		sub->list.multi[subidx].end = save_lpos;
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4098,4112 ****
Karsten Hopp 031077
      int tlen = l->n;
Karsten Hopp 031077
      int count;
Karsten Hopp 031077
      int listidx = *ip;
Karsten Hopp 031077
-     int i;
Karsten Hopp 031077
  
Karsten Hopp 031077
      /* first add the state(s) at the end, so that we know how many there are */
Karsten Hopp 031077
!     addstate(l, state, subs, 0);
Karsten Hopp 031077
! 
Karsten Hopp 031077
!     /* fill in the "pim" field in the new states */
Karsten Hopp 031077
!     if (pim != NULL)
Karsten Hopp 031077
! 	for (i = tlen; i < l->n; ++i)
Karsten Hopp 031077
! 	    l->t[i].pim = pim;
Karsten Hopp 031077
  
Karsten Hopp 031077
      /* when "*ip" was at the end of the list, nothing to do */
Karsten Hopp 031077
      if (listidx + 1 == tlen)
Karsten Hopp 031077
--- 4152,4160 ----
Karsten Hopp 031077
      int tlen = l->n;
Karsten Hopp 031077
      int count;
Karsten Hopp 031077
      int listidx = *ip;
Karsten Hopp 031077
  
Karsten Hopp 031077
      /* first add the state(s) at the end, so that we know how many there are */
Karsten Hopp 031077
!     addstate(l, state, subs, pim, 0);
Karsten Hopp 031077
  
Karsten Hopp 031077
      /* when "*ip" was at the end of the list, nothing to do */
Karsten Hopp 031077
      if (listidx + 1 == tlen)
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4355,4369 ****
Karsten Hopp 031077
      return val == pos;
Karsten Hopp 031077
  }
Karsten Hopp 031077
  
Karsten Hopp 031077
! static int recursive_regmatch __ARGS((nfa_state_T *state, nfa_regprog_T *prog, regsubs_T *submatch, regsubs_T *m, int **listids));
Karsten Hopp 031077
  static int nfa_regmatch __ARGS((nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *submatch, regsubs_T *m));
Karsten Hopp 031077
  
Karsten Hopp 031077
  /*
Karsten Hopp 031077
   * Recursively call nfa_regmatch()
Karsten Hopp 031077
   */
Karsten Hopp 031077
      static int
Karsten Hopp 031077
! recursive_regmatch(state, prog, submatch, m, listids)
Karsten Hopp 031077
      nfa_state_T	    *state;
Karsten Hopp 031077
      nfa_regprog_T   *prog;
Karsten Hopp 031077
      regsubs_T	    *submatch;
Karsten Hopp 031077
      regsubs_T	    *m;
Karsten Hopp 031077
--- 4403,4420 ----
Karsten Hopp 031077
      return val == pos;
Karsten Hopp 031077
  }
Karsten Hopp 031077
  
Karsten Hopp 031077
! static int recursive_regmatch __ARGS((nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T *prog, regsubs_T *submatch, regsubs_T *m, int **listids));
Karsten Hopp 031077
  static int nfa_regmatch __ARGS((nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *submatch, regsubs_T *m));
Karsten Hopp 031077
  
Karsten Hopp 031077
  /*
Karsten Hopp 031077
   * Recursively call nfa_regmatch()
Karsten Hopp 031077
+  * "pim" is NULL or contains info about a Postponed Invisible Match (start
Karsten Hopp 031077
+  * position).
Karsten Hopp 031077
   */
Karsten Hopp 031077
      static int
Karsten Hopp 031077
! recursive_regmatch(state, pim, prog, submatch, m, listids)
Karsten Hopp 031077
      nfa_state_T	    *state;
Karsten Hopp 031077
+     nfa_pim_T	    *pim;
Karsten Hopp 031077
      nfa_regprog_T   *prog;
Karsten Hopp 031077
      regsubs_T	    *submatch;
Karsten Hopp 031077
      regsubs_T	    *m;
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4380,4397 ****
Karsten Hopp 031077
      int		result;
Karsten Hopp 031077
      int		need_restore = FALSE;
Karsten Hopp 031077
  
Karsten Hopp 031077
      if (state->c == NFA_START_INVISIBLE_BEFORE
Karsten Hopp 031077
          || state->c == NFA_START_INVISIBLE_BEFORE_NEG)
Karsten Hopp 031077
      {
Karsten Hopp 031077
! 	/* The recursive match must end at the current position. */
Karsten Hopp 031077
  	endposp = &endpos;
Karsten Hopp 031077
  	if (REG_MULTI)
Karsten Hopp 031077
  	{
Karsten Hopp 031077
! 	    endpos.se_u.pos.col = (int)(reginput - regline);
Karsten Hopp 031077
! 	    endpos.se_u.pos.lnum = reglnum;
Karsten Hopp 031077
  	}
Karsten Hopp 031077
  	else
Karsten Hopp 031077
! 	    endpos.se_u.ptr = reginput;
Karsten Hopp 031077
  
Karsten Hopp 031077
  	/* Go back the specified number of bytes, or as far as the
Karsten Hopp 031077
  	 * start of the previous line, to try matching "\@<=" or
Karsten Hopp 031077
--- 4431,4468 ----
Karsten Hopp 031077
      int		result;
Karsten Hopp 031077
      int		need_restore = FALSE;
Karsten Hopp 031077
  
Karsten Hopp 031077
+     if (pim != NULL)
Karsten Hopp 031077
+     {
Karsten Hopp 031077
+ 	/* start at the position where the postponed match was */
Karsten Hopp 031077
+ 	if (REG_MULTI)
Karsten Hopp 031077
+ 	    reginput = regline + pim->end.pos.col;
Karsten Hopp 031077
+ 	else
Karsten Hopp 031077
+ 	    reginput = pim->end.ptr;
Karsten Hopp 031077
+     }
Karsten Hopp 031077
+ 
Karsten Hopp 031077
      if (state->c == NFA_START_INVISIBLE_BEFORE
Karsten Hopp 031077
          || state->c == NFA_START_INVISIBLE_BEFORE_NEG)
Karsten Hopp 031077
      {
Karsten Hopp 031077
! 	/* The recursive match must end at the current position. When "pim" is
Karsten Hopp 031077
! 	 * not NULL it specifies the current position. */
Karsten Hopp 031077
  	endposp = &endpos;
Karsten Hopp 031077
  	if (REG_MULTI)
Karsten Hopp 031077
  	{
Karsten Hopp 031077
! 	    if (pim == NULL)
Karsten Hopp 031077
! 	    {
Karsten Hopp 031077
! 		endpos.se_u.pos.col = (int)(reginput - regline);
Karsten Hopp 031077
! 		endpos.se_u.pos.lnum = reglnum;
Karsten Hopp 031077
! 	    }
Karsten Hopp 031077
! 	    else
Karsten Hopp 031077
! 		endpos.se_u.pos = pim->end.pos;
Karsten Hopp 031077
  	}
Karsten Hopp 031077
  	else
Karsten Hopp 031077
! 	{
Karsten Hopp 031077
! 	    if (pim == NULL)
Karsten Hopp 031077
! 		endpos.se_u.ptr = reginput;
Karsten Hopp 031077
! 	    else
Karsten Hopp 031077
! 		endpos.se_u.ptr = pim->end.ptr;
Karsten Hopp 031077
! 	}
Karsten Hopp 031077
  
Karsten Hopp 031077
  	/* Go back the specified number of bytes, or as far as the
Karsten Hopp 031077
  	 * start of the previous line, to try matching "\@<=" or
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4784,4790 ****
Karsten Hopp 031077
      int		add_here;
Karsten Hopp 031077
      int		add_count;
Karsten Hopp 031077
      int		add_off;
Karsten Hopp 031077
-     garray_T	pimlist;
Karsten Hopp 031077
      int		toplevel = start->c == NFA_MOPEN;
Karsten Hopp 031077
  #ifdef NFA_REGEXP_DEBUG_LOG
Karsten Hopp 031077
      FILE	*debug = fopen(NFA_REGEXP_DEBUG_LOG, "a");
Karsten Hopp 031077
--- 4855,4860 ----
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4796,4802 ****
Karsten Hopp 031077
      }
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
      nfa_match = FALSE;
Karsten Hopp 031077
-     ga_init2(&pimlist, sizeof(nfa_pim_T), 5);
Karsten Hopp 031077
  
Karsten Hopp 031077
      /* Allocate memory for the lists of nodes. */
Karsten Hopp 031077
      size = (nstate + 1) * sizeof(nfa_thread_T);
Karsten Hopp 031077
--- 4866,4871 ----
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4845,4854 ****
Karsten Hopp 031077
  	else
Karsten Hopp 031077
  	    m->norm.list.line[0].start = reginput;
Karsten Hopp 031077
  	m->norm.in_use = 1;
Karsten Hopp 031077
! 	addstate(thislist, start->out, m, 0);
Karsten Hopp 031077
      }
Karsten Hopp 031077
      else
Karsten Hopp 031077
! 	addstate(thislist, start, m, 0);
Karsten Hopp 031077
  
Karsten Hopp 031077
  #define	ADD_STATE_IF_MATCH(state)			\
Karsten Hopp 031077
      if (result) {					\
Karsten Hopp 031077
--- 4914,4923 ----
Karsten Hopp 031077
  	else
Karsten Hopp 031077
  	    m->norm.list.line[0].start = reginput;
Karsten Hopp 031077
  	m->norm.in_use = 1;
Karsten Hopp 031077
! 	addstate(thislist, start->out, m, NULL, 0);
Karsten Hopp 031077
      }
Karsten Hopp 031077
      else
Karsten Hopp 031077
! 	addstate(thislist, start, m, NULL, 0);
Karsten Hopp 031077
  
Karsten Hopp 031077
  #define	ADD_STATE_IF_MATCH(state)			\
Karsten Hopp 031077
      if (result) {					\
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4890,4897 ****
Karsten Hopp 031077
  	thislist->id = nfa_listid;
Karsten Hopp 031077
  	nextlist->id = nfa_listid + 1;
Karsten Hopp 031077
  
Karsten Hopp 031077
- 	pimlist.ga_len = 0;
Karsten Hopp 031077
- 
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
  	fprintf(log_fd, "------------------------------------------\n");
Karsten Hopp 031077
  	fprintf(log_fd, ">>> Reginput is \"%s\"\n", reginput);
Karsten Hopp 031077
--- 4959,4964 ----
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 4935,4942 ****
Karsten Hopp 031077
  		else
Karsten Hopp 031077
  		    col = (int)(t->subs.norm.list.line[0].start - regline);
Karsten Hopp 031077
  		nfa_set_code(t->state->c);
Karsten Hopp 031077
! 		fprintf(log_fd, "(%d) char %d %s (start col %d) ... \n",
Karsten Hopp 031077
! 			abs(t->state->id), (int)t->state->c, code, col);
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  
Karsten Hopp 031077
--- 5002,5010 ----
Karsten Hopp 031077
  		else
Karsten Hopp 031077
  		    col = (int)(t->subs.norm.list.line[0].start - regline);
Karsten Hopp 031077
  		nfa_set_code(t->state->c);
Karsten Hopp 031077
! 		fprintf(log_fd, "(%d) char %d %s (start col %d)%s ... \n",
Karsten Hopp 031077
! 			abs(t->state->id), (int)t->state->c, code, col,
Karsten Hopp 031077
! 			pim_info(&t->pim));
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 5028,5048 ****
Karsten Hopp 031077
  	    case NFA_START_INVISIBLE_BEFORE:
Karsten Hopp 031077
  	    case NFA_START_INVISIBLE_BEFORE_NEG:
Karsten Hopp 031077
  		{
Karsten Hopp 031077
- 		    nfa_pim_T *pim;
Karsten Hopp 031077
  		    int cout = t->state->out1->out->c;
Karsten Hopp 031077
  
Karsten Hopp 031077
  		    /* Do it directly when what follows is possibly end of
Karsten Hopp 031077
  		     * match (closing paren).
Karsten Hopp 031077
  		     * Postpone when it is \@<= or \@
Karsten Hopp 031077
- 		     * TODO: remove the check for t->pim and check multiple
Karsten Hopp 031077
- 		     * where it's used?
Karsten Hopp 031077
  		     * Otherwise first do the one that has the highest chance
Karsten Hopp 031077
  		     * of failing. */
Karsten Hopp 031077
  		    if ((cout >= NFA_MCLOSE && cout <= NFA_MCLOSE9)
Karsten Hopp 031077
  #ifdef FEAT_SYN_HL
Karsten Hopp 031077
  			    || (cout >= NFA_ZCLOSE && cout <= NFA_ZCLOSE9)
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
! 			    || t->pim != NULL
Karsten Hopp 031077
  			    || (t->state->c != NFA_START_INVISIBLE_BEFORE
Karsten Hopp 031077
  			        && t->state->c != NFA_START_INVISIBLE_BEFORE_NEG
Karsten Hopp 031077
  				&& failure_chance(t->state->out1->out, 0)
Karsten Hopp 031077
--- 5096,5114 ----
Karsten Hopp 031077
  	    case NFA_START_INVISIBLE_BEFORE:
Karsten Hopp 031077
  	    case NFA_START_INVISIBLE_BEFORE_NEG:
Karsten Hopp 031077
  		{
Karsten Hopp 031077
  		    int cout = t->state->out1->out->c;
Karsten Hopp 031077
  
Karsten Hopp 031077
  		    /* Do it directly when what follows is possibly end of
Karsten Hopp 031077
  		     * match (closing paren).
Karsten Hopp 031077
+ 		     * Do it directly if there already is a PIM.
Karsten Hopp 031077
  		     * Postpone when it is \@<= or \@
Karsten Hopp 031077
  		     * Otherwise first do the one that has the highest chance
Karsten Hopp 031077
  		     * of failing. */
Karsten Hopp 031077
  		    if ((cout >= NFA_MCLOSE && cout <= NFA_MCLOSE9)
Karsten Hopp 031077
  #ifdef FEAT_SYN_HL
Karsten Hopp 031077
  			    || (cout >= NFA_ZCLOSE && cout <= NFA_ZCLOSE9)
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
! 			    || t->pim.result != NFA_PIM_UNUSED
Karsten Hopp 031077
  			    || (t->state->c != NFA_START_INVISIBLE_BEFORE
Karsten Hopp 031077
  			        && t->state->c != NFA_START_INVISIBLE_BEFORE_NEG
Karsten Hopp 031077
  				&& failure_chance(t->state->out1->out, 0)
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 5052,5058 ****
Karsten Hopp 031077
  			 * First try matching the invisible match, then what
Karsten Hopp 031077
  			 * follows.
Karsten Hopp 031077
  			 */
Karsten Hopp 031077
! 			result = recursive_regmatch(t->state, prog,
Karsten Hopp 031077
  						       submatch, m, &listids);
Karsten Hopp 031077
  
Karsten Hopp 031077
  			/* for \@! and \@
Karsten Hopp 031077
--- 5118,5124 ----
Karsten Hopp 031077
  			 * First try matching the invisible match, then what
Karsten Hopp 031077
  			 * follows.
Karsten Hopp 031077
  			 */
Karsten Hopp 031077
! 			result = recursive_regmatch(t->state, NULL, prog,
Karsten Hopp 031077
  						       submatch, m, &listids);
Karsten Hopp 031077
  
Karsten Hopp 031077
  			/* for \@! and \@
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 5077,5102 ****
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  		    else
Karsten Hopp 031077
  		    {
Karsten Hopp 031077
  			/*
Karsten Hopp 031077
! 			 * First try matching what follows at the current
Karsten Hopp 031077
! 			 * position.  Only if a match is found, before
Karsten Hopp 031077
! 			 * addstate() is called, then verify the invisible
Karsten Hopp 031077
! 			 * match matches.  Add a nfa_pim_T to the following
Karsten Hopp 031077
! 			 * states, it contains info about the invisible match.
Karsten Hopp 031077
  			 */
Karsten Hopp 031077
! 			if (ga_grow(&pimlist, 1) == FAIL)
Karsten Hopp 031077
! 			    goto theend;
Karsten Hopp 031077
! 			pim = (nfa_pim_T *)pimlist.ga_data + pimlist.ga_len;
Karsten Hopp 031077
! 			++pimlist.ga_len;
Karsten Hopp 031077
! 			pim->state = t->state;
Karsten Hopp 031077
! 			pim->pim = NULL;
Karsten Hopp 031077
! 			pim->result = NFA_PIM_TODO;
Karsten Hopp 031077
  
Karsten Hopp 031077
  			/* t->state->out1 is the corresponding END_INVISIBLE
Karsten Hopp 031077
  			 * node; Add its out to the current list (zero-width
Karsten Hopp 031077
  			 * match). */
Karsten Hopp 031077
  			addstate_here(thislist, t->state->out1->out, &t->subs,
Karsten Hopp 031077
! 							       pim, &listidx);
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  		}
Karsten Hopp 031077
  		break;
Karsten Hopp 031077
--- 5143,5175 ----
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  		    else
Karsten Hopp 031077
  		    {
Karsten Hopp 031077
+ 			nfa_pim_T pim;
Karsten Hopp 031077
+ 
Karsten Hopp 031077
  			/*
Karsten Hopp 031077
! 			 * First try matching what follows.  Only if a match
Karsten Hopp 031077
! 			 * is found verify the invisible match matches.  Add a
Karsten Hopp 031077
! 			 * nfa_pim_T to the following states, it contains info
Karsten Hopp 031077
! 			 * about the invisible match.
Karsten Hopp 031077
  			 */
Karsten Hopp 031077
! 			pim.state = t->state;
Karsten Hopp 031077
! 			pim.result = NFA_PIM_TODO;
Karsten Hopp 031077
! 			pim.subs.norm.in_use = 0;
Karsten Hopp 031077
! #ifdef FEAT_SYN_HL
Karsten Hopp 031077
! 			pim.subs.synt.in_use = 0;
Karsten Hopp 031077
! #endif
Karsten Hopp 031077
! 			if (REG_MULTI)
Karsten Hopp 031077
! 			{
Karsten Hopp 031077
! 			    pim.end.pos.col = (int)(reginput - regline);
Karsten Hopp 031077
! 			    pim.end.pos.lnum = reglnum;
Karsten Hopp 031077
! 			}
Karsten Hopp 031077
! 			else
Karsten Hopp 031077
! 			    pim.end.ptr = reginput;
Karsten Hopp 031077
  
Karsten Hopp 031077
  			/* t->state->out1 is the corresponding END_INVISIBLE
Karsten Hopp 031077
  			 * node; Add its out to the current list (zero-width
Karsten Hopp 031077
  			 * match). */
Karsten Hopp 031077
  			addstate_here(thislist, t->state->out1->out, &t->subs,
Karsten Hopp 031077
! 							       &pim, &listidx);
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  		}
Karsten Hopp 031077
  		break;
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 5144,5150 ****
Karsten Hopp 031077
  		}
Karsten Hopp 031077
  
Karsten Hopp 031077
  		/* First try matching the pattern. */
Karsten Hopp 031077
! 		result = recursive_regmatch(t->state, prog,
Karsten Hopp 031077
  						       submatch, m, &listids);
Karsten Hopp 031077
  		if (result)
Karsten Hopp 031077
  		{
Karsten Hopp 031077
--- 5217,5223 ----
Karsten Hopp 031077
  		}
Karsten Hopp 031077
  
Karsten Hopp 031077
  		/* First try matching the pattern. */
Karsten Hopp 031077
! 		result = recursive_regmatch(t->state, NULL, prog,
Karsten Hopp 031077
  						       submatch, m, &listids);
Karsten Hopp 031077
  		if (result)
Karsten Hopp 031077
  		{
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 5798,5809 ****
Karsten Hopp 031077
  
Karsten Hopp 031077
  	    if (add_state != NULL)
Karsten Hopp 031077
  	    {
Karsten Hopp 031077
! 		/* Handle the postponed invisible match before advancing to
Karsten Hopp 031077
! 		 * the next character and for a zero-width match if the match
Karsten Hopp 031077
! 		 * might end without advancing. */
Karsten Hopp 031077
! 		if (t->pim != NULL && (!add_here || match_follows(add_state, 0)))
Karsten Hopp 031077
  		{
Karsten Hopp 031077
! 		    if (t->pim->result == NFA_PIM_TODO)
Karsten Hopp 031077
  		    {
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
  			fprintf(log_fd, "\n");
Karsten Hopp 031077
--- 5871,5888 ----
Karsten Hopp 031077
  
Karsten Hopp 031077
  	    if (add_state != NULL)
Karsten Hopp 031077
  	    {
Karsten Hopp 031077
! 		nfa_pim_T *pim;
Karsten Hopp 031077
! 
Karsten Hopp 031077
! 		if (t->pim.result == NFA_PIM_UNUSED)
Karsten Hopp 031077
! 		    pim = NULL;
Karsten Hopp 031077
! 		else
Karsten Hopp 031077
! 		    pim = &t->pim;
Karsten Hopp 031077
! 
Karsten Hopp 031077
! 		/* Handle the postponed invisible match if the match might end
Karsten Hopp 031077
! 		 * without advancing and before the end of the line. */
Karsten Hopp 031077
! 		if (pim != NULL && (clen == 0 || match_follows(add_state, 0)))
Karsten Hopp 031077
  		{
Karsten Hopp 031077
! 		    if (pim->result == NFA_PIM_TODO)
Karsten Hopp 031077
  		    {
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
  			fprintf(log_fd, "\n");
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 5811,5868 ****
Karsten Hopp 031077
  			fprintf(log_fd, "Postponed recursive nfa_regmatch()\n");
Karsten Hopp 031077
  			fprintf(log_fd, "\n");
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
! 			result = recursive_regmatch(t->pim->state,
Karsten Hopp 031077
  						 prog, submatch, m, &listids);
Karsten Hopp 031077
! 			t->pim->result = result ? NFA_PIM_MATCH
Karsten Hopp 031077
! 							    : NFA_PIM_NOMATCH;
Karsten Hopp 031077
  			/* for \@! and \@
Karsten Hopp 031077
  			 * FALSE */
Karsten Hopp 031077
! 			if (result != (t->pim->state->c
Karsten Hopp 031077
! 						    == NFA_START_INVISIBLE_NEG
Karsten Hopp 031077
! 			            || t->pim->state->c
Karsten Hopp 031077
  					   == NFA_START_INVISIBLE_BEFORE_NEG))
Karsten Hopp 031077
  			{
Karsten Hopp 031077
  			    /* Copy submatch info from the recursive call */
Karsten Hopp 031077
! 			    copy_sub_off(&t->pim->subs.norm, &m->norm);
Karsten Hopp 031077
  #ifdef FEAT_SYN_HL
Karsten Hopp 031077
  			    if (nfa_has_zsubexpr)
Karsten Hopp 031077
! 				copy_sub_off(&t->pim->subs.synt, &m->synt);
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  			}
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  		    else
Karsten Hopp 031077
  		    {
Karsten Hopp 031077
! 			result = (t->pim->result == NFA_PIM_MATCH);
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
  			fprintf(log_fd, "\n");
Karsten Hopp 031077
! 			fprintf(log_fd, "Using previous recursive nfa_regmatch() result, result == %d\n", t->pim->result);
Karsten Hopp 031077
  			fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : "FALSE");
Karsten Hopp 031077
  			fprintf(log_fd, "\n");
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  
Karsten Hopp 031077
  		    /* for \@! and \@
Karsten Hopp 031077
! 		    if (result != (t->pim->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp 031077
! 			        || t->pim->state->c
Karsten Hopp 031077
  					   == NFA_START_INVISIBLE_BEFORE_NEG))
Karsten Hopp 031077
  		    {
Karsten Hopp 031077
  			/* Copy submatch info from the recursive call */
Karsten Hopp 031077
! 			copy_sub_off(&t->subs.norm, &t->pim->subs.norm);
Karsten Hopp 031077
  #ifdef FEAT_SYN_HL
Karsten Hopp 031077
  			if (nfa_has_zsubexpr)
Karsten Hopp 031077
! 			    copy_sub_off(&t->subs.synt, &t->pim->subs.synt);
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  		    else
Karsten Hopp 031077
  			/* look-behind match failed, don't add the state */
Karsten Hopp 031077
  			continue;
Karsten Hopp 031077
  		}
Karsten Hopp 031077
  
Karsten Hopp 031077
  		if (add_here)
Karsten Hopp 031077
! 		    addstate_here(thislist, add_state, &t->subs, t->pim, &listidx);
Karsten Hopp 031077
  		else
Karsten Hopp 031077
  		{
Karsten Hopp 031077
! 		    addstate(nextlist, add_state, &t->subs, add_off);
Karsten Hopp 031077
  		    if (add_count > 0)
Karsten Hopp 031077
  			nextlist->t[nextlist->n - 1].count = add_count;
Karsten Hopp 031077
  		}
Karsten Hopp 031077
--- 5890,5949 ----
Karsten Hopp 031077
  			fprintf(log_fd, "Postponed recursive nfa_regmatch()\n");
Karsten Hopp 031077
  			fprintf(log_fd, "\n");
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
! 			result = recursive_regmatch(pim->state, pim,
Karsten Hopp 031077
  						 prog, submatch, m, &listids);
Karsten Hopp 031077
! 			pim->result = result ? NFA_PIM_MATCH : NFA_PIM_NOMATCH;
Karsten Hopp 031077
  			/* for \@! and \@
Karsten Hopp 031077
  			 * FALSE */
Karsten Hopp 031077
! 			if (result != (pim->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp 031077
! 			            || pim->state->c
Karsten Hopp 031077
  					   == NFA_START_INVISIBLE_BEFORE_NEG))
Karsten Hopp 031077
  			{
Karsten Hopp 031077
  			    /* Copy submatch info from the recursive call */
Karsten Hopp 031077
! 			    copy_sub_off(&pim->subs.norm, &m->norm);
Karsten Hopp 031077
  #ifdef FEAT_SYN_HL
Karsten Hopp 031077
  			    if (nfa_has_zsubexpr)
Karsten Hopp 031077
! 				copy_sub_off(&pim->subs.synt, &m->synt);
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  			}
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  		    else
Karsten Hopp 031077
  		    {
Karsten Hopp 031077
! 			result = (pim->result == NFA_PIM_MATCH);
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
  			fprintf(log_fd, "\n");
Karsten Hopp 031077
! 			fprintf(log_fd, "Using previous recursive nfa_regmatch() result, result == %d\n", pim->result);
Karsten Hopp 031077
  			fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : "FALSE");
Karsten Hopp 031077
  			fprintf(log_fd, "\n");
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  
Karsten Hopp 031077
  		    /* for \@! and \@
Karsten Hopp 031077
! 		    if (result != (pim->state->c == NFA_START_INVISIBLE_NEG
Karsten Hopp 031077
! 			        || pim->state->c
Karsten Hopp 031077
  					   == NFA_START_INVISIBLE_BEFORE_NEG))
Karsten Hopp 031077
  		    {
Karsten Hopp 031077
  			/* Copy submatch info from the recursive call */
Karsten Hopp 031077
! 			copy_sub_off(&t->subs.norm, &pim->subs.norm);
Karsten Hopp 031077
  #ifdef FEAT_SYN_HL
Karsten Hopp 031077
  			if (nfa_has_zsubexpr)
Karsten Hopp 031077
! 			    copy_sub_off(&t->subs.synt, &pim->subs.synt);
Karsten Hopp 031077
  #endif
Karsten Hopp 031077
  		    }
Karsten Hopp 031077
  		    else
Karsten Hopp 031077
  			/* look-behind match failed, don't add the state */
Karsten Hopp 031077
  			continue;
Karsten Hopp 031077
+ 
Karsten Hopp 031077
+ 		    /* Postponed invisible match was handled, don't add it to
Karsten Hopp 031077
+ 		     * following states. */
Karsten Hopp 031077
+ 		    pim = NULL;
Karsten Hopp 031077
  		}
Karsten Hopp 031077
  
Karsten Hopp 031077
  		if (add_here)
Karsten Hopp 031077
! 		    addstate_here(thislist, add_state, &t->subs, pim, &listidx);
Karsten Hopp 031077
  		else
Karsten Hopp 031077
  		{
Karsten Hopp 031077
! 		    addstate(nextlist, add_state, &t->subs, pim, add_off);
Karsten Hopp 031077
  		    if (add_count > 0)
Karsten Hopp 031077
  			nextlist->t[nextlist->n - 1].count = add_count;
Karsten Hopp 031077
  		}
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 5941,5951 ****
Karsten Hopp 031077
  					 (colnr_T)(reginput - regline) + clen;
Karsten Hopp 031077
  		    else
Karsten Hopp 031077
  			m->norm.list.line[0].start = reginput + clen;
Karsten Hopp 031077
! 		    addstate(nextlist, start->out, m, clen);
Karsten Hopp 031077
  		}
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  	    else
Karsten Hopp 031077
! 		addstate(nextlist, start, m, clen);
Karsten Hopp 031077
  	}
Karsten Hopp 031077
  
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
--- 6022,6032 ----
Karsten Hopp 031077
  					 (colnr_T)(reginput - regline) + clen;
Karsten Hopp 031077
  		    else
Karsten Hopp 031077
  			m->norm.list.line[0].start = reginput + clen;
Karsten Hopp 031077
! 		    addstate(nextlist, start->out, m, NULL, clen);
Karsten Hopp 031077
  		}
Karsten Hopp 031077
  	    }
Karsten Hopp 031077
  	    else
Karsten Hopp 031077
! 		addstate(nextlist, start, m, NULL, clen);
Karsten Hopp 031077
  	}
Karsten Hopp 031077
  
Karsten Hopp 031077
  #ifdef ENABLE_LOG
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 5982,5988 ****
Karsten Hopp 031077
      vim_free(list[0].t);
Karsten Hopp 031077
      vim_free(list[1].t);
Karsten Hopp 031077
      vim_free(listids);
Karsten Hopp 031077
-     ga_clear(&pimlist);
Karsten Hopp 031077
  #undef ADD_STATE_IF_MATCH
Karsten Hopp 031077
  #ifdef NFA_REGEXP_DEBUG_LOG
Karsten Hopp 031077
      fclose(debug);
Karsten Hopp 031077
--- 6063,6068 ----
Karsten Hopp 031077
*** ../vim-7.3.1152/src/version.c	2013-06-08 23:30:00.000000000 +0200
Karsten Hopp 031077
--- src/version.c	2013-06-09 15:21:03.000000000 +0200
Karsten Hopp 031077
***************
Karsten Hopp 031077
*** 730,731 ****
Karsten Hopp 031077
--- 730,733 ----
Karsten Hopp 031077
  {   /* Add new patch number below this line */
Karsten Hopp 031077
+ /**/
Karsten Hopp 031077
+     1153,
Karsten Hopp 031077
  /**/
Karsten Hopp 031077
Karsten Hopp 031077
-- 
Karsten Hopp 031077
"Computers in the future may weigh no more than 1.5 tons."
Karsten Hopp 031077
                                   Popular Mechanics, 1949
Karsten Hopp 031077
Karsten Hopp 031077
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 031077
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 031077
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 031077
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///