diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c index f22b7abd79e..07cd71a3b24 100644 --- a/usr.bin/grep/util.c +++ b/usr.bin/grep/util.c @@ -252,6 +252,16 @@ static bool procmatches(struct mprintc *mc, struct parsec *pc, bool matched) { + if (mflag && mcount <= 0) { + /* + * We already hit our match count, but we need to keep dumping + * lines until we've lost our tail. + */ + grep_printline(&pc->ln, '-'); + mc->tail--; + return (mc->tail != 0); + } + /* * XXX TODO: This should loop over pc->matches and handle things on a * line-by-line basis, setting up a `struct str` as needed. @@ -264,8 +274,9 @@ procmatches(struct mprintc *mc, struct parsec *pc, bool matched) if (mflag) { /* XXX TODO: Decrement by number of matched lines */ mcount -= 1; - if (mcount <= 0) - return (false); + if (mcount <= 0) { + return (mc->tail != 0); + } } } else if (mc->doctx) procmatch_nomatch(mc, pc); @@ -357,6 +368,15 @@ procfile(const char *fn) return (0); } + if (mflag && mcount <= 0) { + /* + * Short-circuit, already hit match count and now we're + * just picking up any remaining pieces. + */ + if (!procmatches(&mc, &pc, false)) + break; + continue; + } line_matched = procline(&pc) == !vflag; if (line_matched) ++lines;