Karsten Hopp b3183e
To: vim_dev@googlegroups.com
Karsten Hopp b3183e
Subject: Patch 7.3.1087
Karsten Hopp b3183e
Fcc: outbox
Karsten Hopp b3183e
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp b3183e
Mime-Version: 1.0
Karsten Hopp b3183e
Content-Type: text/plain; charset=UTF-8
Karsten Hopp b3183e
Content-Transfer-Encoding: 8bit
Karsten Hopp b3183e
------------
Karsten Hopp b3183e
Karsten Hopp b3183e
Patch 7.3.1087
Karsten Hopp b3183e
Problem:    A leading star is not seen as a normal char when \{} follows.
Karsten Hopp b3183e
Solution:   Save and restore the parse state properly.
Karsten Hopp b3183e
Files:	    src/regexp.c, src/regexp_nfa.c, src/testdir/test64.in,
Karsten Hopp b3183e
	    src/testdir/test64.ok
Karsten Hopp b3183e
Karsten Hopp b3183e
Karsten Hopp b3183e
*** ../vim-7.3.1086/src/regexp.c	2013-05-29 18:45:07.000000000 +0200
Karsten Hopp b3183e
--- src/regexp.c	2013-06-01 14:33:26.000000000 +0200
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 665,674 ****
Karsten Hopp b3183e
--- 665,689 ----
Karsten Hopp b3183e
  #define REG_ZPAREN	2	/* \z(\) */
Karsten Hopp b3183e
  #define REG_NPAREN	3	/* \%(\) */
Karsten Hopp b3183e
  
Karsten Hopp b3183e
+ typedef struct
Karsten Hopp b3183e
+ {
Karsten Hopp b3183e
+      char_u	*regparse;
Karsten Hopp b3183e
+      int	prevchr_len;
Karsten Hopp b3183e
+      int	curchr;
Karsten Hopp b3183e
+      int	prevchr;
Karsten Hopp b3183e
+      int	prevprevchr;
Karsten Hopp b3183e
+      int	nextchr;
Karsten Hopp b3183e
+      int	at_start;
Karsten Hopp b3183e
+      int	prev_at_start;
Karsten Hopp b3183e
+      int	regnpar;
Karsten Hopp b3183e
+ } parse_state_T;
Karsten Hopp b3183e
+ 
Karsten Hopp b3183e
  /*
Karsten Hopp b3183e
   * Forward declarations for vim_regcomp()'s friends.
Karsten Hopp b3183e
   */
Karsten Hopp b3183e
  static void	initchr __ARGS((char_u *));
Karsten Hopp b3183e
+ static void	save_parse_state __ARGS((parse_state_T *ps));
Karsten Hopp b3183e
+ static void	restore_parse_state __ARGS((parse_state_T *ps));
Karsten Hopp b3183e
  static int	getchr __ARGS((void));
Karsten Hopp b3183e
  static void	skipchr_keepstart __ARGS((void));
Karsten Hopp b3183e
  static int	peekchr __ARGS((void));
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 2951,2956 ****
Karsten Hopp b3183e
--- 2966,3009 ----
Karsten Hopp b3183e
  }
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  /*
Karsten Hopp b3183e
+  * Save the current parse state, so that it can be restored and parsing
Karsten Hopp b3183e
+  * starts in the same state again.
Karsten Hopp b3183e
+  */
Karsten Hopp b3183e
+     static void
Karsten Hopp b3183e
+ save_parse_state(ps)
Karsten Hopp b3183e
+     parse_state_T *ps;
Karsten Hopp b3183e
+ {
Karsten Hopp b3183e
+     ps->regparse = regparse;
Karsten Hopp b3183e
+     ps->prevchr_len = prevchr_len;
Karsten Hopp b3183e
+     ps->curchr = curchr;
Karsten Hopp b3183e
+     ps->prevchr = prevchr;
Karsten Hopp b3183e
+     ps->prevprevchr = prevprevchr;
Karsten Hopp b3183e
+     ps->nextchr = nextchr;
Karsten Hopp b3183e
+     ps->at_start = at_start;
Karsten Hopp b3183e
+     ps->prev_at_start = prev_at_start;
Karsten Hopp b3183e
+     ps->regnpar = regnpar;
Karsten Hopp b3183e
+ }
Karsten Hopp b3183e
+ 
Karsten Hopp b3183e
+ /*
Karsten Hopp b3183e
+  * Restore a previously saved parse state.
Karsten Hopp b3183e
+  */
Karsten Hopp b3183e
+     static void
Karsten Hopp b3183e
+ restore_parse_state(ps)
Karsten Hopp b3183e
+     parse_state_T *ps;
Karsten Hopp b3183e
+ {
Karsten Hopp b3183e
+     regparse = ps->regparse;
Karsten Hopp b3183e
+     prevchr_len = ps->prevchr_len;
Karsten Hopp b3183e
+     curchr = ps->curchr;
Karsten Hopp b3183e
+     prevchr = ps->prevchr;
Karsten Hopp b3183e
+     prevprevchr = ps->prevprevchr;
Karsten Hopp b3183e
+     nextchr = ps->nextchr;
Karsten Hopp b3183e
+     at_start = ps->at_start;
Karsten Hopp b3183e
+     prev_at_start = ps->prev_at_start;
Karsten Hopp b3183e
+     regnpar = ps->regnpar;
Karsten Hopp b3183e
+ }
Karsten Hopp b3183e
+ 
Karsten Hopp b3183e
+ 
Karsten Hopp b3183e
+ /*
Karsten Hopp b3183e
   * Get the next character without advancing.
Karsten Hopp b3183e
   */
Karsten Hopp b3183e
      static int
Karsten Hopp b3183e
*** ../vim-7.3.1086/src/regexp_nfa.c	2013-06-01 13:24:19.000000000 +0200
Karsten Hopp b3183e
--- src/regexp_nfa.c	2013-06-01 14:30:27.000000000 +0200
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 1318,1336 ****
Karsten Hopp b3183e
      int		ret;
Karsten Hopp b3183e
      long	minval, maxval;
Karsten Hopp b3183e
      int		greedy = TRUE;      /* Braces are prefixed with '-' ? */
Karsten Hopp b3183e
!     char_u	*old_regparse, *new_regparse;
Karsten Hopp b3183e
      int		c2;
Karsten Hopp b3183e
      int		old_post_pos;
Karsten Hopp b3183e
      int		my_post_start;
Karsten Hopp b3183e
-     int		old_regnpar;
Karsten Hopp b3183e
      int		quest;
Karsten Hopp b3183e
  
Karsten Hopp b3183e
!     /* Save the current position in the regexp, so that we can use it if
Karsten Hopp b3183e
!      * <atom>{m,n} is next. */
Karsten Hopp b3183e
!     old_regparse = regparse;
Karsten Hopp b3183e
!     /* Save current number of open parenthesis, so we can use it if
Karsten Hopp b3183e
!      * <atom>{m,n} is next */
Karsten Hopp b3183e
!     old_regnpar = regnpar;
Karsten Hopp b3183e
      /* store current pos in the postfix form, for \{m,n} involving 0s */
Karsten Hopp b3183e
      my_post_start = (int)(post_ptr - post_start);
Karsten Hopp b3183e
  
Karsten Hopp b3183e
--- 1318,1334 ----
Karsten Hopp b3183e
      int		ret;
Karsten Hopp b3183e
      long	minval, maxval;
Karsten Hopp b3183e
      int		greedy = TRUE;      /* Braces are prefixed with '-' ? */
Karsten Hopp b3183e
!     parse_state_T old_state;
Karsten Hopp b3183e
!     parse_state_T new_state;
Karsten Hopp b3183e
      int		c2;
Karsten Hopp b3183e
      int		old_post_pos;
Karsten Hopp b3183e
      int		my_post_start;
Karsten Hopp b3183e
      int		quest;
Karsten Hopp b3183e
  
Karsten Hopp b3183e
!     /* Save the current parse state, so that we can use it if <atom>{m,n} is
Karsten Hopp b3183e
!      * next. */
Karsten Hopp b3183e
!     save_parse_state(&old_state);
Karsten Hopp b3183e
! 
Karsten Hopp b3183e
      /* store current pos in the postfix form, for \{m,n} involving 0s */
Karsten Hopp b3183e
      my_post_start = (int)(post_ptr - post_start);
Karsten Hopp b3183e
  
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 1361,1368 ****
Karsten Hopp b3183e
  	     * In order to be consistent with the old engine, we replace
Karsten Hopp b3183e
  	     * <atom>+ with <atom><atom>*
Karsten Hopp b3183e
  	     */
Karsten Hopp b3183e
! 	    regnpar = old_regnpar;
Karsten Hopp b3183e
! 	    regparse = old_regparse;
Karsten Hopp b3183e
  	    curchr = -1;
Karsten Hopp b3183e
  	    if (nfa_regatom() == FAIL)
Karsten Hopp b3183e
  		return FAIL;
Karsten Hopp b3183e
--- 1359,1365 ----
Karsten Hopp b3183e
  	     * In order to be consistent with the old engine, we replace
Karsten Hopp b3183e
  	     * <atom>+ with <atom><atom>*
Karsten Hopp b3183e
  	     */
Karsten Hopp b3183e
! 	    restore_parse_state(&old_state);
Karsten Hopp b3183e
  	    curchr = -1;
Karsten Hopp b3183e
  	    if (nfa_regatom() == FAIL)
Karsten Hopp b3183e
  		return FAIL;
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 1452,1468 ****
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  	    /* Ignore previous call to nfa_regatom() */
Karsten Hopp b3183e
  	    post_ptr = post_start + my_post_start;
Karsten Hopp b3183e
! 	    /* Save pos after the repeated atom and the \{} */
Karsten Hopp b3183e
! 	    new_regparse = regparse;
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  	    quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY);
Karsten Hopp b3183e
  	    for (i = 0; i < maxval; i++)
Karsten Hopp b3183e
  	    {
Karsten Hopp b3183e
  		/* Goto beginning of the repeated atom */
Karsten Hopp b3183e
! 		regparse = old_regparse;
Karsten Hopp b3183e
! 		curchr = -1;
Karsten Hopp b3183e
! 		/* Restore count of parenthesis */
Karsten Hopp b3183e
! 		regnpar = old_regnpar;
Karsten Hopp b3183e
  		old_post_pos = (int)(post_ptr - post_start);
Karsten Hopp b3183e
  		if (nfa_regatom() == FAIL)
Karsten Hopp b3183e
  		    return FAIL;
Karsten Hopp b3183e
--- 1449,1462 ----
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  	    /* Ignore previous call to nfa_regatom() */
Karsten Hopp b3183e
  	    post_ptr = post_start + my_post_start;
Karsten Hopp b3183e
! 	    /* Save parse state after the repeated atom and the \{} */
Karsten Hopp b3183e
! 	    save_parse_state(&new_state);
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  	    quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY);
Karsten Hopp b3183e
  	    for (i = 0; i < maxval; i++)
Karsten Hopp b3183e
  	    {
Karsten Hopp b3183e
  		/* Goto beginning of the repeated atom */
Karsten Hopp b3183e
! 		restore_parse_state(&old_state);
Karsten Hopp b3183e
  		old_post_pos = (int)(post_ptr - post_start);
Karsten Hopp b3183e
  		if (nfa_regatom() == FAIL)
Karsten Hopp b3183e
  		    return FAIL;
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 1486,1492 ****
Karsten Hopp b3183e
  	    }
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  	    /* Go to just after the repeated atom and the \{} */
Karsten Hopp b3183e
! 	    regparse = new_regparse;
Karsten Hopp b3183e
  	    curchr = -1;
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  	    break;
Karsten Hopp b3183e
--- 1480,1486 ----
Karsten Hopp b3183e
  	    }
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  	    /* Go to just after the repeated atom and the \{} */
Karsten Hopp b3183e
! 	    restore_parse_state(&new_state);
Karsten Hopp b3183e
  	    curchr = -1;
Karsten Hopp b3183e
  
Karsten Hopp b3183e
  	    break;
Karsten Hopp b3183e
*** ../vim-7.3.1086/src/testdir/test64.in	2013-06-01 13:24:19.000000000 +0200
Karsten Hopp b3183e
--- src/testdir/test64.in	2013-06-01 14:36:15.000000000 +0200
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 188,193 ****
Karsten Hopp b3183e
--- 188,197 ----
Karsten Hopp b3183e
  :call add(tl, [2, 'a\{,0}', 'oidfguih iuhi hiu aaaa', ''])
Karsten Hopp b3183e
  :call add(tl, [2, 'a\{,5}', 'abcd', 'a'])
Karsten Hopp b3183e
  :call add(tl, [2, 'a\{,5}', 'aaaaaaaaaa', 'aaaaa'])
Karsten Hopp b3183e
+ :" leading star as normal char when \{} follows
Karsten Hopp b3183e
+ :call add(tl, [2, '^*\{4,}$', '***'])
Karsten Hopp b3183e
+ :call add(tl, [2, '^*\{4,}$', '****', '****'])
Karsten Hopp b3183e
+ :call add(tl, [2, '^*\{4,}$', '*****', '*****'])
Karsten Hopp b3183e
  :" same thing as 'a*'
Karsten Hopp b3183e
  :call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', ''])
Karsten Hopp b3183e
  :call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa'])
Karsten Hopp b3183e
*** ../vim-7.3.1086/src/testdir/test64.ok	2013-06-01 13:24:19.000000000 +0200
Karsten Hopp b3183e
--- src/testdir/test64.ok	2013-06-01 14:36:39.000000000 +0200
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 407,412 ****
Karsten Hopp b3183e
--- 407,421 ----
Karsten Hopp b3183e
  OK 0 - a\{,5}
Karsten Hopp b3183e
  OK 1 - a\{,5}
Karsten Hopp b3183e
  OK 2 - a\{,5}
Karsten Hopp b3183e
+ OK 0 - ^*\{4,}$
Karsten Hopp b3183e
+ OK 1 - ^*\{4,}$
Karsten Hopp b3183e
+ OK 2 - ^*\{4,}$
Karsten Hopp b3183e
+ OK 0 - ^*\{4,}$
Karsten Hopp b3183e
+ OK 1 - ^*\{4,}$
Karsten Hopp b3183e
+ OK 2 - ^*\{4,}$
Karsten Hopp b3183e
+ OK 0 - ^*\{4,}$
Karsten Hopp b3183e
+ OK 1 - ^*\{4,}$
Karsten Hopp b3183e
+ OK 2 - ^*\{4,}$
Karsten Hopp b3183e
  OK 0 - a\{}
Karsten Hopp b3183e
  OK 1 - a\{}
Karsten Hopp b3183e
  OK 2 - a\{}
Karsten Hopp b3183e
*** ../vim-7.3.1086/src/version.c	2013-06-01 13:24:19.000000000 +0200
Karsten Hopp b3183e
--- src/version.c	2013-06-01 14:37:37.000000000 +0200
Karsten Hopp b3183e
***************
Karsten Hopp b3183e
*** 730,731 ****
Karsten Hopp b3183e
--- 730,733 ----
Karsten Hopp b3183e
  {   /* Add new patch number below this line */
Karsten Hopp b3183e
+ /**/
Karsten Hopp b3183e
+     1087,
Karsten Hopp b3183e
  /**/
Karsten Hopp b3183e
Karsten Hopp b3183e
-- 
Karsten Hopp b3183e
Change is inevitable, except from a vending machine.
Karsten Hopp b3183e
Karsten Hopp b3183e
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp b3183e
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp b3183e
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp b3183e
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///