summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-06-21 13:59:57 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2017-06-21 19:01:00 -0700
commitb0dc886d9c1fb5df275b5ea9a95c061a5931e50b (patch)
treec07877e8e1d0927ec8476e027701a3457568f6cc
parentc57fba2604b4e1095e869de6c844d8c3d973814f (diff)
downloadgrep-b0dc886d9c1fb5df275b5ea9a95c061a5931e50b.tar.gz
grep: -m no longer cuts off trailing context
Problem reported by Markus Jochim (Bug#26254). * NEWS, doc/grep.texi (General Output Control): Document this. * src/grep.c (prpending): Selected lines no longer cut off context. (usage): Say "selected" instead of "matching", where appropriate. * tests/foad1, tests/max-count-vs-context, tests/yesno: Adjust to match new behavior.
-rw-r--r--NEWS5
-rw-r--r--doc/grep.texi10
-rw-r--r--src/grep.c29
-rwxr-xr-xtests/foad18
-rwxr-xr-xtests/max-count-vs-context2
-rwxr-xr-xtests/yesno8
6 files changed, 28 insertions, 34 deletions
diff --git a/NEWS b/NEWS
index 0a8cbbc9..bd2c00a6 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,11 @@ GNU grep NEWS -*- outline -*-
** Changes in behavior
+ Context no longer excludes selected lines omitted because of -m.
+ For example, 'grep "^" -m1 -A1' now outputs the first two input
+ lines, not just the first line. This fixes a glitch that has been
+ present since -m was added in grep 2.5.
+
The following changes affect only MS-Windows platforms. First, the
--binary (-U) option now governs whether binary I/O is used, instead
of a heuristic that was sometimes incorrect. Second, the
diff --git a/doc/grep.texi b/doc/grep.texi
index 728c039d..334a0593 100644
--- a/doc/grep.texi
+++ b/doc/grep.texi
@@ -311,11 +311,11 @@ The scanning of each file stops on the first match.
@opindex -m
@opindex --max-count
@cindex max-count
-Stop reading a file after @var{num} matching lines.
+Stop after the first @var{num} selected lines.
If the input is standard input from a regular file,
-and @var{num} matching lines are output,
+and @var{num} selected lines are output,
@command{grep} ensures that the standard input is positioned
-just after the last matching line before exiting,
+just after the last selected line before exiting,
regardless of the presence of trailing context lines.
This enables a calling process to resume a search.
For example, the following shell script makes use of it:
@@ -340,10 +340,8 @@ done
@end example
@cindex context lines
-When @command{grep} stops after @var{num} matching lines,
+When @command{grep} stops after @var{num} selected lines,
it outputs any trailing context lines.
-Since context does not include matching lines,
-@command{grep} will stop when it encounters another matching line.
When the @option{-c} or @option{--count} option is also used,
@command{grep} does not output a count greater than @var{num}.
When the @option{-v} or @option{--invert-match} option is also used,
diff --git a/src/grep.c b/src/grep.c
index bc2599f3..8d22aec3 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -1011,7 +1011,7 @@ static intmax_t out_before; /* Lines of leading context. */
static intmax_t out_after; /* Lines of trailing context. */
static bool count_matches; /* Count matching lines. */
static bool no_filenames; /* Suppress file names. */
-static intmax_t max_count; /* Stop after outputting this many
+static intmax_t max_count; /* Max number of selected
lines from an input file. */
static bool line_buffered; /* Use line buffering. */
static char *label = NULL; /* Fake filename for stdin */
@@ -1023,7 +1023,7 @@ static char const *lastnl; /* Pointer after last newline counted. */
static char *lastout; /* Pointer after last character output;
NULL if no character has been output
or if it's conceptually before bufbeg. */
-static intmax_t outleft; /* Maximum number of lines to be output. */
+static intmax_t outleft; /* Maximum number of selected lines. */
static intmax_t pending; /* Pending lines of output.
Always kept 0 if out_quiet is true. */
static bool done_on_match; /* Stop scanning file on first match. */
@@ -1276,25 +1276,16 @@ prline (char *beg, char *lim, char sep)
lastout = lim;
}
-/* Print pending lines of trailing context prior to LIM. Trailing context ends
- at the next matching line when OUTLEFT is 0. */
+/* Print pending lines of trailing context prior to LIM. */
static void
prpending (char const *lim)
{
if (!lastout)
lastout = bufbeg;
- while (pending > 0 && lastout < lim)
+ for (; 0 < pending && lastout < lim; pending--)
{
char *nl = memchr (lastout, eolbyte, lim - lastout);
- size_t match_size;
- --pending;
- if (outleft
- || ((execute (compiled_pattern, lastout, nl + 1 - lastout,
- &match_size, NULL) == (size_t) -1)
- == !out_invert))
- prline (lastout, nl + 1, SEP_CHAR_REJECTED);
- else
- pending = 0;
+ prline (lastout, nl + 1, SEP_CHAR_REJECTED);
}
}
@@ -1949,11 +1940,11 @@ Miscellaneous:\n\
printf (_("\
\n\
Output control:\n\
- -m, --max-count=NUM stop after NUM matches\n\
+ -m, --max-count=NUM stop after NUM selected lines\n\
-b, --byte-offset print the byte offset with output lines\n\
-n, --line-number print line number with output lines\n\
--line-buffered flush output on every line\n\
- -H, --with-filename print the file name for each match\n\
+ -H, --with-filename print file name with output lines\n\
-h, --no-filename suppress the file name prefix on output\n\
--label=LABEL use LABEL as the standard input file name prefix\n\
"));
@@ -1981,9 +1972,9 @@ Output control:\n\
--exclude-dir=PATTERN directories that match PATTERN will be skipped.\n\
"));
printf (_("\
- -L, --files-without-match print only names of FILEs containing no match\n\
- -l, --files-with-matches print only names of FILEs containing matches\n\
- -c, --count print only a count of matching lines per FILE\n\
+ -L, --files-without-match print only names of FILEs with no selected lines\n\
+ -l, --files-with-matches print only names of FILEs with selected lines\n\
+ -c, --count print only a count of selected lines per FILE\n\
-T, --initial-tab make tabs line up (if needed)\n\
-Z, --null print 0 byte after FILE name\n"));
printf (_("\
diff --git a/tests/foad1 b/tests/foad1
index 0163f1a1..e3999819 100755
--- a/tests/foad1
+++ b/tests/foad1
@@ -93,12 +93,12 @@ grep_test "wordword/" "${CB}word${CE}word/" "\<word" --color=always
grep_test "4/40/" "4/40/" "^4$" -m1 -A99
grep_test "4/04/" "4/04/" "^4$" -m1 -A99
grep_test "4/444/" "4/444/" "^4$" -m1 -A99
-grep_test "4/40/" "4/" "^4" -m1 -A99
+grep_test "4/40/" "4/40/" "^4" -m1 -A99
grep_test "4/04/" "4/04/" "^4" -m1 -A99
-grep_test "4/444/" "4/" "^4" -m1 -A99
+grep_test "4/444/" "4/444/" "^4" -m1 -A99
grep_test "4/40/" "4/40/" "4$" -m1 -A99
-grep_test "4/04/" "4/" "4$" -m1 -A99
-grep_test "4/444/" "4/" "4$" -m1 -A99
+grep_test "4/04/" "4/04/" "4$" -m1 -A99
+grep_test "4/444/" "4/444/" "4$" -m1 -A99
# Test for "-F -w" bugs. Thanks to Gordon Lack for these two.
diff --git a/tests/max-count-vs-context b/tests/max-count-vs-context
index 5633dd6a..e80c3ced 100755
--- a/tests/max-count-vs-context
+++ b/tests/max-count-vs-context
@@ -12,7 +12,7 @@ another needle
6th line...
EOF
-sed 4q in > exp || framework_failure_
+sed 6q in > exp || framework_failure_
fail=0
grep -m1 -A5 needle in > out 2>err || fail=1
diff --git a/tests/yesno b/tests/yesno
index e379c19b..1ae2142f 100755
--- a/tests/yesno
+++ b/tests/yesno
@@ -73,14 +73,14 @@ set x \
'-C,1,--no-gr' "$rB$C$D$E$rF$rG$H$I$rJ$rL$M$N$z0" \
'-m,4' "$C$D$E$H$z0$XI$XJ$XK$XL$XM$XN" \
'-m,4,-o' "$c$d$e$h$z0$XI$XJ$XK$XL$XM$XN" \
- '-m,4,-C,1' "$rB$C$D$E$rF$rG$H$z0$XI$XJ$XK$XL$XM$XN" \
+ '-m,4,-C,1' "$rB$C$D$E$rF$rG$H$rI$z0$XI$XJ$XK$XL$XM$XN" \
'-m,4,-C,1,-o' "$c$d$e$h$z0$XI$XJ$XK$XL$XM$XN" \
'-m,5' "$C$D$E$H$I$z0$XJ$XK$XL$XM$XN" \
'-m,5,-o' "$c$d$e$h$i$z0$XJ$XK$XL$XM$XN" \
'-m,5,-C,1,-o' "$c$d$e$h$i$z0$XJ$XK$XL$XM$XN" \
'-m,6' "$C$D$E$H$I$M$z0$XN" \
'-m,6,-o' "$c$d$e$h$i$m$z0$XN" \
- '-m,6,-C,1' "$rB$C$D$E$rF$rG$H$I$rJ$s$rL$M$z0$XN" \
+ '-m,6,-C,1' "$rB$C$D$E$rF$rG$H$I$rJ$s$rL$M$rN$z0$XN" \
'-m,6,-C,1,-o' "$c$d$e$h$i$s$m$z0$XN" \
'-v' "$A$B$F$G$J$K$L$z0" \
'-v,-o' "$z0" \
@@ -92,13 +92,13 @@ set x \
'-4,-v,-1' "$A$B$rC$s$rE$F$G$rH$rI$J$K$L$rM$z0" \
'-m,1,-v' "$A$z0$XB$XC$XD$XE$XF$XG$XH$XI$XJ$XK$XL$XM$XN" \
'-m,1,-v,-o' "$z0$XB$XC$XD$XE$XF$XG$XH$XI$XJ$XK$XL$XM$XN" \
- '-m,1,-v,-C,1' "$A$z0$XB$XC$XD$XE$XF$XG$XH$XI$XJ$XK$XL$XM$XN" \
+ '-m,1,-v,-C,1' "$A$rB$z0$XB$XC$XD$XE$XF$XG$XH$XI$XJ$XK$XL$XM$XN" \
'-m,1,-v,-C,1,-o' "$z0$XB$XC$XD$XE$XF$XG$XH$XI$XJ$XK$XL$XM$XN" \
'-m,2,-v' "$A$B$z0$XC$XD$XE$XF$XG$XH$XI$XJ$XK$XL$XM$XN" \
'-m,2,-v,-o' "$z0$XC$XD$XE$XF$XG$XH$XI$XJ$XK$XL$XM$XN" \
'-m,3,-v' "$A$B$F$z0$XG$XH$XI$XJ$XK$XL$XM$XN" \
'-m,3,-v,-o' "$z0$XG$XH$XI$XJ$XK$XL$XM$XN" \
- '-m,3,-v,-C,1' "$A$B$rC$s$rE$F$z0$XG$XH$XI$XJ$XK$XL$XM$XN" \
+ '-m,3,-v,-C,1' "$A$B$rC$s$rE$F$rG$z0$XG$XH$XI$XJ$XK$XL$XM$XN" \
'-m,3,-v,-C,1,-o' "$rc$s$re$z0$XG$XH$XI$XJ$XK$XL$XM$XN" \
x
shift