Subject: Re: bug#17448: [PATCH] grep: retry DFA superset after matched with multiple lines by it

From: Paul Eggert <[email-masked]>
Date: Fri, 09 May 2014 14:52:58 -0700

Thanks, I installed that, along with the attached patch which improves 
it slightly by avoiding a test of the returned value of memrchr in a 
context where memrchr cannot return NULL, plus I redid the while-control 
to make it a bit clearer when the loop terminates.
From ad6ca9bb54ae2a9811c889c990ea67d67919a4f4 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Fri, 9 May 2014 14:48:47 -0700
Subject: [PATCH] grep: minor improvements to retry-DFA-superset patch

* src/dfasearch.c (EGexecute): Avoid unnecessary test in a context
where memrchr cannot return a null pointer.
---
 src/dfasearch.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/src/dfasearch.c b/src/dfasearch.c
index 9fb7449..77b4e3e 100644
--- a/src/dfasearch.c
+++ b/src/dfasearch.c
@@ -284,23 +284,18 @@ EGexecute (char const *buf, size_t size, size_t *match_size,
           /* Try matching with the superset of DFA, if it's defined.  */
           if (superset && !exact_kwset_match)
             {
-              while (true)
+              /* Keep using the superset while it reports multiline
+                 potential matches; this is more likely to be fast
+                 than falling back to KWset would be.  */
+              while ((next_beg = dfaexec (superset, dfa_beg, (char *) end, 1,
+                                          &count, NULL))
+                     && next_beg != end
+                     && count != 0)
                 {
-                  next_beg = dfaexec (superset, dfa_beg, (char *) end, 1,
-                                      &count, NULL);
-                  /* If there's no match, or if we've matched the sentinel,
-                     we're done.  */
-                  if (next_beg == NULL || next_beg == end)
-                    break;
-
-                  if (count == 0)
-                    break;
+                  /* Try to match in just one line.  */
                   count = 0;
-
-                  /* If dfaexec may match in multiple lines, try to
-                     match in one line.  */
                   beg = memrchr (buf, eol, next_beg - buf);
-                  beg = beg ? beg + 1 : buf;
+                  beg++;
                   dfa_beg = beg;
                 }
               if (next_beg == NULL || next_beg == end)
@@ -310,6 +305,7 @@ EGexecute (char const *buf, size_t size, size_t *match_size,
               end = memchr (next_beg, eol, buflim - next_beg);
               end = end ? end + 1 : buflim;
             }
+
           /* Try matching with DFA.  */
           next_beg = dfaexec (dfa, dfa_beg, (char *) end, 0, &count, &backref);
 
-- 
1.9.0