From 3062fc9e9a9f0d7ce347f32fa2e03cc8a793298f Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 23 Sep 2021 20:19:53 -0500 Subject: [PATCH] Fix grep --color to highlight all matches, based on Peter Collingbourne's patch but with several other cleanups rolled in. --- tests/grep.test | 4 ++++ toys/posix/grep.c | 26 +++++++++++--------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/grep.test b/tests/grep.test index 7f882919..dbab4cc0 100755 --- a/tests/grep.test +++ b/tests/grep.test @@ -203,3 +203,7 @@ testing "-z with \n in pattern" "grep -f input" "hi\nthere\n" "i\nt" "hi\nthere" testing "print zero length match" "grep '[0-9]*'" "abc\n" "" "abc\n" testing "-o skip zero length match" "grep -o '[0-9]*'" "1234\n" "" "a1234b" +# Bit of a hack, but other greps insert gratuitous \e[K clear-to-EOL +testing "--color highlights all matches" \ + "grep --color=always def | grep -o '[[][0-9;]*[Km]def.[[]m' | wc -l" \ + "2\n" "" "abcdefghidefjkl\n" diff --git a/toys/posix/grep.c b/toys/posix/grep.c index 37e2083d..95b82cb1 100644 --- a/toys/posix/grep.c +++ b/toys/posix/grep.c @@ -44,10 +44,10 @@ config GREP -x whole line -z input NUL terminated display modes: (default: matched line) - -L show only non-matching filenames - -c count of matching lines -l show only matching filenames + -L filenames with no match -Z output is NUL terminated + -c count of matching lines -l filenames with a match -o only matching part -q quiet (errors only) - -s silent (no error msg) -Z output NUL terminated + -s silent (no error msg) output prefix (default: filename if checking more than 1 file) -H force filename -b byte offset of match @@ -264,13 +264,14 @@ static void do_grep(int fd, char *name) } matched++; TT.found = 1; + + // Are we NOT showing the matching text? if (FLAG(q)) { toys.exitval = 0; xexit(); } if (FLAG(L) || FLAG(l)) { - if (FLAG(l)) - xprintf("%s%c", name, TT.outdelim); + if (FLAG(l)) xprintf("%s%c", name, TT.outdelim); free(line); fclose(file); return; @@ -298,9 +299,9 @@ static void do_grep(int fd, char *name) outline(FLAG(color) ? 0 : line, ':', name, lcount, bcount, ulen); if (FLAG(color)) { xputsn(TT.grey); - if (mm->rm_so) xputsl(line, mm->rm_so); + if (mm->rm_so) xputsl(start, mm->rm_so); xputsn(TT.red); - xputsl(line+mm->rm_so, mm->rm_eo-mm->rm_so); + xputsl(start+mm->rm_so, mm->rm_eo-mm->rm_so); } if (TT.A) after = TT.A+1; @@ -309,7 +310,6 @@ static void do_grep(int fd, char *name) start += mm->rm_eo; if (mm->rm_so == mm->rm_eo) break; - if (!FLAG(o) && FLAG(color)) break; } while (*start); offset += len; @@ -355,12 +355,8 @@ static void do_grep(int fd, char *name) if (FLAG(m) && mcount >= TT.m) break; } - if (FLAG(L)) { - xprintf("%s%c", name, TT.outdelim); - return; - } - - if (FLAG(c)) outline(0, ':', name, mcount, 0, 1); + if (FLAG(L)) xprintf("%s%c", name, TT.outdelim); + else if (FLAG(c)) outline(0, ':', name, mcount, 0, 1); // loopfiles will also close the fd, but this frees an (opaque) struct. fclose(file); @@ -469,7 +465,7 @@ void grep_main(void) TT.cyan = "\033[36m"; TT.red = "\033[1;31m"; TT.green = "\033[32m"; - TT.grey = "\033[0m"; + TT.grey = "\033[m"; } else TT.purple = TT.cyan = TT.red = TT.green = TT.grey = ""; if (FLAG(R)) toys.optflags |= FLAG_r; -- 2.39.2