Blame SOURCES/grep-2.20-long-pattern-speedup.patch

dd21a5
diff --git a/src/dfa.c b/src/dfa.c
dd21a5
index b9b7103..cd11db6 100644
dd21a5
--- a/src/dfa.c
dd21a5
+++ b/src/dfa.c
dd21a5
@@ -3894,13 +3894,13 @@ struct must
dd21a5
 };
dd21a5
 
dd21a5
 static must *
dd21a5
-allocmust (must *mp)
dd21a5
+allocmust (must *mp, size_t size)
dd21a5
 {
dd21a5
   must *new_mp = xmalloc (sizeof *new_mp);
dd21a5
   new_mp->in = xzalloc (sizeof *new_mp->in);
dd21a5
-  new_mp->left = xzalloc (2);
dd21a5
-  new_mp->right = xzalloc (2);
dd21a5
-  new_mp->is = xzalloc (2);
dd21a5
+  new_mp->left = xzalloc (size);
dd21a5
+  new_mp->right = xzalloc (size);
dd21a5
+  new_mp->is = xzalloc (size);
dd21a5
   new_mp->begline = false;
dd21a5
   new_mp->endline = false;
dd21a5
   new_mp->prev = mp;
dd21a5
@@ -3933,24 +3933,23 @@ dfamust (struct dfa *d)
dd21a5
 {
dd21a5
   must *mp = NULL;
dd21a5
   char const *result = "";
dd21a5
-  size_t ri;
dd21a5
   size_t i;
dd21a5
   bool exact = false;
dd21a5
   bool begline = false;
dd21a5
   bool endline = false;
dd21a5
   struct dfamust *dm;
dd21a5
 
dd21a5
-  for (ri = 0; ri < d->tindex; ++ri)
dd21a5
+  for (size_t ri = 0; ri < d->tindex; ++ri)
dd21a5
     {
dd21a5
       token t = d->tokens[ri];
dd21a5
       switch (t)
dd21a5
         {
dd21a5
         case BEGLINE:
dd21a5
-          mp = allocmust (mp);
dd21a5
+          mp = allocmust (mp, 2);
dd21a5
           mp->begline = true;
dd21a5
           break;
dd21a5
         case ENDLINE:
dd21a5
-          mp = allocmust (mp);
dd21a5
+          mp = allocmust (mp, 2);
dd21a5
           mp->endline = true;
dd21a5
           break;
dd21a5
         case LPAREN:
dd21a5
@@ -3965,7 +3964,7 @@ dfamust (struct dfa *d)
dd21a5
         case BACKREF:
dd21a5
         case ANYCHAR:
dd21a5
         case MBCSET:
dd21a5
-          mp = allocmust (mp);
dd21a5
+          mp = allocmust (mp, 2);
dd21a5
           break;
dd21a5
 
dd21a5
         case STAR:
dd21a5
@@ -4082,7 +4081,6 @@ dfamust (struct dfa *d)
dd21a5
           goto done;
dd21a5
 
dd21a5
         default:
dd21a5
-          mp = allocmust (mp);
dd21a5
           if (CSET <= t)
dd21a5
             {
dd21a5
               /* If T is a singleton, or if case-folding in a unibyte
dd21a5
@@ -4095,7 +4093,10 @@ dfamust (struct dfa *d)
dd21a5
                 if (tstbit (j, *ccl))
dd21a5
                   break;
dd21a5
               if (! (j < NOTCHAR))
dd21a5
-                break;
dd21a5
+                {
dd21a5
+                  mp = allocmust (mp, 2);
dd21a5
+                  break;
dd21a5
+                }
dd21a5
               t = j;
dd21a5
               while (++j < NOTCHAR)
dd21a5
                 if (tstbit (j, *ccl)
dd21a5
@@ -4103,12 +4104,36 @@ dfamust (struct dfa *d)
dd21a5
                           && toupper (j) == toupper (t)))
dd21a5
                   break;
dd21a5
               if (j < NOTCHAR)
dd21a5
-                break;
dd21a5
+                {
dd21a5
+                  mp = allocmust (mp, 2);
dd21a5
+                  break;
dd21a5
+                }
dd21a5
             }
dd21a5
+
dd21a5
+          size_t rj = ri + 2;
dd21a5
+          if (d->tokens[ri + 1] == CAT)
dd21a5
+            {
dd21a5
+              for (; rj < d->tindex - 1; rj += 2)
dd21a5
+                {
dd21a5
+                  if ((rj != ri && (d->tokens[rj] <= 0
dd21a5
+                                    || NOTCHAR <= d->tokens[rj]))
dd21a5
+                      || d->tokens[rj + 1] != CAT)
dd21a5
+                    break;
dd21a5
+                }
dd21a5
+            }
dd21a5
+          mp = allocmust (mp, ((rj - ri) >> 1) + 1);
dd21a5
           mp->is[0] = mp->left[0] = mp->right[0]
dd21a5
             = case_fold && !d->multibyte ? toupper (t) : t;
dd21a5
-          mp->is[1] = mp->left[1] = mp->right[1] = '\0';
dd21a5
-          mp->in = enlist (mp->in, mp->is, 1);
dd21a5
+
dd21a5
+          for (i = 1; ri + 2 < rj; i++)
dd21a5
+            {
dd21a5
+              ri += 2;
dd21a5
+              t = d->tokens[ri];
dd21a5
+              mp->is[i] = mp->left[i] = mp->right[i]
dd21a5
+                = case_fold && MB_CUR_MAX == 1 ? toupper (t) : t;
dd21a5
+            }
dd21a5
+          mp->is[i] = mp->left[i] = mp->right[i] = '\0';
dd21a5
+          mp->in = enlist (mp->in, mp->is, i - 1);
dd21a5
           break;
dd21a5
         }
dd21a5
     }