Karsten Hopp cb1bb0
To: vim-dev@vim.org
Karsten Hopp cb1bb0
Subject: Patch 7.1.292
Karsten Hopp cb1bb0
Fcc: outbox
Karsten Hopp cb1bb0
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp cb1bb0
Mime-Version: 1.0
Karsten Hopp cb1bb0
Content-Type: text/plain; charset=ISO-8859-1
Karsten Hopp cb1bb0
Content-Transfer-Encoding: 8bit
Karsten Hopp cb1bb0
------------
Karsten Hopp cb1bb0
Karsten Hopp cb1bb0
Patch 7.1.292
Karsten Hopp cb1bb0
Problem:    When using a pattern with "\@<=" the submatches can be wrong.
Karsten Hopp cb1bb0
	    (Brett Stahlman)
Karsten Hopp cb1bb0
Solution:   Save the submatches when attempting a look-behind match.
Karsten Hopp cb1bb0
Files:	    src/regexp.c
Karsten Hopp cb1bb0
Karsten Hopp cb1bb0
Karsten Hopp cb1bb0
*** ../vim-7.1.291/src/regexp.c	Sat Jan 19 15:55:51 2008
Karsten Hopp cb1bb0
--- src/regexp.c	Tue Apr  1 18:15:47 2008
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 3039,3044 ****
Karsten Hopp cb1bb0
--- 3039,3053 ----
Karsten Hopp cb1bb0
      } se_u;
Karsten Hopp cb1bb0
  } save_se_T;
Karsten Hopp cb1bb0
  
Karsten Hopp cb1bb0
+ /* used for BEHIND and NOBEHIND matching */
Karsten Hopp cb1bb0
+ typedef struct regbehind_S
Karsten Hopp cb1bb0
+ {
Karsten Hopp cb1bb0
+     regsave_T	save_after;
Karsten Hopp cb1bb0
+     regsave_T	save_behind;
Karsten Hopp cb1bb0
+     save_se_T   save_start[NSUBEXP];
Karsten Hopp cb1bb0
+     save_se_T   save_end[NSUBEXP];
Karsten Hopp cb1bb0
+ } regbehind_T;
Karsten Hopp cb1bb0
+ 
Karsten Hopp cb1bb0
  static char_u	*reg_getline __ARGS((linenr_T lnum));
Karsten Hopp cb1bb0
  static long	vim_regexec_both __ARGS((char_u *line, colnr_T col, proftime_T *tm));
Karsten Hopp cb1bb0
  static long	regtry __ARGS((regprog_T *prog, colnr_T col));
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 3046,3051 ****
Karsten Hopp cb1bb0
--- 3055,3062 ----
Karsten Hopp cb1bb0
  #ifdef FEAT_SYN_HL
Karsten Hopp cb1bb0
  static void	cleanup_zsubexpr __ARGS((void));
Karsten Hopp cb1bb0
  #endif
Karsten Hopp cb1bb0
+ static void	save_subexpr __ARGS((regbehind_T *bp));
Karsten Hopp cb1bb0
+ static void	restore_subexpr __ARGS((regbehind_T *bp));
Karsten Hopp cb1bb0
  static void	reg_nextline __ARGS((void));
Karsten Hopp cb1bb0
  static void	reg_save __ARGS((regsave_T *save, garray_T *gap));
Karsten Hopp cb1bb0
  static void	reg_restore __ARGS((regsave_T *save, garray_T *gap));
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 3166,3184 ****
Karsten Hopp cb1bb0
  	save_se_T  sesave;
Karsten Hopp cb1bb0
  	regsave_T  regsave;
Karsten Hopp cb1bb0
      } rs_un;			/* room for saving reginput */
Karsten Hopp cb1bb0
!     short	rs_no;		/* submatch nr */
Karsten Hopp cb1bb0
  } regitem_T;
Karsten Hopp cb1bb0
  
Karsten Hopp cb1bb0
  static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan));
Karsten Hopp cb1bb0
  static void regstack_pop __ARGS((char_u **scan));
Karsten Hopp cb1bb0
  
Karsten Hopp cb1bb0
- /* used for BEHIND and NOBEHIND matching */
Karsten Hopp cb1bb0
- typedef struct regbehind_S
Karsten Hopp cb1bb0
- {
Karsten Hopp cb1bb0
-     regsave_T	save_after;
Karsten Hopp cb1bb0
-     regsave_T	save_behind;
Karsten Hopp cb1bb0
- } regbehind_T;
Karsten Hopp cb1bb0
- 
Karsten Hopp cb1bb0
  /* used for STAR, PLUS and BRACE_SIMPLE matching */
Karsten Hopp cb1bb0
  typedef struct regstar_S
Karsten Hopp cb1bb0
  {
Karsten Hopp cb1bb0
--- 3177,3188 ----
Karsten Hopp cb1bb0
  	save_se_T  sesave;
Karsten Hopp cb1bb0
  	regsave_T  regsave;
Karsten Hopp cb1bb0
      } rs_un;			/* room for saving reginput */
Karsten Hopp cb1bb0
!     short	rs_no;		/* submatch nr or BEHIND/NOBEHIND */
Karsten Hopp cb1bb0
  } regitem_T;
Karsten Hopp cb1bb0
  
Karsten Hopp cb1bb0
  static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan));
Karsten Hopp cb1bb0
  static void regstack_pop __ARGS((char_u **scan));
Karsten Hopp cb1bb0
  
Karsten Hopp cb1bb0
  /* used for STAR, PLUS and BRACE_SIMPLE matching */
Karsten Hopp cb1bb0
  typedef struct regstar_S
Karsten Hopp cb1bb0
  {
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 4888,4893 ****
Karsten Hopp cb1bb0
--- 4892,4901 ----
Karsten Hopp cb1bb0
  		    status = RA_FAIL;
Karsten Hopp cb1bb0
  		else
Karsten Hopp cb1bb0
  		{
Karsten Hopp cb1bb0
+ 		    /* Need to save the subexpr to be able to restore them
Karsten Hopp cb1bb0
+ 		     * when there is a match but we don't use it. */
Karsten Hopp cb1bb0
+ 		    save_subexpr(((regbehind_T *)rp) - 1);
Karsten Hopp cb1bb0
+ 
Karsten Hopp cb1bb0
  		    rp->rs_no = op;
Karsten Hopp cb1bb0
  		    reg_save(&rp->rs_un.regsave, &backpos);
Karsten Hopp cb1bb0
  		    /* First try if what follows matches.  If it does then we
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 5118,5132 ****
Karsten Hopp cb1bb0
  		    reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
Karsten Hopp cb1bb0
  								    &backpos);
Karsten Hopp cb1bb0
  		else
Karsten Hopp cb1bb0
! 		    /* But we didn't want a match. */
Karsten Hopp cb1bb0
  		    status = RA_NOMATCH;
Karsten Hopp cb1bb0
  		regstack_pop(&scan;;
Karsten Hopp cb1bb0
  		regstack.ga_len -= sizeof(regbehind_T);
Karsten Hopp cb1bb0
  	    }
Karsten Hopp cb1bb0
  	    else
Karsten Hopp cb1bb0
  	    {
Karsten Hopp cb1bb0
! 		/* No match: Go back one character.  May go to previous
Karsten Hopp cb1bb0
! 		 * line once. */
Karsten Hopp cb1bb0
  		no = OK;
Karsten Hopp cb1bb0
  		if (REG_MULTI)
Karsten Hopp cb1bb0
  		{
Karsten Hopp cb1bb0
--- 5126,5145 ----
Karsten Hopp cb1bb0
  		    reg_restore(&(((regbehind_T *)rp) - 1)->save_after,
Karsten Hopp cb1bb0
  								    &backpos);
Karsten Hopp cb1bb0
  		else
Karsten Hopp cb1bb0
! 		{
Karsten Hopp cb1bb0
! 		    /* But we didn't want a match.  Need to restore the
Karsten Hopp cb1bb0
! 		     * subexpr, because what follows matched, so they have
Karsten Hopp cb1bb0
! 		     * been set. */
Karsten Hopp cb1bb0
  		    status = RA_NOMATCH;
Karsten Hopp cb1bb0
+ 		    restore_subexpr(((regbehind_T *)rp) - 1);
Karsten Hopp cb1bb0
+ 		}
Karsten Hopp cb1bb0
  		regstack_pop(&scan;;
Karsten Hopp cb1bb0
  		regstack.ga_len -= sizeof(regbehind_T);
Karsten Hopp cb1bb0
  	    }
Karsten Hopp cb1bb0
  	    else
Karsten Hopp cb1bb0
  	    {
Karsten Hopp cb1bb0
! 		/* No match or a match that doesn't end where we want it: Go
Karsten Hopp cb1bb0
! 		 * back one character.  May go to previous line once. */
Karsten Hopp cb1bb0
  		no = OK;
Karsten Hopp cb1bb0
  		if (REG_MULTI)
Karsten Hopp cb1bb0
  		{
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 5160,5165 ****
Karsten Hopp cb1bb0
--- 5173,5185 ----
Karsten Hopp cb1bb0
  		    /* Advanced, prepare for finding match again. */
Karsten Hopp cb1bb0
  		    reg_restore(&rp->rs_un.regsave, &backpos);
Karsten Hopp cb1bb0
  		    scan = OPERAND(rp->rs_scan);
Karsten Hopp cb1bb0
+ 		    if (status == RA_MATCH)
Karsten Hopp cb1bb0
+ 		    {
Karsten Hopp cb1bb0
+ 			/* We did match, so subexpr may have been changed,
Karsten Hopp cb1bb0
+ 			 * need to restore them for the next try. */
Karsten Hopp cb1bb0
+ 			status = RA_NOMATCH;
Karsten Hopp cb1bb0
+ 			restore_subexpr(((regbehind_T *)rp) - 1);
Karsten Hopp cb1bb0
+ 		    }
Karsten Hopp cb1bb0
  		}
Karsten Hopp cb1bb0
  		else
Karsten Hopp cb1bb0
  		{
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 5172,5178 ****
Karsten Hopp cb1bb0
  			status = RA_MATCH;
Karsten Hopp cb1bb0
  		    }
Karsten Hopp cb1bb0
  		    else
Karsten Hopp cb1bb0
! 			status = RA_NOMATCH;
Karsten Hopp cb1bb0
  		    regstack_pop(&scan;;
Karsten Hopp cb1bb0
  		    regstack.ga_len -= sizeof(regbehind_T);
Karsten Hopp cb1bb0
  		}
Karsten Hopp cb1bb0
--- 5192,5207 ----
Karsten Hopp cb1bb0
  			status = RA_MATCH;
Karsten Hopp cb1bb0
  		    }
Karsten Hopp cb1bb0
  		    else
Karsten Hopp cb1bb0
! 		    {
Karsten Hopp cb1bb0
! 			/* We do want a proper match.  Need to restore the
Karsten Hopp cb1bb0
! 			 * subexpr if we had a match, because they may have
Karsten Hopp cb1bb0
! 			 * been set. */
Karsten Hopp cb1bb0
! 			if (status == RA_MATCH)
Karsten Hopp cb1bb0
! 			{
Karsten Hopp cb1bb0
! 			    status = RA_NOMATCH;
Karsten Hopp cb1bb0
! 			    restore_subexpr(((regbehind_T *)rp) - 1);
Karsten Hopp cb1bb0
! 			}
Karsten Hopp cb1bb0
! 		    }
Karsten Hopp cb1bb0
  		    regstack_pop(&scan;;
Karsten Hopp cb1bb0
  		    regstack.ga_len -= sizeof(regbehind_T);
Karsten Hopp cb1bb0
  		}
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 5820,5825 ****
Karsten Hopp cb1bb0
--- 5849,5903 ----
Karsten Hopp cb1bb0
  #endif
Karsten Hopp cb1bb0
  
Karsten Hopp cb1bb0
  /*
Karsten Hopp cb1bb0
+  * Save the current subexpr to "bp", so that they can be restored
Karsten Hopp cb1bb0
+  * later by restore_subexpr().
Karsten Hopp cb1bb0
+  */
Karsten Hopp cb1bb0
+     static void
Karsten Hopp cb1bb0
+ save_subexpr(bp)
Karsten Hopp cb1bb0
+     regbehind_T *bp;
Karsten Hopp cb1bb0
+ {
Karsten Hopp cb1bb0
+     int i;
Karsten Hopp cb1bb0
+ 
Karsten Hopp cb1bb0
+     for (i = 0; i < NSUBEXP; ++i)
Karsten Hopp cb1bb0
+     {
Karsten Hopp cb1bb0
+ 	if (REG_MULTI)
Karsten Hopp cb1bb0
+ 	{
Karsten Hopp cb1bb0
+ 	    bp->save_start[i].se_u.pos = reg_startpos[i];
Karsten Hopp cb1bb0
+ 	    bp->save_end[i].se_u.pos = reg_endpos[i];
Karsten Hopp cb1bb0
+ 	}
Karsten Hopp cb1bb0
+ 	else
Karsten Hopp cb1bb0
+ 	{
Karsten Hopp cb1bb0
+ 	    bp->save_start[i].se_u.ptr = reg_startp[i];
Karsten Hopp cb1bb0
+ 	    bp->save_end[i].se_u.ptr = reg_endp[i];
Karsten Hopp cb1bb0
+ 	}
Karsten Hopp cb1bb0
+     }
Karsten Hopp cb1bb0
+ }
Karsten Hopp cb1bb0
+ 
Karsten Hopp cb1bb0
+ /*
Karsten Hopp cb1bb0
+  * Restore the subexpr from "bp".
Karsten Hopp cb1bb0
+  */
Karsten Hopp cb1bb0
+     static void
Karsten Hopp cb1bb0
+ restore_subexpr(bp)
Karsten Hopp cb1bb0
+     regbehind_T *bp;
Karsten Hopp cb1bb0
+ {
Karsten Hopp cb1bb0
+     int i;
Karsten Hopp cb1bb0
+ 
Karsten Hopp cb1bb0
+     for (i = 0; i < NSUBEXP; ++i)
Karsten Hopp cb1bb0
+     {
Karsten Hopp cb1bb0
+ 	if (REG_MULTI)
Karsten Hopp cb1bb0
+ 	{
Karsten Hopp cb1bb0
+ 	    reg_startpos[i] = bp->save_start[i].se_u.pos;
Karsten Hopp cb1bb0
+ 	    reg_endpos[i] = bp->save_end[i].se_u.pos;
Karsten Hopp cb1bb0
+ 	}
Karsten Hopp cb1bb0
+ 	else
Karsten Hopp cb1bb0
+ 	{
Karsten Hopp cb1bb0
+ 	    reg_startp[i] = bp->save_start[i].se_u.ptr;
Karsten Hopp cb1bb0
+ 	    reg_endp[i] = bp->save_end[i].se_u.ptr;
Karsten Hopp cb1bb0
+ 	}
Karsten Hopp cb1bb0
+     }
Karsten Hopp cb1bb0
+ }
Karsten Hopp cb1bb0
+ 
Karsten Hopp cb1bb0
+ /*
Karsten Hopp cb1bb0
   * Advance reglnum, regline and reginput to the next line.
Karsten Hopp cb1bb0
   */
Karsten Hopp cb1bb0
      static void
Karsten Hopp cb1bb0
*** ../vim-7.1.291/src/version.c	Tue Apr  1 20:58:23 2008
Karsten Hopp cb1bb0
--- src/version.c	Wed Apr  9 12:12:33 2008
Karsten Hopp cb1bb0
***************
Karsten Hopp cb1bb0
*** 668,669 ****
Karsten Hopp cb1bb0
--- 673,676 ----
Karsten Hopp cb1bb0
  {   /* Add new patch number below this line */
Karsten Hopp cb1bb0
+ /**/
Karsten Hopp cb1bb0
+     292,
Karsten Hopp cb1bb0
  /**/
Karsten Hopp cb1bb0
Karsten Hopp cb1bb0
-- 
Karsten Hopp cb1bb0
hundred-and-one symptoms of being an internet addict:
Karsten Hopp cb1bb0
259. When you enter your name in the AltaVista search engine, the top ten
Karsten Hopp cb1bb0
     matches do indeed refer to you.
Karsten Hopp cb1bb0
Karsten Hopp cb1bb0
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp cb1bb0
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp cb1bb0
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp cb1bb0
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///