Karsten Hopp ec2eb3
To: vim_dev@googlegroups.com
Karsten Hopp ec2eb3
Subject: Patch 7.3.1017
Karsten Hopp ec2eb3
Fcc: outbox
Karsten Hopp ec2eb3
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp ec2eb3
Mime-Version: 1.0
Karsten Hopp ec2eb3
Content-Type: text/plain; charset=UTF-8
Karsten Hopp ec2eb3
Content-Transfer-Encoding: 8bit
Karsten Hopp ec2eb3
------------
Karsten Hopp ec2eb3
Karsten Hopp ec2eb3
Patch 7.3.1017
Karsten Hopp ec2eb3
Problem:    Zero width match changes length of match.
Karsten Hopp ec2eb3
Solution:   For a zero width match put new states in the current position in
Karsten Hopp ec2eb3
	    the state list.
Karsten Hopp ec2eb3
Files:	    src/regexp_nfa.c, src/testdir/test64.in, src/testdir/test64.ok,
Karsten Hopp ec2eb3
	    src/regexp.h
Karsten Hopp ec2eb3
Karsten Hopp ec2eb3
Karsten Hopp ec2eb3
*** ../vim-7.3.1016/src/regexp_nfa.c	2013-05-25 15:31:02.000000000 +0200
Karsten Hopp ec2eb3
--- src/regexp_nfa.c	2013-05-25 20:18:25.000000000 +0200
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 2471,2494 ****
Karsten Hopp ec2eb3
   * NFA execution code.
Karsten Hopp ec2eb3
   ****************************************************************/
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
! /* thread_T contains runtime information of a NFA state */
Karsten Hopp ec2eb3
! struct thread
Karsten Hopp ec2eb3
  {
Karsten Hopp ec2eb3
      nfa_state_T	*state;
Karsten Hopp ec2eb3
!     regsub_T	sub;		/* submatch info */
Karsten Hopp ec2eb3
! };
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  typedef struct
Karsten Hopp ec2eb3
  {
Karsten Hopp ec2eb3
!     thread_T	*t;
Karsten Hopp ec2eb3
!     int		n;
Karsten Hopp ec2eb3
! } List;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
! static void addstate __ARGS((List *l, nfa_state_T *state, regsub_T *m, int off, int lid, int *match));
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
      static void
Karsten Hopp ec2eb3
  addstate(l, state, m, off, lid, match)
Karsten Hopp ec2eb3
!     List		*l;	/* runtime state list */
Karsten Hopp ec2eb3
      nfa_state_T		*state;	/* state to update */
Karsten Hopp ec2eb3
      regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp ec2eb3
      int			off;	/* byte offset, when -1 go to next line */
Karsten Hopp ec2eb3
--- 2471,2497 ----
Karsten Hopp ec2eb3
   * NFA execution code.
Karsten Hopp ec2eb3
   ****************************************************************/
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
! /* nfa_thread_T contains runtime information of a NFA state */
Karsten Hopp ec2eb3
! typedef struct
Karsten Hopp ec2eb3
  {
Karsten Hopp ec2eb3
      nfa_state_T	*state;
Karsten Hopp ec2eb3
!     regsub_T	sub;		/* Submatch info. TODO: expensive! */
Karsten Hopp ec2eb3
! } nfa_thread_T;
Karsten Hopp ec2eb3
! 
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  typedef struct
Karsten Hopp ec2eb3
  {
Karsten Hopp ec2eb3
!     nfa_thread_T    *t;
Karsten Hopp ec2eb3
!     int		    n;
Karsten Hopp ec2eb3
! } nfa_list_T;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
! static void addstate __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *m, int off, int lid, int *match));
Karsten Hopp ec2eb3
! 
Karsten Hopp ec2eb3
! static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state, regsub_T *m, int lid, int *match, int *ip));
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
      static void
Karsten Hopp ec2eb3
  addstate(l, state, m, off, lid, match)
Karsten Hopp ec2eb3
!     nfa_list_T		*l;	/* runtime state list */
Karsten Hopp ec2eb3
      nfa_state_T		*state;	/* state to update */
Karsten Hopp ec2eb3
      regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp ec2eb3
      int			off;	/* byte offset, when -1 go to next line */
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 2497,2503 ****
Karsten Hopp ec2eb3
  {
Karsten Hopp ec2eb3
      regsub_T		save;
Karsten Hopp ec2eb3
      int			subidx = 0;
Karsten Hopp ec2eb3
!     thread_T		*lastthread;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
      if (l == NULL || state == NULL)
Karsten Hopp ec2eb3
  	return;
Karsten Hopp ec2eb3
--- 2500,2506 ----
Karsten Hopp ec2eb3
  {
Karsten Hopp ec2eb3
      regsub_T		save;
Karsten Hopp ec2eb3
      int			subidx = 0;
Karsten Hopp ec2eb3
!     nfa_thread_T	*lastthread;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
      if (l == NULL || state == NULL)
Karsten Hopp ec2eb3
  	return;
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 2533,2539 ****
Karsten Hopp ec2eb3
  		state->lastlist = lid;
Karsten Hopp ec2eb3
  		lastthread = &l->t[l->n++];
Karsten Hopp ec2eb3
  		lastthread->state = state;
Karsten Hopp ec2eb3
! 		lastthread->sub = *m;
Karsten Hopp ec2eb3
  	    }
Karsten Hopp ec2eb3
      }
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
--- 2536,2542 ----
Karsten Hopp ec2eb3
  		state->lastlist = lid;
Karsten Hopp ec2eb3
  		lastthread = &l->t[l->n++];
Karsten Hopp ec2eb3
  		lastthread->state = state;
Karsten Hopp ec2eb3
! 		lastthread->sub = *m; /* TODO: expensive! */
Karsten Hopp ec2eb3
  	    }
Karsten Hopp ec2eb3
      }
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 2698,2703 ****
Karsten Hopp ec2eb3
--- 2701,2754 ----
Karsten Hopp ec2eb3
  }
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  /*
Karsten Hopp ec2eb3
+  * Like addstate(), but the new state(s) are put at position "*ip".
Karsten Hopp ec2eb3
+  * Used for zero-width matches, next state to use is the added one.
Karsten Hopp ec2eb3
+  * This makes sure the order of states to be tried does not change, which
Karsten Hopp ec2eb3
+  * matters for alternatives.
Karsten Hopp ec2eb3
+  */
Karsten Hopp ec2eb3
+     static void
Karsten Hopp ec2eb3
+ addstate_here(l, state, m, lid, matchp, ip)
Karsten Hopp ec2eb3
+     nfa_list_T		*l;	/* runtime state list */
Karsten Hopp ec2eb3
+     nfa_state_T		*state;	/* state to update */
Karsten Hopp ec2eb3
+     regsub_T		*m;	/* pointers to subexpressions */
Karsten Hopp ec2eb3
+     int			lid;
Karsten Hopp ec2eb3
+     int			*matchp;	/* found match? */
Karsten Hopp ec2eb3
+     int			*ip;
Karsten Hopp ec2eb3
+ {
Karsten Hopp ec2eb3
+     int tlen = l->n;
Karsten Hopp ec2eb3
+     int count;
Karsten Hopp ec2eb3
+     int i = *ip;
Karsten Hopp ec2eb3
+ 
Karsten Hopp ec2eb3
+     /* first add the state(s) at the end, so that we know how many there are */
Karsten Hopp ec2eb3
+     addstate(l, state, m, 0, lid, matchp);
Karsten Hopp ec2eb3
+ 
Karsten Hopp ec2eb3
+     /* when "*ip" was at the end of the list, nothing to do */
Karsten Hopp ec2eb3
+     if (i + 1 == tlen)
Karsten Hopp ec2eb3
+ 	return;
Karsten Hopp ec2eb3
+ 
Karsten Hopp ec2eb3
+     /* re-order to put the new state at the current position */
Karsten Hopp ec2eb3
+     count = l->n - tlen;
Karsten Hopp ec2eb3
+     if (count > 1)
Karsten Hopp ec2eb3
+     {
Karsten Hopp ec2eb3
+ 	/* make space for new states, then move them from the
Karsten Hopp ec2eb3
+ 	 * end to the current position */
Karsten Hopp ec2eb3
+ 	mch_memmove(&(l->t[i + count]),
Karsten Hopp ec2eb3
+ 		&(l->t[i + 1]),
Karsten Hopp ec2eb3
+ 		sizeof(nfa_thread_T) * (l->n - i - 1));
Karsten Hopp ec2eb3
+ 	mch_memmove(&(l->t[i]),
Karsten Hopp ec2eb3
+ 		&(l->t[l->n - 1]),
Karsten Hopp ec2eb3
+ 		sizeof(nfa_thread_T) * count);
Karsten Hopp ec2eb3
+     }
Karsten Hopp ec2eb3
+     else
Karsten Hopp ec2eb3
+     {
Karsten Hopp ec2eb3
+ 	/* overwrite the current state */
Karsten Hopp ec2eb3
+ 	l->t[i] = l->t[l->n - 1];
Karsten Hopp ec2eb3
+     }
Karsten Hopp ec2eb3
+     --l->n;
Karsten Hopp ec2eb3
+     *ip = i - 1;
Karsten Hopp ec2eb3
+ }
Karsten Hopp ec2eb3
+ 
Karsten Hopp ec2eb3
+ /*
Karsten Hopp ec2eb3
   * Check character class "class" against current character c.
Karsten Hopp ec2eb3
   */
Karsten Hopp ec2eb3
      static int
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 2872,2888 ****
Karsten Hopp ec2eb3
      int		match = FALSE;
Karsten Hopp ec2eb3
      int		flag = 0;
Karsten Hopp ec2eb3
      int		old_reglnum = -1;
Karsten Hopp ec2eb3
!     int		go_to_nextline;
Karsten Hopp ec2eb3
!     thread_T	*t;
Karsten Hopp ec2eb3
      char_u	*old_reginput = NULL;
Karsten Hopp ec2eb3
      char_u	*old_regline = NULL;
Karsten Hopp ec2eb3
!     List	list[3];
Karsten Hopp ec2eb3
!     List	*listtbl[2][2];
Karsten Hopp ec2eb3
!     List	*ll;
Karsten Hopp ec2eb3
      int		listid = 1;
Karsten Hopp ec2eb3
!     List	*thislist;
Karsten Hopp ec2eb3
!     List	*nextlist;
Karsten Hopp ec2eb3
!     List	*neglist;
Karsten Hopp ec2eb3
      int		*listids = NULL;
Karsten Hopp ec2eb3
      int		j = 0;
Karsten Hopp ec2eb3
  #ifdef NFA_REGEXP_DEBUG_LOG
Karsten Hopp ec2eb3
--- 2923,2939 ----
Karsten Hopp ec2eb3
      int		match = FALSE;
Karsten Hopp ec2eb3
      int		flag = 0;
Karsten Hopp ec2eb3
      int		old_reglnum = -1;
Karsten Hopp ec2eb3
!     int		go_to_nextline = FALSE;
Karsten Hopp ec2eb3
!     nfa_thread_T *t;
Karsten Hopp ec2eb3
      char_u	*old_reginput = NULL;
Karsten Hopp ec2eb3
      char_u	*old_regline = NULL;
Karsten Hopp ec2eb3
!     nfa_list_T	list[3];
Karsten Hopp ec2eb3
!     nfa_list_T	*listtbl[2][2];
Karsten Hopp ec2eb3
!     nfa_list_T	*ll;
Karsten Hopp ec2eb3
      int		listid = 1;
Karsten Hopp ec2eb3
!     nfa_list_T	*thislist;
Karsten Hopp ec2eb3
!     nfa_list_T	*nextlist;
Karsten Hopp ec2eb3
!     nfa_list_T	*neglist;
Karsten Hopp ec2eb3
      int		*listids = NULL;
Karsten Hopp ec2eb3
      int		j = 0;
Karsten Hopp ec2eb3
  #ifdef NFA_REGEXP_DEBUG_LOG
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 2896,2905 ****
Karsten Hopp ec2eb3
  #endif
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
      /* Allocate memory for the lists of nodes */
Karsten Hopp ec2eb3
!     size = (nstate + 1) * sizeof(thread_T);
Karsten Hopp ec2eb3
!     list[0].t = (thread_T *)lalloc(size, TRUE);
Karsten Hopp ec2eb3
!     list[1].t = (thread_T *)lalloc(size, TRUE);
Karsten Hopp ec2eb3
!     list[2].t = (thread_T *)lalloc(size, TRUE);
Karsten Hopp ec2eb3
      if (list[0].t == NULL || list[1].t == NULL || list[2].t == NULL)
Karsten Hopp ec2eb3
  	goto theend;
Karsten Hopp ec2eb3
      vim_memset(list[0].t, 0, size);
Karsten Hopp ec2eb3
--- 2947,2956 ----
Karsten Hopp ec2eb3
  #endif
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
      /* Allocate memory for the lists of nodes */
Karsten Hopp ec2eb3
!     size = (nstate + 1) * sizeof(nfa_thread_T);
Karsten Hopp ec2eb3
!     list[0].t = (nfa_thread_T *)lalloc(size, TRUE);
Karsten Hopp ec2eb3
!     list[1].t = (nfa_thread_T *)lalloc(size, TRUE);
Karsten Hopp ec2eb3
!     list[2].t = (nfa_thread_T *)lalloc(size, TRUE);
Karsten Hopp ec2eb3
      if (list[0].t == NULL || list[1].t == NULL || list[2].t == NULL)
Karsten Hopp ec2eb3
  	goto theend;
Karsten Hopp ec2eb3
      vim_memset(list[0].t, 0, size);
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 3056,3063 ****
Karsten Hopp ec2eb3
  		 * nfa_regmatch().  Submatches are stored in *m, and used in
Karsten Hopp ec2eb3
  		 * the parent call. */
Karsten Hopp ec2eb3
  		if (start->c == NFA_MOPEN + 0)
Karsten Hopp ec2eb3
! 		    addstate(thislist, t->state->out, &t->sub, 0, listid,
Karsten Hopp ec2eb3
! 								      &match);
Karsten Hopp ec2eb3
  		else
Karsten Hopp ec2eb3
  		{
Karsten Hopp ec2eb3
  		    *m = t->sub;
Karsten Hopp ec2eb3
--- 3107,3114 ----
Karsten Hopp ec2eb3
  		 * nfa_regmatch().  Submatches are stored in *m, and used in
Karsten Hopp ec2eb3
  		 * the parent call. */
Karsten Hopp ec2eb3
  		if (start->c == NFA_MOPEN + 0)
Karsten Hopp ec2eb3
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp ec2eb3
! 								  &match, &i);
Karsten Hopp ec2eb3
  		else
Karsten Hopp ec2eb3
  		{
Karsten Hopp ec2eb3
  		    *m = t->sub;
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 3130,3137 ****
Karsten Hopp ec2eb3
  			    t->sub.end[j] = m->end[j];
Karsten Hopp ec2eb3
  			}
Karsten Hopp ec2eb3
  		    /* t->state->out1 is the corresponding END_INVISIBLE node */
Karsten Hopp ec2eb3
! 		    addstate(thislist, t->state->out1->out, &t->sub, 0, listid,
Karsten Hopp ec2eb3
! 								    &match);
Karsten Hopp ec2eb3
  		}
Karsten Hopp ec2eb3
  		else
Karsten Hopp ec2eb3
  		{
Karsten Hopp ec2eb3
--- 3181,3188 ----
Karsten Hopp ec2eb3
  			    t->sub.end[j] = m->end[j];
Karsten Hopp ec2eb3
  			}
Karsten Hopp ec2eb3
  		    /* t->state->out1 is the corresponding END_INVISIBLE node */
Karsten Hopp ec2eb3
! 		    addstate_here(thislist, t->state->out1->out, &t->sub,
Karsten Hopp ec2eb3
! 							  listid, &match, &i);
Karsten Hopp ec2eb3
  		}
Karsten Hopp ec2eb3
  		else
Karsten Hopp ec2eb3
  		{
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 3142,3155 ****
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  	    case NFA_BOL:
Karsten Hopp ec2eb3
  		if (reginput == regline)
Karsten Hopp ec2eb3
! 		    addstate(thislist, t->state->out, &t->sub, 0, listid,
Karsten Hopp ec2eb3
! 								    &match);
Karsten Hopp ec2eb3
  		break;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  	    case NFA_EOL:
Karsten Hopp ec2eb3
  		if (c == NUL)
Karsten Hopp ec2eb3
! 		    addstate(thislist, t->state->out, &t->sub, 0, listid,
Karsten Hopp ec2eb3
! 								    &match);
Karsten Hopp ec2eb3
  		break;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  	    case NFA_BOW:
Karsten Hopp ec2eb3
--- 3193,3206 ----
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  	    case NFA_BOL:
Karsten Hopp ec2eb3
  		if (reginput == regline)
Karsten Hopp ec2eb3
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp ec2eb3
! 								  &match, &i);
Karsten Hopp ec2eb3
  		break;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  	    case NFA_EOL:
Karsten Hopp ec2eb3
  		if (c == NUL)
Karsten Hopp ec2eb3
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp ec2eb3
! 								  &match, &i);
Karsten Hopp ec2eb3
  		break;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  	    case NFA_BOW:
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 3176,3183 ****
Karsten Hopp ec2eb3
  				   && vim_iswordc_buf(reginput[-1], reg_buf)))
Karsten Hopp ec2eb3
  		    bow = FALSE;
Karsten Hopp ec2eb3
  		if (bow)
Karsten Hopp ec2eb3
! 		    addstate(thislist, t->state->out, &t->sub, 0, listid,
Karsten Hopp ec2eb3
! 								    &match);
Karsten Hopp ec2eb3
  		break;
Karsten Hopp ec2eb3
  	    }
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
--- 3227,3234 ----
Karsten Hopp ec2eb3
  				   && vim_iswordc_buf(reginput[-1], reg_buf)))
Karsten Hopp ec2eb3
  		    bow = FALSE;
Karsten Hopp ec2eb3
  		if (bow)
Karsten Hopp ec2eb3
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp ec2eb3
! 								  &match, &i);
Karsten Hopp ec2eb3
  		break;
Karsten Hopp ec2eb3
  	    }
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 3204,3211 ****
Karsten Hopp ec2eb3
  			|| (reginput[0] != NUL && vim_iswordc_buf(c, reg_buf)))
Karsten Hopp ec2eb3
  		    eow = FALSE;
Karsten Hopp ec2eb3
  		if (eow)
Karsten Hopp ec2eb3
! 		    addstate(thislist, t->state->out, &t->sub, 0, listid,
Karsten Hopp ec2eb3
! 								    &match);
Karsten Hopp ec2eb3
  		break;
Karsten Hopp ec2eb3
  	    }
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
--- 3255,3262 ----
Karsten Hopp ec2eb3
  			|| (reginput[0] != NUL && vim_iswordc_buf(c, reg_buf)))
Karsten Hopp ec2eb3
  		    eow = FALSE;
Karsten Hopp ec2eb3
  		if (eow)
Karsten Hopp ec2eb3
! 		    addstate_here(thislist, t->state->out, &t->sub, listid,
Karsten Hopp ec2eb3
! 								  &match, &i);
Karsten Hopp ec2eb3
  		break;
Karsten Hopp ec2eb3
  	    }
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
*** ../vim-7.3.1016/src/testdir/test64.in	2013-05-21 13:30:17.000000000 +0200
Karsten Hopp ec2eb3
--- src/testdir/test64.in	2013-05-25 19:54:40.000000000 +0200
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 270,275 ****
Karsten Hopp ec2eb3
--- 270,276 ----
Karsten Hopp ec2eb3
  :call add(tl, ['aa \zsax', ' ax'])						" must match before \zs
Karsten Hopp ec2eb3
  :call add(tl, ['abc \zsmatch\ze abc', 'abc abc abc match abc abc', 'match'])
Karsten Hopp ec2eb3
  :call add(tl, ['\v(a \zsif .*){2}', 'a if then a if last', 'if last', 'a if last'])
Karsten Hopp ec2eb3
+ :call add(tl, ['\>\zs.', 'aword. ', '.'])
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  :"""" Tests for \@ features
Karsten Hopp ec2eb3
  :call add(tl, ['abc\@=', 'abc', 'ab'])
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 299,304 ****
Karsten Hopp ec2eb3
--- 300,311 ----
Karsten Hopp ec2eb3
  :call add(tl, ['\%u0020', 'yes no', ' '])
Karsten Hopp ec2eb3
  :call add(tl, ['\%U00000020', 'yes no', ' '])
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
+ :"""" Alternatives, must use first longest match
Karsten Hopp ec2eb3
+ :call add(tl, ['goo\|go', 'google', 'goo'])
Karsten Hopp ec2eb3
+ :call add(tl, ['\
Karsten Hopp ec2eb3
+ :call add(tl, ['\
Karsten Hopp ec2eb3
+ 
Karsten Hopp ec2eb3
+ 
Karsten Hopp ec2eb3
  :"""" Run the tests
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  :"
Karsten Hopp ec2eb3
*** ../vim-7.3.1016/src/testdir/test64.ok	2013-05-21 13:30:17.000000000 +0200
Karsten Hopp ec2eb3
--- src/testdir/test64.ok	2013-05-25 19:54:43.000000000 +0200
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 209,214 ****
Karsten Hopp ec2eb3
--- 209,215 ----
Karsten Hopp ec2eb3
  OK - aa \zsax
Karsten Hopp ec2eb3
  OK - abc \zsmatch\ze abc
Karsten Hopp ec2eb3
  OK - \v(a \zsif .*){2}
Karsten Hopp ec2eb3
+ OK - \>\zs.
Karsten Hopp ec2eb3
  OK - abc\@=
Karsten Hopp ec2eb3
  OK - abc\@=cd
Karsten Hopp ec2eb3
  OK - abc\@=
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 231,234 ****
Karsten Hopp ec2eb3
--- 232,238 ----
Karsten Hopp ec2eb3
  OK - \%x20
Karsten Hopp ec2eb3
  OK - \%u0020
Karsten Hopp ec2eb3
  OK - \%U00000020
Karsten Hopp ec2eb3
+ OK - goo\|go
Karsten Hopp ec2eb3
+ OK - \
Karsten Hopp ec2eb3
+ OK - \
Karsten Hopp ec2eb3
  192.168.0.1
Karsten Hopp ec2eb3
*** ../vim-7.3.1016/src/regexp.h	2013-05-25 15:31:02.000000000 +0200
Karsten Hopp ec2eb3
--- src/regexp.h	2013-05-25 20:17:53.000000000 +0200
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 29,36 ****
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
  typedef struct regengine regengine_T;
Karsten Hopp ec2eb3
  
Karsten Hopp ec2eb3
- typedef struct thread thread_T;
Karsten Hopp ec2eb3
- 
Karsten Hopp ec2eb3
  /*
Karsten Hopp ec2eb3
   * Structure returned by vim_regcomp() to pass on to vim_regexec().
Karsten Hopp ec2eb3
   * This is the general structure. For the actual matcher, two specific
Karsten Hopp ec2eb3
--- 29,34 ----
Karsten Hopp ec2eb3
*** ../vim-7.3.1016/src/version.c	2013-05-25 15:31:02.000000000 +0200
Karsten Hopp ec2eb3
--- src/version.c	2013-05-25 20:15:23.000000000 +0200
Karsten Hopp ec2eb3
***************
Karsten Hopp ec2eb3
*** 730,731 ****
Karsten Hopp ec2eb3
--- 730,733 ----
Karsten Hopp ec2eb3
  {   /* Add new patch number below this line */
Karsten Hopp ec2eb3
+ /**/
Karsten Hopp ec2eb3
+     1017,
Karsten Hopp ec2eb3
  /**/
Karsten Hopp ec2eb3
Karsten Hopp ec2eb3
-- 
Karsten Hopp ec2eb3
A salesperson says:            Translation:
Karsten Hopp ec2eb3
"backward compatible"          Old technology
Karsten Hopp ec2eb3
"Premium"                      Overpriced
Karsten Hopp ec2eb3
"Can't keep it on the shelf"   Unavailable
Karsten Hopp ec2eb3
"Stands alone"                 Piece of shit
Karsten Hopp ec2eb3
"Proprietary"                  Incompatible
Karsten Hopp ec2eb3
				(Scott Adams - The Dilbert principle)
Karsten Hopp ec2eb3
Karsten Hopp ec2eb3
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp ec2eb3
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp ec2eb3
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp ec2eb3
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///