Blob Blame History Raw
To: vim_dev@googlegroups.com
Subject: Patch 7.3.1147
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 7.3.1147
Problem:    New regexp engine: regstart is only used to find the first match.
Solution:   Use regstart whenever adding the start state.
Files:	    src/regexp_nfa.c


*** ../vim-7.3.1146/src/regexp_nfa.c	2013-06-08 13:33:32.000000000 +0200
--- src/regexp_nfa.c	2013-06-08 14:37:36.000000000 +0200
***************
*** 4153,4158 ****
--- 4153,4159 ----
  }
  
  static int failure_chance __ARGS((nfa_state_T *state, int depth));
+ static int skip_to_start __ARGS((int c, colnr_T *colp));
  
  /*
   * Estimate the chance of a match with "state" failing.
***************
*** 4305,4310 ****
--- 4306,4336 ----
  }
  
  /*
+  * Skip until the char "c" we know a match must start with.
+  */
+     static int
+ skip_to_start(c, colp)
+     int		c;
+     colnr_T	*colp;
+ {
+     char_u *s;
+ 
+     /* Used often, do some work to avoid call overhead. */
+     if (!ireg_ic
+ #ifdef FEAT_MBYTE
+ 		&& !has_mbyte
+ #endif
+ 		)
+ 	s = vim_strbyte(regline + *colp, c);
+     else
+ 	s = cstrchr(regline + *colp, c);
+     if (s == NULL)
+ 	return FAIL;
+     *colp = (int)(s - regline);
+     return OK;
+ }
+ 
+ /*
   * Main matching routine.
   *
   * Run NFA to determine whether it matches reginput.
***************
*** 5449,5460 ****
  	     * the first MOPEN. */
  	    if (toplevel)
  	    {
! 		if (REG_MULTI)
! 		    m->norm.list.multi[0].start.col =
  					 (colnr_T)(reginput - regline) + clen;
! 		else
! 		    m->norm.list.line[0].start = reginput + clen;
! 		addstate(nextlist, start->out, m, clen);
  	    }
  	    else
  		addstate(nextlist, start, m, clen);
--- 5475,5524 ----
  	     * the first MOPEN. */
  	    if (toplevel)
  	    {
! 		int add = TRUE;
! 		int c;
! 
! 		if (prog->regstart != NUL && clen != 0)
! 		{
! 		    if (nextlist->n == 0)
! 		    {
! 			colnr_T col = (colnr_T)(reginput - regline) + clen;
! 
! 			/* Nextlist is empty, we can skip ahead to the
! 			 * character that must appear at the start. */
! 			if (skip_to_start(prog->regstart, &col) == FAIL)
! 			    break;
! #ifdef ENABLE_LOG
! 			fprintf(log_fd, "  Skipping ahead %d bytes to regstart\n",
! 				col - ((colnr_T)(reginput - regline) + clen));
! #endif
! 			reginput = regline + col - clen;
! 		    }
! 		    else
! 		    {
! 			/* Checking if the required start character matches is
! 			 * cheaper than adding a state that won't match. */
! 			c = PTR2CHAR(reginput + clen);
! 			if (c != prog->regstart && (!ireg_ic || MB_TOLOWER(c)
! 					       != MB_TOLOWER(prog->regstart)))
! 			{
! #ifdef ENABLE_LOG
! 			    fprintf(log_fd, "  Skipping start state, regstart does not match\n");
! #endif
! 			    add = FALSE;
! 			}
! 		    }
! 		}
! 
! 		if (add)
! 		{
! 		    if (REG_MULTI)
! 			m->norm.list.multi[0].start.col =
  					 (colnr_T)(reginput - regline) + clen;
! 		    else
! 			m->norm.list.line[0].start = reginput + clen;
! 		    addstate(nextlist, start->out, m, clen);
! 		}
  	    }
  	    else
  		addstate(nextlist, start, m, clen);
***************
*** 5701,5723 ****
  	return 0L;
  
      if (prog->regstart != NUL)
!     {
! 	char_u *s;
! 
! 	/* Skip until the char we know it must start with.
! 	 * Used often, do some work to avoid call overhead. */
! 	if (!ireg_ic
! #ifdef FEAT_MBYTE
! 		    && !has_mbyte
! #endif
! 		    )
! 	    s = vim_strbyte(regline + col, prog->regstart);
! 	else
! 	    s = cstrchr(regline + col, prog->regstart);
! 	if (s == NULL)
  	    return 0L;
- 	col = (int)(s - regline);
-     }
  
      /* If the start column is past the maximum column: no need to try. */
      if (ireg_maxcol > 0 && col >= ireg_maxcol)
--- 5765,5774 ----
  	return 0L;
  
      if (prog->regstart != NUL)
! 	/* Skip ahead until a character we know the match must start with.
! 	 * When there is none there is no match. */
! 	if (skip_to_start(prog->regstart, &col) == FAIL)
  	    return 0L;
  
      /* If the start column is past the maximum column: no need to try. */
      if (ireg_maxcol > 0 && col >= ireg_maxcol)
*** ../vim-7.3.1146/src/version.c	2013-06-08 13:33:32.000000000 +0200
--- src/version.c	2013-06-08 14:35:54.000000000 +0200
***************
*** 730,731 ****
--- 730,733 ----
  {   /* Add new patch number below this line */
+ /**/
+     1147,
  /**/

-- 
Nobody will ever need more than 640 kB RAM.
		-- Bill Gates, 1983
Windows 98 requires 16 MB RAM.
		-- Bill Gates, 1999
Logical conclusion: Nobody will ever need Windows 98.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///