procline: only reduce mcount once per line, not once per match.
authormillert <millert@openbsd.org>
Wed, 15 Nov 2023 00:50:43 +0000 (00:50 +0000)
committermillert <millert@openbsd.org>
Wed, 15 Nov 2023 00:50:43 +0000 (00:50 +0000)
This makes "grep -m" behave like GNU grep (where the -m option
originated).  From Crystal Kolipe.

usr.bin/grep/grep.1
usr.bin/grep/util.c

index 7b5d15b..3fe35fb 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: grep.1,v 1.52 2023/01/04 07:33:00 jmc Exp $
+.\"    $OpenBSD: grep.1,v 1.53 2023/11/15 00:50:43 millert Exp $
 .\" Copyright (c) 1980, 1990, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
@@ -28,7 +28,7 @@
 .\"
 .\"    @(#)grep.1      8.3 (Berkeley) 4/18/94
 .\"
-.Dd $Mdocdate: January 4 2023 $
+.Dd $Mdocdate: November 15 2023 $
 .Dt GREP 1
 .Os
 .Sh NAME
@@ -222,9 +222,9 @@ If the standard input is searched, the string
 .Dq (standard input)
 is written.
 .It Fl m Ar num
-Stop after
+Stop after finding at least one match on
 .Ar num
-matches.
+different lines.
 .It Fl n
 Each output line is preceded by its relative line number in the file,
 starting at line 1.
index c79e306..8b423c7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: util.c,v 1.67 2022/07/12 18:09:31 op Exp $    */
+/*     $OpenBSD: util.c,v 1.68 2023/11/15 00:50:43 millert Exp $       */
 
 /*-
  * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
@@ -197,7 +197,7 @@ static int
 procline(str_t *l, int nottext)
 {
        regmatch_t      pmatch = { 0 };
-       int             c, i, r;
+       int             c, i, r, counted;
        regoff_t        offset;
 
        /* size_t will be converted to regoff_t. ssize_t is guaranteed to fit
@@ -208,6 +208,7 @@ procline(str_t *l, int nottext)
 
        c = 0;
        i = 0;
+       counted = 0;
        if (matchall) {
                c = 1;
                goto print;
@@ -251,9 +252,11 @@ print:
        if (vflag)
                c = !c;
 
-       /* Count the matches if we have a match limit */
-       if (mflag)
+       /* Count the matches if there is a match limit (but only once). */
+       if (mflag && !counted) {
                mcount -= c;
+               counted = 1;
+       }
 
        if (c && binbehave == BIN_FILE_BIN && nottext)
                return c; /* Binary file */