Subject: bug#24457: [PATCH] sed: use dfa matcher for regex with anchor

From: Norihiro Tanaka <[email-masked]>
Date: Sun, 18 Sep 2016 18:00:38 +0900

Recently, dfa module started to support that newline_anchor option is
set to false.

sed could not use dfa fully up to now, as sed sets newline_anchor to
false in many cases.

This change is that sed uses dfa even if newline_anchor option is false.
From 16e59d67e7b8710985517f8c8e5a2abbb3424371 Mon Sep 17 00:00:00 2001
From: Norihiro Tanaka <[email-masked]>
Date: Mon, 12 Sep 2016 23:08:31 +0900
Subject: [PATCH] sed: use dfa matcher for regex with anchor

* sed/regex.c (compile_regex_1, match_regex): Use dfa matcher for regex with anchor.
* testsuite/locale.mk: Add new test.
* testsuite/Makefile.tests:
* testsuite/anchor.good: New test-related files.
* testsuite/anchor.inp:
* testsuite/anchor.sed:
---
 sed/regexp.c             |    9 +++++----
 testsuite/Makefile.tests |    2 +-
 testsuite/anchor.good    |    3 +++
 testsuite/anchor.inp     |    1 +
 testsuite/anchor.sed     |    7 +++++++
 testsuite/local.mk       |    6 +++++-
 6 files changed, 22 insertions(+), 6 deletions(-)
 create mode 100644 testsuite/anchor.good
 create mode 100644 testsuite/anchor.inp
 create mode 100644 testsuite/anchor.sed

diff --git a/sed/regexp.c b/sed/regexp.c
index 1eecd73..b87bb74 100644
--- a/sed/regexp.c
+++ b/sed/regexp.c
@@ -142,7 +142,9 @@ compile_regex_1 (struct regex *new_regex, int needed_sub)
       bad_prog(buf);
     }
 
-  int dfaopts = (new_regex->flags & REG_ICASE) ? DFA_CASE_FOLD : 0;
+  int dfaopts = 0;
+  dfaopts |= (new_regex->flags & REG_ICASE) ? DFA_CASE_FOLD : 0;
+  dfaopts |= (new_regex->flags & REG_NEWLINE) ? 0 : DFA_ANCHOR;
   new_regex->dfa = dfaalloc ();
   dfasyntax (new_regex->dfa, &localeinfo, syntax, dfaopts);
   dfacomp (new_regex->re, new_regex->sz, new_regex->dfa, 1);
@@ -263,15 +265,14 @@ match_regex(struct regex *regex, char *buf, size_t buflen,
       if (superset && !dfaexec (superset, buf, buf + buflen, true, NULL, NULL))
         return 0;
 
-      if ((!regsize && regex->pattern.newline_anchor)
-          || (!superset && dfaisfast (regex->dfa)))
+      if (!regsize || (!superset && dfaisfast (regex->dfa)))
         {
           bool backref = false;
 
           if (!dfaexec (regex->dfa, buf, buf + buflen, true, NULL, &backref))
             return 0;
 
-          if (!regsize && regex->pattern.newline_anchor && !backref)
+          if (!regsize && !backref)
             return 1;
         }
     }
diff --git a/testsuite/Makefile.tests b/testsuite/Makefile.tests
index ab48bc1..debda6e 100644
--- a/testsuite/Makefile.tests
+++ b/testsuite/Makefile.tests
@@ -21,7 +21,7 @@ SKIP = :>$@.skip; exit 77
 enable sep inclib 8bit 8to7 newjis xabcx dollar noeol bkslashes \
 numsub head madding mac-mf empty xbxcx xbxcx3 recall recall2 xemacs \
 appquit fasts uniq manis linecnt khadafy allsub flipcase space modulo \
-y-bracket y-newline y-zero insert brackets amp-escape::
+y-bracket y-newline y-zero insert brackets amp-escape anchor::
 	$(SEDENV) $(SED) -f $(srcdir)/$@.sed \
 		< $(srcdir)/$@.inp | $(TR) -d \\r > $@.out
 	$(CMP) $(srcdir)/$@.good $@.out
diff --git a/testsuite/anchor.good b/testsuite/anchor.good
new file mode 100644
index 0000000..91e35e3
--- /dev/null
+++ b/testsuite/anchor.good
@@ -0,0 +1,3 @@
+X line1 B
+C line2 D
+E line3 X
diff --git a/testsuite/anchor.inp b/testsuite/anchor.inp
new file mode 100644
index 0000000..432820a
--- /dev/null
+++ b/testsuite/anchor.inp
@@ -0,0 +1 @@
+A line1 B,C line2 D,E line3 F
diff --git a/testsuite/anchor.sed b/testsuite/anchor.sed
new file mode 100644
index 0000000..9048a2f
--- /dev/null
+++ b/testsuite/anchor.sed
@@ -0,0 +1,7 @@
+s/,/\n/g
+/^A/s/A/X/
+/B$/s/B/X/
+/^C/s/C/X/
+/D$/s/D/X/
+/^E/s/E/X/
+/F$/s/F/X/
diff --git a/testsuite/local.mk b/testsuite/local.mk
index 6ae11e4..167e106 100644
--- a/testsuite/local.mk
+++ b/testsuite/local.mk
@@ -107,7 +107,8 @@ SEDTESTS += testsuite/appquit testsuite/enable testsuite/sep		\
         testsuite/badenc testsuite/inplace-hold testsuite/brackets	\
         testsuite/amp-escape testsuite/help testsuite/file		\
         testsuite/quiet testsuite/factor testsuite/binary3		\
-        testsuite/binary2 testsuite/binary testsuite/dc
+        testsuite/binary2 testsuite/binary testsuite/dc			\
+	testsuite/anchor
 
 # Note that the first lines are statements.  They ensure that environment
 # variables that can perturb tests are unset or set to expected values.
@@ -184,6 +185,9 @@ EXTRA_DIST += \
 	testsuite/amp-escape.good \
 	testsuite/amp-escape.inp \
 	testsuite/amp-escape.sed \
+	testsuite/anchor.good \
+	testsuite/anchor.inp \
+	testsuite/anchor.sed \
 	testsuite/appquit.good \
 	testsuite/appquit.inp \
 	testsuite/appquit.sed \
-- 
1.7.1