sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

commit 0ba879cdba1311a99895938bf8442425ed29cfe4
parent e6b3af07cf5488dde5da9bc7f15353c06216e51c
Author: Michael Forney <mforney@mforney.org>
Date:   Fri, 13 May 2016 23:34:52 -0700

grep: Fix -v output and exit status

Previously, it printed lines that didn't match some pattern. Instead,
it should print lines that don't match *any* pattern.

Test case:

out=$(echo foo | ./grep -v -e foo -e bar)
if [ "$?" = 1 ] && [ -z "$out" ] ; then
	echo pass
else
	echo fail
fi

Diffstat:
Mgrep.c | 28+++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/grep.c b/grep.c @@ -113,25 +113,28 @@ grep(FILE *fp, const char *str) /* Remove the trailing newline if one is present. */ if (len && buf[len - 1] == '\n') buf[len - 1] = '\0'; + match = 0; SLIST_FOREACH(pnode, &phead, entry) { if (Fflag) { if (xflag) { - if (!(iflag ? strcasecmp : strcmp)(buf, pnode->pattern)) - match = Match; - else - match = NoMatch; + if (!(iflag ? strcasecmp : strcmp)(buf, pnode->pattern)) { + match = 1; + break; + } } else { - if ((iflag ? strcasestr : strstr)(buf, pnode->pattern)) - match = Match; - else - match = NoMatch; + if ((iflag ? strcasestr : strstr)(buf, pnode->pattern)) { + match = 1; + break; + } } - if (match ^ vflag) - continue; } else { - if (regexec(&pnode->preg, buf, 0, NULL, 0) ^ vflag) - continue; + if (regexec(&pnode->preg, buf, 0, NULL, 0) == 0) { + match = 1; + break; + } } + } + if (match != vflag) { switch (mode) { case 'c': c++; @@ -150,7 +153,6 @@ grep(FILE *fp, const char *str) break; } result = Match; - break; } } if (mode == 'c')