Karsten Hopp 70ebfa
To: vim_dev@googlegroups.com
Karsten Hopp 70ebfa
Subject: Patch 7.3.1028
Karsten Hopp 70ebfa
Fcc: outbox
Karsten Hopp 70ebfa
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 70ebfa
Mime-Version: 1.0
Karsten Hopp 70ebfa
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 70ebfa
Content-Transfer-Encoding: 8bit
Karsten Hopp 70ebfa
------------
Karsten Hopp 70ebfa
Karsten Hopp 70ebfa
Patch 7.3.1028
Karsten Hopp 70ebfa
Problem:    New regexp performance: Copying a lot of position state.
Karsten Hopp 70ebfa
Solution:   Only copy the sub-expressions that are being used.
Karsten Hopp 70ebfa
Files:	    src/regexp_nfa.c, src/regexp.h
Karsten Hopp 70ebfa
Karsten Hopp 70ebfa
Karsten Hopp 70ebfa
*** ../vim-7.3.1027/src/regexp_nfa.c	2013-05-26 19:19:48.000000000 +0200
Karsten Hopp 70ebfa
--- src/regexp_nfa.c	2013-05-26 21:35:33.000000000 +0200
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 161,166 ****
Karsten Hopp 70ebfa
--- 161,170 ----
Karsten Hopp 70ebfa
  /* NFA regexp \ze operator encountered. */
Karsten Hopp 70ebfa
  static int nfa_has_zend = FALSE;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
+ /* Number of sub expressions actually being used during execution. 1 if only
Karsten Hopp 70ebfa
+  * the whole match (subexpr 0) is used. */
Karsten Hopp 70ebfa
+ static int nfa_nsubexpr;
Karsten Hopp 70ebfa
+ 
Karsten Hopp 70ebfa
  static int *post_start;  /* holds the postfix form of r.e. */
Karsten Hopp 70ebfa
  static int *post_end;
Karsten Hopp 70ebfa
  static int *post_ptr;
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 1645,1656 ****
Karsten Hopp 70ebfa
      return OK;
Karsten Hopp 70ebfa
  }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! typedef struct
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
!     char_u	*start[NSUBEXP];
Karsten Hopp 70ebfa
!     char_u	*end[NSUBEXP];
Karsten Hopp 70ebfa
!     lpos_T	startpos[NSUBEXP];
Karsten Hopp 70ebfa
!     lpos_T	endpos[NSUBEXP];
Karsten Hopp 70ebfa
  } regsub_T;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  static int nfa_regmatch __ARGS((nfa_state_T *start, regsub_T *submatch, regsub_T *m));
Karsten Hopp 70ebfa
--- 1649,1666 ----
Karsten Hopp 70ebfa
      return OK;
Karsten Hopp 70ebfa
  }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! typedef union
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
!     struct multipos
Karsten Hopp 70ebfa
!     {
Karsten Hopp 70ebfa
! 	lpos_T	start;
Karsten Hopp 70ebfa
! 	lpos_T	end;
Karsten Hopp 70ebfa
!     } multilist[NSUBEXP];
Karsten Hopp 70ebfa
!     struct linepos
Karsten Hopp 70ebfa
!     {
Karsten Hopp 70ebfa
! 	char_u	*start;
Karsten Hopp 70ebfa
! 	char_u	*end;
Karsten Hopp 70ebfa
!     } linelist[NSUBEXP];
Karsten Hopp 70ebfa
  } regsub_T;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  static int nfa_regmatch __ARGS((nfa_state_T *start, regsub_T *submatch, regsub_T *m));
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2479,2514 ****
Karsten Hopp 70ebfa
   * NFA execution code.
Karsten Hopp 70ebfa
   ****************************************************************/
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! /* nfa_thread_T contains runtime information of a NFA state */
Karsten Hopp 70ebfa
  typedef struct
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
      nfa_state_T	*state;
Karsten Hopp 70ebfa
!     regsub_T	sub;		/* Submatch info. TODO: expensive! */
Karsten Hopp 70ebfa
  } nfa_thread_T;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! 
Karsten Hopp 70ebfa
  typedef struct
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
      nfa_thread_T    *t;
Karsten Hopp 70ebfa
      int		    n;
Karsten Hopp 70ebfa
  } nfa_list_T;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *m, int off, int lid, int *match));
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *m, int lid, int *match, int *ip));
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      static void
Karsten Hopp 70ebfa
! addstate(l, state, m, off, lid, match)
Karsten Hopp 70ebfa
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp 70ebfa
      nfa_state_T		*state;	/* state to update */
Karsten Hopp 70ebfa
      regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp 70ebfa
      int			off;	/* byte offset, when -1 go to next line */
Karsten Hopp 70ebfa
      int			lid;
Karsten Hopp 70ebfa
-     int			*match;	/* found match? */
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
!     regsub_T		save;
Karsten Hopp 70ebfa
!     int			subidx = 0;
Karsten Hopp 70ebfa
      nfa_thread_T	*lastthread;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      if (l == NULL || state == NULL)
Karsten Hopp 70ebfa
  	return;
Karsten Hopp 70ebfa
--- 2489,2527 ----
Karsten Hopp 70ebfa
   * NFA execution code.
Karsten Hopp 70ebfa
   ****************************************************************/
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! /* nfa_thread_T contains execution information of a NFA state */
Karsten Hopp 70ebfa
  typedef struct
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
      nfa_state_T	*state;
Karsten Hopp 70ebfa
!     regsub_T	sub;		/* submatch info, only party used */
Karsten Hopp 70ebfa
  } nfa_thread_T;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! /* nfa_list_T contains the alternative NFA execution states. */
Karsten Hopp 70ebfa
  typedef struct
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
      nfa_thread_T    *t;
Karsten Hopp 70ebfa
      int		    n;
Karsten Hopp 70ebfa
  } nfa_list_T;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! /* Used during execution: whether a match has been found. */
Karsten Hopp 70ebfa
! static int nfa_match;
Karsten Hopp 70ebfa
! 
Karsten Hopp 70ebfa
! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *m, int off, int lid));
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *m, int lid, int *ip));
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      static void
Karsten Hopp 70ebfa
! addstate(l, state, m, off, lid)
Karsten Hopp 70ebfa
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp 70ebfa
      nfa_state_T		*state;	/* state to update */
Karsten Hopp 70ebfa
      regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp 70ebfa
      int			off;	/* byte offset, when -1 go to next line */
Karsten Hopp 70ebfa
      int			lid;
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
!     int			subidx;
Karsten Hopp 70ebfa
      nfa_thread_T	*lastthread;
Karsten Hopp 70ebfa
+     lpos_T		save_lpos;
Karsten Hopp 70ebfa
+     char_u		*save_ptr;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      if (l == NULL || state == NULL)
Karsten Hopp 70ebfa
  	return;
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2544,2550 ****
Karsten Hopp 70ebfa
  		state->lastlist = lid;
Karsten Hopp 70ebfa
  		lastthread = &l->t[l->n++];
Karsten Hopp 70ebfa
  		lastthread->state = state;
Karsten Hopp 70ebfa
! 		lastthread->sub = *m; /* TODO: expensive! */
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
--- 2557,2572 ----
Karsten Hopp 70ebfa
  		state->lastlist = lid;
Karsten Hopp 70ebfa
  		lastthread = &l->t[l->n++];
Karsten Hopp 70ebfa
  		lastthread->state = state;
Karsten Hopp 70ebfa
! 
Karsten Hopp 70ebfa
! 		/* Copy the match start and end positions. */
Karsten Hopp 70ebfa
! 		if (REG_MULTI)
Karsten Hopp 70ebfa
! 		    mch_memmove(&lastthread->sub.multilist[0],
Karsten Hopp 70ebfa
! 			        &m->multilist[0],
Karsten Hopp 70ebfa
! 				sizeof(struct multipos) * nfa_nsubexpr);
Karsten Hopp 70ebfa
! 		else
Karsten Hopp 70ebfa
! 		    mch_memmove(&lastthread->sub.linelist[0],
Karsten Hopp 70ebfa
! 			        &m->linelist[0],
Karsten Hopp 70ebfa
! 			        sizeof(struct linepos) * nfa_nsubexpr);
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2556,2571 ****
Karsten Hopp 70ebfa
      switch (state->c)
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
  	case NFA_MATCH:
Karsten Hopp 70ebfa
! 	    *match = TRUE;
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	case NFA_SPLIT:
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid, match);
Karsten Hopp 70ebfa
! 	    addstate(l, state->out1, m, off, lid, match);
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	case NFA_SKIP_CHAR:
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid, match);
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  #if 0
Karsten Hopp 70ebfa
--- 2578,2593 ----
Karsten Hopp 70ebfa
      switch (state->c)
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
  	case NFA_MATCH:
Karsten Hopp 70ebfa
! 	    nfa_match = TRUE;
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	case NFA_SPLIT:
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp 70ebfa
! 	    addstate(l, state->out1, m, off, lid);
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	case NFA_SKIP_CHAR:
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  #if 0
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2587,2593 ****
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	case NFA_NOPEN:
Karsten Hopp 70ebfa
  	case NFA_NCLOSE:
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid, match);
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	/* If this state is reached, then a recursive call of nfa_regmatch()
Karsten Hopp 70ebfa
--- 2609,2615 ----
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	case NFA_NOPEN:
Karsten Hopp 70ebfa
  	case NFA_NCLOSE:
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	/* If this state is reached, then a recursive call of nfa_regmatch()
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2609,2659 ****
Karsten Hopp 70ebfa
  	case NFA_MOPEN + 8:
Karsten Hopp 70ebfa
  	case NFA_MOPEN + 9:
Karsten Hopp 70ebfa
  	case NFA_ZSTART:
Karsten Hopp 70ebfa
- 	    subidx = state->c - NFA_MOPEN;
Karsten Hopp 70ebfa
  	    if (state->c == NFA_ZSTART)
Karsten Hopp 70ebfa
  		subidx = 0;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    if (REG_MULTI)
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		save.startpos[subidx] = m->startpos[subidx];
Karsten Hopp 70ebfa
! 		save.endpos[subidx] = m->endpos[subidx];
Karsten Hopp 70ebfa
  		if (off == -1)
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
! 		    m->startpos[subidx].lnum = reglnum + 1;
Karsten Hopp 70ebfa
! 		    m->startpos[subidx].col = 0;
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		else
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
! 		    m->startpos[subidx].lnum = reglnum;
Karsten Hopp 70ebfa
! 		    m->startpos[subidx].col =
Karsten Hopp 70ebfa
  					  (colnr_T)(reginput - regline + off);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  	    else
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		save.start[subidx] = m->start[subidx];
Karsten Hopp 70ebfa
! 		save.end[subidx] = m->end[subidx];
Karsten Hopp 70ebfa
! 		m->start[subidx] = reginput + off;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid, match);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    if (REG_MULTI)
Karsten Hopp 70ebfa
! 	    {
Karsten Hopp 70ebfa
! 		m->startpos[subidx] = save.startpos[subidx];
Karsten Hopp 70ebfa
! 		m->endpos[subidx] = save.endpos[subidx];
Karsten Hopp 70ebfa
! 	    }
Karsten Hopp 70ebfa
  	    else
Karsten Hopp 70ebfa
! 	    {
Karsten Hopp 70ebfa
! 		m->start[subidx] = save.start[subidx];
Karsten Hopp 70ebfa
! 		m->end[subidx] = save.end[subidx];
Karsten Hopp 70ebfa
! 	    }
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	case NFA_MCLOSE + 0:
Karsten Hopp 70ebfa
  	    if (nfa_has_zend)
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		addstate(l, state->out, m, off, lid, match);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  	case NFA_MCLOSE + 1:
Karsten Hopp 70ebfa
--- 2631,2674 ----
Karsten Hopp 70ebfa
  	case NFA_MOPEN + 8:
Karsten Hopp 70ebfa
  	case NFA_MOPEN + 9:
Karsten Hopp 70ebfa
  	case NFA_ZSTART:
Karsten Hopp 70ebfa
  	    if (state->c == NFA_ZSTART)
Karsten Hopp 70ebfa
  		subidx = 0;
Karsten Hopp 70ebfa
+ 	    else
Karsten Hopp 70ebfa
+ 		subidx = state->c - NFA_MOPEN;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    if (REG_MULTI)
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		save_lpos = m->multilist[subidx].start;
Karsten Hopp 70ebfa
  		if (off == -1)
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
! 		    m->multilist[subidx].start.lnum = reglnum + 1;
Karsten Hopp 70ebfa
! 		    m->multilist[subidx].start.col = 0;
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		else
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
! 		    m->multilist[subidx].start.lnum = reglnum;
Karsten Hopp 70ebfa
! 		    m->multilist[subidx].start.col =
Karsten Hopp 70ebfa
  					  (colnr_T)(reginput - regline + off);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  	    else
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		save_ptr = m->linelist[subidx].start;
Karsten Hopp 70ebfa
! 		m->linelist[subidx].start = reginput + off;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    if (REG_MULTI)
Karsten Hopp 70ebfa
! 		m->multilist[subidx].start = save_lpos;
Karsten Hopp 70ebfa
  	    else
Karsten Hopp 70ebfa
! 		m->linelist[subidx].start = save_ptr;
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	case NFA_MCLOSE + 0:
Karsten Hopp 70ebfa
  	    if (nfa_has_zend)
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		addstate(l, state->out, m, off, lid);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  	case NFA_MCLOSE + 1:
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2666,2709 ****
Karsten Hopp 70ebfa
  	case NFA_MCLOSE + 8:
Karsten Hopp 70ebfa
  	case NFA_MCLOSE + 9:
Karsten Hopp 70ebfa
  	case NFA_ZEND:
Karsten Hopp 70ebfa
- 	    subidx = state->c - NFA_MCLOSE;
Karsten Hopp 70ebfa
  	    if (state->c == NFA_ZEND)
Karsten Hopp 70ebfa
  		subidx = 0;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    if (REG_MULTI)
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		save.startpos[subidx] = m->startpos[subidx];
Karsten Hopp 70ebfa
! 		save.endpos[subidx] = m->endpos[subidx];
Karsten Hopp 70ebfa
  		if (off == -1)
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
! 		    m->endpos[subidx].lnum = reglnum + 1;
Karsten Hopp 70ebfa
! 		    m->endpos[subidx].col = 0;
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		else
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
! 		    m->endpos[subidx].lnum = reglnum;
Karsten Hopp 70ebfa
! 		    m->endpos[subidx].col = (colnr_T)(reginput - regline + off);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  	    else
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		save.start[subidx] = m->start[subidx];
Karsten Hopp 70ebfa
! 		save.end[subidx] = m->end[subidx];
Karsten Hopp 70ebfa
! 		m->end[subidx] = reginput + off;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid, match);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    if (REG_MULTI)
Karsten Hopp 70ebfa
! 	    {
Karsten Hopp 70ebfa
! 		m->startpos[subidx] = save.startpos[subidx];
Karsten Hopp 70ebfa
! 		m->endpos[subidx] = save.endpos[subidx];
Karsten Hopp 70ebfa
! 	    }
Karsten Hopp 70ebfa
  	    else
Karsten Hopp 70ebfa
! 	    {
Karsten Hopp 70ebfa
! 		m->start[subidx] = save.start[subidx];
Karsten Hopp 70ebfa
! 		m->end[subidx] = save.end[subidx];
Karsten Hopp 70ebfa
! 	    }
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
  }
Karsten Hopp 70ebfa
--- 2681,2718 ----
Karsten Hopp 70ebfa
  	case NFA_MCLOSE + 8:
Karsten Hopp 70ebfa
  	case NFA_MCLOSE + 9:
Karsten Hopp 70ebfa
  	case NFA_ZEND:
Karsten Hopp 70ebfa
  	    if (state->c == NFA_ZEND)
Karsten Hopp 70ebfa
  		subidx = 0;
Karsten Hopp 70ebfa
+ 	    else
Karsten Hopp 70ebfa
+ 		subidx = state->c - NFA_MCLOSE;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    if (REG_MULTI)
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		save_lpos = m->multilist[subidx].end;
Karsten Hopp 70ebfa
  		if (off == -1)
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
! 		    m->multilist[subidx].end.lnum = reglnum + 1;
Karsten Hopp 70ebfa
! 		    m->multilist[subidx].end.col = 0;
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		else
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
! 		    m->multilist[subidx].end.lnum = reglnum;
Karsten Hopp 70ebfa
! 		    m->multilist[subidx].end.col =
Karsten Hopp 70ebfa
! 					  (colnr_T)(reginput - regline + off);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  	    else
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
! 		save_ptr = m->linelist[subidx].end;
Karsten Hopp 70ebfa
! 		m->linelist[subidx].end = reginput + off;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
! 	    addstate(l, state->out, m, off, lid);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    if (REG_MULTI)
Karsten Hopp 70ebfa
! 		m->multilist[subidx].end = save_lpos;
Karsten Hopp 70ebfa
  	    else
Karsten Hopp 70ebfa
! 		m->linelist[subidx].end = save_ptr;
Karsten Hopp 70ebfa
  	    break;
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
  }
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2715,2726 ****
Karsten Hopp 70ebfa
   * matters for alternatives.
Karsten Hopp 70ebfa
   */
Karsten Hopp 70ebfa
      static void
Karsten Hopp 70ebfa
! addstate_here(l, state, m, lid, matchp, ip)
Karsten Hopp 70ebfa
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp 70ebfa
      nfa_state_T		*state;	/* state to update */
Karsten Hopp 70ebfa
      regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp 70ebfa
      int			lid;
Karsten Hopp 70ebfa
-     int			*matchp;	/* found match? */
Karsten Hopp 70ebfa
      int			*ip;
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
      int tlen = l->n;
Karsten Hopp 70ebfa
--- 2724,2734 ----
Karsten Hopp 70ebfa
   * matters for alternatives.
Karsten Hopp 70ebfa
   */
Karsten Hopp 70ebfa
      static void
Karsten Hopp 70ebfa
! addstate_here(l, state, m, lid, ip)
Karsten Hopp 70ebfa
      nfa_list_T		*l;	/* runtime state list */
Karsten Hopp 70ebfa
      nfa_state_T		*state;	/* state to update */
Karsten Hopp 70ebfa
      regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp 70ebfa
      int			lid;
Karsten Hopp 70ebfa
      int			*ip;
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
      int tlen = l->n;
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2728,2734 ****
Karsten Hopp 70ebfa
      int i = *ip;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /* first add the state(s) at the end, so that we know how many there are */
Karsten Hopp 70ebfa
!     addstate(l, state, m, 0, lid, matchp);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /* when "*ip" was at the end of the list, nothing to do */
Karsten Hopp 70ebfa
      if (i + 1 == tlen)
Karsten Hopp 70ebfa
--- 2736,2742 ----
Karsten Hopp 70ebfa
      int i = *ip;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /* first add the state(s) at the end, so that we know how many there are */
Karsten Hopp 70ebfa
!     addstate(l, state, m, 0, lid);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /* when "*ip" was at the end of the list, nothing to do */
Karsten Hopp 70ebfa
      if (i + 1 == tlen)
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2925,2931 ****
Karsten Hopp 70ebfa
  {
Karsten Hopp 70ebfa
      int		result;
Karsten Hopp 70ebfa
      int		size = 0;
Karsten Hopp 70ebfa
-     int		match = FALSE;
Karsten Hopp 70ebfa
      int		flag = 0;
Karsten Hopp 70ebfa
      int		old_reglnum = -1;
Karsten Hopp 70ebfa
      int		go_to_nextline = FALSE;
Karsten Hopp 70ebfa
--- 2933,2938 ----
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2951,2956 ****
Karsten Hopp 70ebfa
--- 2958,2964 ----
Karsten Hopp 70ebfa
  	return FALSE;
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
  #endif
Karsten Hopp 70ebfa
+     nfa_match = FALSE;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /* Allocate memory for the lists of nodes */
Karsten Hopp 70ebfa
      size = (nstate + 1) * sizeof(nfa_thread_T);
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 2989,2995 ****
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
      fprintf(log_fd, "(---) STARTSTATE\n");
Karsten Hopp 70ebfa
  #endif
Karsten Hopp 70ebfa
!     addstate(thislist, start, m, 0, listid, &match);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /* There are two cases when the NFA advances: 1. input char matches the
Karsten Hopp 70ebfa
       * NFA node and 2. input char does not match the NFA node, but the next
Karsten Hopp 70ebfa
--- 2997,3003 ----
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
      fprintf(log_fd, "(---) STARTSTATE\n");
Karsten Hopp 70ebfa
  #endif
Karsten Hopp 70ebfa
!     addstate(thislist, start, m, 0, listid);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /* There are two cases when the NFA advances: 1. input char matches the
Karsten Hopp 70ebfa
       * NFA node and 2. input char does not match the NFA node, but the next
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3002,3008 ****
Karsten Hopp 70ebfa
  #define	ADD_POS_NEG_STATE(node)						    \
Karsten Hopp 70ebfa
      ll = listtbl[result ? 1 : 0][node->negated];			    \
Karsten Hopp 70ebfa
      if (ll != NULL)							    \
Karsten Hopp 70ebfa
! 	addstate(ll, node->out , &t->sub, clen, listid + 1, &match);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /*
Karsten Hopp 70ebfa
--- 3010,3016 ----
Karsten Hopp 70ebfa
  #define	ADD_POS_NEG_STATE(node)						    \
Karsten Hopp 70ebfa
      ll = listtbl[result ? 1 : 0][node->negated];			    \
Karsten Hopp 70ebfa
      if (ll != NULL)							    \
Karsten Hopp 70ebfa
! 	addstate(ll, node->out , &t->sub, clen, listid + 1);
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      /*
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3090,3096 ****
Karsten Hopp 70ebfa
  	    switch (t->state->c)
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
  	    case NFA_MATCH:
Karsten Hopp 70ebfa
! 		match = TRUE;
Karsten Hopp 70ebfa
  		*submatch = t->sub;
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
  		for (j = 0; j < 4; j++)
Karsten Hopp 70ebfa
--- 3098,3104 ----
Karsten Hopp 70ebfa
  	    switch (t->state->c)
Karsten Hopp 70ebfa
  	    {
Karsten Hopp 70ebfa
  	    case NFA_MATCH:
Karsten Hopp 70ebfa
! 		nfa_match = TRUE;
Karsten Hopp 70ebfa
  		*submatch = t->sub;
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
  		for (j = 0; j < 4; j++)
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3125,3135 ****
Karsten Hopp 70ebfa
  		 * the parent call. */
Karsten Hopp 70ebfa
  		if (start->c == NFA_MOPEN + 0)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 							    &match, &listidx);
Karsten Hopp 70ebfa
  		else
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
  		    *m = t->sub;
Karsten Hopp 70ebfa
! 		    match = TRUE;
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
--- 3133,3143 ----
Karsten Hopp 70ebfa
  		 * the parent call. */
Karsten Hopp 70ebfa
  		if (start->c == NFA_MOPEN + 0)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 								    &listidx);
Karsten Hopp 70ebfa
  		else
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
  		    *m = t->sub;
Karsten Hopp 70ebfa
! 		    nfa_match = TRUE;
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3186,3205 ****
Karsten Hopp 70ebfa
  		    reglnum = old_reglnum;
Karsten Hopp 70ebfa
  		    /* Copy submatch info from the recursive call */
Karsten Hopp 70ebfa
  		    if (REG_MULTI)
Karsten Hopp 70ebfa
! 			for (j = 1; j < NSUBEXP; j++)
Karsten Hopp 70ebfa
  			{
Karsten Hopp 70ebfa
! 			    t->sub.startpos[j] = m->startpos[j];
Karsten Hopp 70ebfa
! 			    t->sub.endpos[j] = m->endpos[j];
Karsten Hopp 70ebfa
  			}
Karsten Hopp 70ebfa
  		    else
Karsten Hopp 70ebfa
! 			for (j = 1; j < NSUBEXP; j++)
Karsten Hopp 70ebfa
  			{
Karsten Hopp 70ebfa
! 			    t->sub.start[j] = m->start[j];
Karsten Hopp 70ebfa
! 			    t->sub.end[j] = m->end[j];
Karsten Hopp 70ebfa
  			}
Karsten Hopp 70ebfa
  		    /* t->state->out1 is the corresponding END_INVISIBLE node */
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out1->out, &t->sub,
Karsten Hopp 70ebfa
! 						    listid, &match, &listidx);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		else
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
--- 3194,3213 ----
Karsten Hopp 70ebfa
  		    reglnum = old_reglnum;
Karsten Hopp 70ebfa
  		    /* Copy submatch info from the recursive call */
Karsten Hopp 70ebfa
  		    if (REG_MULTI)
Karsten Hopp 70ebfa
! 			for (j = 1; j < nfa_nsubexpr; j++)
Karsten Hopp 70ebfa
  			{
Karsten Hopp 70ebfa
! 			    t->sub.multilist[j].start = m->multilist[j].start;
Karsten Hopp 70ebfa
! 			    t->sub.multilist[j].end = m->multilist[j].end;
Karsten Hopp 70ebfa
  			}
Karsten Hopp 70ebfa
  		    else
Karsten Hopp 70ebfa
! 			for (j = 1; j < nfa_nsubexpr; j++)
Karsten Hopp 70ebfa
  			{
Karsten Hopp 70ebfa
! 			    t->sub.linelist[j].start = m->linelist[j].start;
Karsten Hopp 70ebfa
! 			    t->sub.linelist[j].end = m->linelist[j].end;
Karsten Hopp 70ebfa
  			}
Karsten Hopp 70ebfa
  		    /* t->state->out1 is the corresponding END_INVISIBLE node */
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out1->out, &t->sub,
Karsten Hopp 70ebfa
! 							    listid, &listidx);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		else
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3211,3223 ****
Karsten Hopp 70ebfa
  	    case NFA_BOL:
Karsten Hopp 70ebfa
  		if (reginput == regline)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 							    &match, &listidx);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    case NFA_EOL:
Karsten Hopp 70ebfa
  		if (curc == NUL)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 							    &match, &listidx);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    case NFA_BOW:
Karsten Hopp 70ebfa
--- 3219,3231 ----
Karsten Hopp 70ebfa
  	    case NFA_BOL:
Karsten Hopp 70ebfa
  		if (reginput == regline)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 								    &listidx);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    case NFA_EOL:
Karsten Hopp 70ebfa
  		if (curc == NUL)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 								    &listidx);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    case NFA_BOW:
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3245,3251 ****
Karsten Hopp 70ebfa
  		    bow = FALSE;
Karsten Hopp 70ebfa
  		if (bow)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 							    &match, &listidx);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
--- 3253,3259 ----
Karsten Hopp 70ebfa
  		    bow = FALSE;
Karsten Hopp 70ebfa
  		if (bow)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 								    &listidx);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3274,3280 ****
Karsten Hopp 70ebfa
  		    eow = FALSE;
Karsten Hopp 70ebfa
  		if (eow)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 							    &match, &listidx);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
--- 3282,3288 ----
Karsten Hopp 70ebfa
  		    eow = FALSE;
Karsten Hopp 70ebfa
  		if (eow)
Karsten Hopp 70ebfa
  		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp 70ebfa
! 								    &listidx);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  	    }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3364,3377 ****
Karsten Hopp 70ebfa
  		    go_to_nextline = TRUE;
Karsten Hopp 70ebfa
  		    /* Pass -1 for the offset, which means taking the position
Karsten Hopp 70ebfa
  		     * at the start of the next line. */
Karsten Hopp 70ebfa
! 		    addstate(nextlist, t->state->out, &t->sub, -1,
Karsten Hopp 70ebfa
! 							  listid + 1, &match);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		else if (curc == '\n' && reg_line_lbr)
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
  		    /* match \n as if it is an ordinary character */
Karsten Hopp 70ebfa
! 		    addstate(nextlist, t->state->out, &t->sub, 1,
Karsten Hopp 70ebfa
! 							  listid + 1, &match);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
--- 3372,3383 ----
Karsten Hopp 70ebfa
  		    go_to_nextline = TRUE;
Karsten Hopp 70ebfa
  		    /* Pass -1 for the offset, which means taking the position
Karsten Hopp 70ebfa
  		     * at the start of the next line. */
Karsten Hopp 70ebfa
! 		    addstate(nextlist, t->state->out, &t->sub, -1, listid + 1);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		else if (curc == '\n' && reg_line_lbr)
Karsten Hopp 70ebfa
  		{
Karsten Hopp 70ebfa
  		    /* match \n as if it is an ordinary character */
Karsten Hopp 70ebfa
! 		    addstate(nextlist, t->state->out, &t->sub, 1, listid + 1);
Karsten Hopp 70ebfa
  		}
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3400,3413 ****
Karsten Hopp 70ebfa
  		 * CHAR(x), NFA_NOT, CHAR(y), NFA_NOT etc. */
Karsten Hopp 70ebfa
  		if (curc > 0)
Karsten Hopp 70ebfa
  		    addstate(nextlist, t->state->out, &t->sub, clen,
Karsten Hopp 70ebfa
! 							  listid + 1, &match);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    case NFA_ANY:
Karsten Hopp 70ebfa
  		/* Any char except '\0', (end of input) does not match. */
Karsten Hopp 70ebfa
  		if (curc > 0)
Karsten Hopp 70ebfa
  		    addstate(nextlist, t->state->out, &t->sub, clen,
Karsten Hopp 70ebfa
! 							  listid + 1, &match);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    /*
Karsten Hopp 70ebfa
--- 3406,3419 ----
Karsten Hopp 70ebfa
  		 * CHAR(x), NFA_NOT, CHAR(y), NFA_NOT etc. */
Karsten Hopp 70ebfa
  		if (curc > 0)
Karsten Hopp 70ebfa
  		    addstate(nextlist, t->state->out, &t->sub, clen,
Karsten Hopp 70ebfa
! 								  listid + 1);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    case NFA_ANY:
Karsten Hopp 70ebfa
  		/* Any char except '\0', (end of input) does not match. */
Karsten Hopp 70ebfa
  		if (curc > 0)
Karsten Hopp 70ebfa
  		    addstate(nextlist, t->state->out, &t->sub, clen,
Karsten Hopp 70ebfa
! 								  listid + 1);
Karsten Hopp 70ebfa
  		break;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	    /*
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3597,3609 ****
Karsten Hopp 70ebfa
  	 * Do not add the start state in recursive calls of nfa_regmatch(),
Karsten Hopp 70ebfa
  	 * because recursive calls should only start in the first position.
Karsten Hopp 70ebfa
  	 * Also don't start a match past the first line. */
Karsten Hopp 70ebfa
! 	if (match == FALSE && start->c == NFA_MOPEN + 0
Karsten Hopp 70ebfa
  						 && reglnum == 0 && clen != 0)
Karsten Hopp 70ebfa
  	{
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
  	    fprintf(log_fd, "(---) STARTSTATE\n");
Karsten Hopp 70ebfa
  #endif
Karsten Hopp 70ebfa
! 	    addstate(nextlist, start, m, clen, listid + 1, &match);
Karsten Hopp 70ebfa
  	}
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
--- 3603,3615 ----
Karsten Hopp 70ebfa
  	 * Do not add the start state in recursive calls of nfa_regmatch(),
Karsten Hopp 70ebfa
  	 * because recursive calls should only start in the first position.
Karsten Hopp 70ebfa
  	 * Also don't start a match past the first line. */
Karsten Hopp 70ebfa
! 	if (nfa_match == FALSE && start->c == NFA_MOPEN + 0
Karsten Hopp 70ebfa
  						 && reglnum == 0 && clen != 0)
Karsten Hopp 70ebfa
  	{
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
  	    fprintf(log_fd, "(---) STARTSTATE\n");
Karsten Hopp 70ebfa
  #endif
Karsten Hopp 70ebfa
! 	    addstate(nextlist, start, m, clen, listid + 1);
Karsten Hopp 70ebfa
  	}
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3640,3653 ****
Karsten Hopp 70ebfa
      vim_free(list[1].t);
Karsten Hopp 70ebfa
      vim_free(list[2].t);
Karsten Hopp 70ebfa
      list[0].t = list[1].t = list[2].t = NULL;
Karsten Hopp 70ebfa
!     if (listids != NULL)
Karsten Hopp 70ebfa
! 	vim_free(listids);
Karsten Hopp 70ebfa
  #undef ADD_POS_NEG_STATE
Karsten Hopp 70ebfa
  #ifdef NFA_REGEXP_DEBUG_LOG
Karsten Hopp 70ebfa
      fclose(debug);
Karsten Hopp 70ebfa
  #endif
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
!     return match;
Karsten Hopp 70ebfa
  }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  /*
Karsten Hopp 70ebfa
--- 3646,3658 ----
Karsten Hopp 70ebfa
      vim_free(list[1].t);
Karsten Hopp 70ebfa
      vim_free(list[2].t);
Karsten Hopp 70ebfa
      list[0].t = list[1].t = list[2].t = NULL;
Karsten Hopp 70ebfa
!     vim_free(listids);
Karsten Hopp 70ebfa
  #undef ADD_POS_NEG_STATE
Karsten Hopp 70ebfa
  #ifdef NFA_REGEXP_DEBUG_LOG
Karsten Hopp 70ebfa
      fclose(debug);
Karsten Hopp 70ebfa
  #endif
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
!     return nfa_match;
Karsten Hopp 70ebfa
  }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  /*
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3690,3706 ****
Karsten Hopp 70ebfa
      if (REG_MULTI)
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
  	/* Use 0xff to set lnum to -1 */
Karsten Hopp 70ebfa
! 	vim_memset(sub.startpos, 0xff, sizeof(lpos_T) * NSUBEXP);
Karsten Hopp 70ebfa
! 	vim_memset(sub.endpos, 0xff, sizeof(lpos_T) * NSUBEXP);
Karsten Hopp 70ebfa
! 	vim_memset(m.startpos, 0xff, sizeof(lpos_T) * NSUBEXP);
Karsten Hopp 70ebfa
! 	vim_memset(m.endpos, 0xff, sizeof(lpos_T) * NSUBEXP);
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
      else
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
! 	vim_memset(sub.start, 0, sizeof(char_u *) * NSUBEXP);
Karsten Hopp 70ebfa
! 	vim_memset(sub.end, 0, sizeof(char_u *) * NSUBEXP);
Karsten Hopp 70ebfa
! 	vim_memset(m.start, 0, sizeof(char_u *) * NSUBEXP);
Karsten Hopp 70ebfa
! 	vim_memset(m.end, 0, sizeof(char_u *) * NSUBEXP);
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      if (nfa_regmatch(start, &sub, &m) == FALSE)
Karsten Hopp 70ebfa
--- 3695,3707 ----
Karsten Hopp 70ebfa
      if (REG_MULTI)
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
  	/* Use 0xff to set lnum to -1 */
Karsten Hopp 70ebfa
! 	vim_memset(sub.multilist, 0xff, sizeof(struct multipos) * nfa_nsubexpr);
Karsten Hopp 70ebfa
! 	vim_memset(m.multilist, 0xff, sizeof(struct multipos) * nfa_nsubexpr);
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
      else
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
! 	vim_memset(sub.linelist, 0, sizeof(struct linepos) * nfa_nsubexpr);
Karsten Hopp 70ebfa
! 	vim_memset(m.linelist, 0, sizeof(struct linepos) * nfa_nsubexpr);
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      if (nfa_regmatch(start, &sub, &m) == FALSE)
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3709,3718 ****
Karsten Hopp 70ebfa
      cleanup_subexpr();
Karsten Hopp 70ebfa
      if (REG_MULTI)
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
! 	for (i = 0; i < NSUBEXP; i++)
Karsten Hopp 70ebfa
  	{
Karsten Hopp 70ebfa
! 	    reg_startpos[i] = sub.startpos[i];
Karsten Hopp 70ebfa
! 	    reg_endpos[i] = sub.endpos[i];
Karsten Hopp 70ebfa
  	}
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	if (reg_startpos[0].lnum < 0)
Karsten Hopp 70ebfa
--- 3710,3719 ----
Karsten Hopp 70ebfa
      cleanup_subexpr();
Karsten Hopp 70ebfa
      if (REG_MULTI)
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
! 	for (i = 0; i < nfa_nsubexpr; i++)
Karsten Hopp 70ebfa
  	{
Karsten Hopp 70ebfa
! 	    reg_startpos[i] = sub.multilist[i].start;
Karsten Hopp 70ebfa
! 	    reg_endpos[i] = sub.multilist[i].end;
Karsten Hopp 70ebfa
  	}
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	if (reg_startpos[0].lnum < 0)
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3731,3740 ****
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
      else
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
! 	for (i = 0; i < NSUBEXP; i++)
Karsten Hopp 70ebfa
  	{
Karsten Hopp 70ebfa
! 	    reg_startp[i] = sub.start[i];
Karsten Hopp 70ebfa
! 	    reg_endp[i] = sub.end[i];
Karsten Hopp 70ebfa
  	}
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	if (reg_startp[0] == NULL)
Karsten Hopp 70ebfa
--- 3732,3741 ----
Karsten Hopp 70ebfa
      }
Karsten Hopp 70ebfa
      else
Karsten Hopp 70ebfa
      {
Karsten Hopp 70ebfa
! 	for (i = 0; i < nfa_nsubexpr; i++)
Karsten Hopp 70ebfa
  	{
Karsten Hopp 70ebfa
! 	    reg_startp[i] = sub.linelist[i].start;
Karsten Hopp 70ebfa
! 	    reg_endp[i] = sub.linelist[i].end;
Karsten Hopp 70ebfa
  	}
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
  	if (reg_startp[0] == NULL)
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3802,3807 ****
Karsten Hopp 70ebfa
--- 3803,3809 ----
Karsten Hopp 70ebfa
      reglnum = 0;    /* relative to line */
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      nfa_has_zend = prog->has_zend;
Karsten Hopp 70ebfa
+     nfa_nsubexpr = prog->nsubexp;
Karsten Hopp 70ebfa
  
Karsten Hopp 70ebfa
      nstate = prog->nstate;
Karsten Hopp 70ebfa
      for (i = 0; i < nstate; ++i)
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 3896,3901 ****
Karsten Hopp 70ebfa
--- 3898,3904 ----
Karsten Hopp 70ebfa
      prog->engine = &nfa_regengine;
Karsten Hopp 70ebfa
      prog->nstate = nstate;
Karsten Hopp 70ebfa
      prog->has_zend = nfa_has_zend;
Karsten Hopp 70ebfa
+     prog->nsubexp = regnpar;
Karsten Hopp 70ebfa
  #ifdef ENABLE_LOG
Karsten Hopp 70ebfa
      nfa_postfix_dump(expr, OK);
Karsten Hopp 70ebfa
      nfa_dump(prog);
Karsten Hopp 70ebfa
*** ../vim-7.3.1027/src/regexp.h	2013-05-26 16:57:23.000000000 +0200
Karsten Hopp 70ebfa
--- src/regexp.h	2013-05-26 20:08:09.000000000 +0200
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 87,92 ****
Karsten Hopp 70ebfa
--- 87,93 ----
Karsten Hopp 70ebfa
      regprog_T		regprog;
Karsten Hopp 70ebfa
      nfa_state_T		*start;
Karsten Hopp 70ebfa
      int			has_zend;	/* pattern contains \ze */
Karsten Hopp 70ebfa
+     int			nsubexp;	/* number of () */
Karsten Hopp 70ebfa
      int			nstate;
Karsten Hopp 70ebfa
      nfa_state_T		state[0];	/* actually longer.. */
Karsten Hopp 70ebfa
  } nfa_regprog_T;
Karsten Hopp 70ebfa
*** ../vim-7.3.1027/src/version.c	2013-05-26 19:19:48.000000000 +0200
Karsten Hopp 70ebfa
--- src/version.c	2013-05-26 21:44:20.000000000 +0200
Karsten Hopp 70ebfa
***************
Karsten Hopp 70ebfa
*** 730,731 ****
Karsten Hopp 70ebfa
--- 730,733 ----
Karsten Hopp 70ebfa
  {   /* Add new patch number below this line */
Karsten Hopp 70ebfa
+ /**/
Karsten Hopp 70ebfa
+     1028,
Karsten Hopp 70ebfa
  /**/
Karsten Hopp 70ebfa
Karsten Hopp 70ebfa
-- 
Karsten Hopp 70ebfa
Q:  What's a light-year?
Karsten Hopp 70ebfa
A:  One-third less calories than a regular year.
Karsten Hopp 70ebfa
Karsten Hopp 70ebfa
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 70ebfa
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 70ebfa
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 70ebfa
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///