summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.bin/grep/util.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c
index 4ab7b06..437a264 100644
--- a/usr.bin/grep/util.c
+++ b/usr.bin/grep/util.c
@@ -55,6 +55,9 @@ __FBSDID("$FreeBSD$");
static int linesqueued;
static int procline(struct str *l, int);
+static int lasta;
+static bool ctxover;
+
bool
file_matching(const char *fname)
{
@@ -204,8 +207,10 @@ procfile(const char *fn)
strcpy(ln.file, fn);
ln.line_no = 0;
ln.len = 0;
+ ctxover = false;
linesqueued = 0;
tail = 0;
+ lasta = 0;
ln.off = -1;
for (c = 0; c == 0 || !(lflag || qflag); ) {
@@ -227,10 +232,24 @@ procfile(const char *fn)
free(f);
return (0);
}
- /* Process the file line-by-line */
+
+ /* Process the file line-by-line, enqueue non-matching lines */
if ((t = procline(&ln, f->binary)) == 0 && Bflag > 0) {
- enqueue(&ln);
- linesqueued++;
+ /* Except don't enqueue lines that appear in -A ctx */
+ if (ln.line_no == 0 || lasta != ln.line_no) {
+ /* queue is maxed to Bflag number of lines */
+ enqueue(&ln);
+ linesqueued++;
+ ctxover = false;
+ } else {
+ /*
+ * Indicate to procline() that we have ctx
+ * overlap and make sure queue is empty.
+ */
+ if (!ctxover)
+ clearqueue();
+ ctxover = true;
+ }
}
c += t;
if (mflag && mcount <= 0)
@@ -385,17 +404,19 @@ procline(struct str *l, int nottext)
/* Dealing with the context */
if ((tail || c) && !cflag && !qflag && !lflag && !Lflag) {
if (c) {
- if (!first && !prev && !tail && Aflag)
+ if (!first && !prev && !tail && (Bflag || Aflag) &&
+ !ctxover)
printf("--\n");
tail = Aflag;
if (Bflag > 0) {
- if (!first && !prev)
- printf("--\n");
printqueue();
+ ctxover = false;
}
linesqueued = 0;
printline(l, ':', matches, m);
} else {
+ /* Print -A lines following matches */
+ lasta = l->line_no;
printline(l, '-', matches, m);
tail--;
}
OpenPOWER on IntegriCloud