]> granicus.if.org Git - vim/commitdiff
updated for version 7.3.1147 v7.3.1147
authorBram Moolenaar <Bram@vim.org>
Sat, 8 Jun 2013 12:38:27 +0000 (14:38 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 8 Jun 2013 12:38:27 +0000 (14:38 +0200)
Problem:    New regexp engine: regstart is only used to find the first match.
Solution:   Use regstart whenever adding the start state.

src/regexp_nfa.c
src/version.c

index 116ea67525d5fd0550ea8851588c8b519cc82048..b03d09aeb7e1b6d91e1c237b5957e4a5c2673a77 100644 (file)
@@ -4153,6 +4153,7 @@ recursive_regmatch(state, prog, submatch, m, listids)
 }
 
 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.
@@ -4304,6 +4305,31 @@ failure_chance(state, depth)
     return 50;
 }
 
+/*
+ * 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.
  *
@@ -5449,12 +5475,50 @@ nfa_regmatch(prog, start, submatch, m)
             * the first MOPEN. */
            if (toplevel)
            {
-               if (REG_MULTI)
-                   m->norm.list.multi[0].start.col =
+               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
+                       m->norm.list.line[0].start = reginput + clen;
+                   addstate(nextlist, start->out, m, clen);
+               }
            }
            else
                addstate(nextlist, start, m, clen);
@@ -5701,23 +5765,10 @@ nfa_regexec_both(line, startcol)
        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)
+       /* 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;
-       col = (int)(s - regline);
-    }
 
     /* If the start column is past the maximum column: no need to try. */
     if (ireg_maxcol > 0 && col >= ireg_maxcol)
index ed3fcd719800a33504b25222e0b276dc2283b613..f83750188fca9540c8acbd75609eae6647f5e690 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1147,
 /**/
     1146,
 /**/