Subject: [PATCH] grep: fix grep -F -x -o outputs extra newlines
From: Norihiro Tanaka <[email-masked]>
To: [email-masked]
Date: Wed, 12 Nov 2014 22:54:36 +0900
List-Id: <debbugs-submit.debbugs.gnu.org>

grep -F -x -o outputs extra newlines as following.

$ printf 'abc\nabc\n' | grep -F -x -o abc
abc

abc

$ 

(expected)
$ printf 'abc\nabc\n' | grep -F -x -o abc
abc
abc
$ 

Jim, could you take this bug fix in next release?

From a4dc9c14dae6d83ab14891ee1d85a41f4d24d684 Mon Sep 17 00:00:00 2001
From: Norihiro Tanaka <[email-masked]>
Date: Wed, 12 Nov 2014 22:25:18 +0900
Subject: [PATCH] grep: fix grep -F -x -o outputs extra newlines

* src/kwsearch.c: Fix grep -F -x -o outputs extra newlines.
* tests/match-lines: Add a new test.
---
 NEWS           | 3 +++
 src/kwsearch.c | 7 +++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index c465162..663b422 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,9 @@ GNU grep NEWS                                    -*- outline -*-
   implying that the match, "10" was on line 1.
   [bug introduced in grep-2.19]
 
+  grep -F -x -o no longer output extra newlines.
+  [bug introduced in grep-2.19]
+
   grep in a non-UTF8 multibyte locale could mistakenly match in the middle
   of a multibyte character when using a '^'-anchored alternate in a pattern,
   leading it to print non-matching lines.  [bug present since "the beginning"]
diff --git a/src/kwsearch.c b/src/kwsearch.c
index 6bd516a..aa965f6 100644
--- a/src/kwsearch.c
+++ b/src/kwsearch.c
@@ -129,7 +129,7 @@ Fexecute (char const *buf, size_t size, size_t *match_size,
                                buf + size - beg + match_lines, &kwsmatch);
       if (offset == (size_t) -1)
         goto failure;
-      len = kwsmatch.size[0] - match_lines;
+      len = kwsmatch.size[0] - 2 * match_lines;
       if (!match_lines && MB_CUR_MAX > 1 && !using_utf8 ()
           && mb_goback (&mb_start, beg + offset, buf + size) != 0)
         {
@@ -142,7 +142,10 @@ Fexecute (char const *buf, size_t size, size_t *match_size,
       if (start_ptr && !match_words)
         goto success_in_beg_and_len;
       if (match_lines)
-        goto success_in_beg_and_len;
+        {
+          len += start_ptr == NULL;
+          goto success_in_beg_and_len;
+        }
       if (match_words)
         for (try = beg; ; )
           {
-- 
2.1.3