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
This commit is contained in:
Michael Forney 2016-05-13 23:34:52 -07:00 committed by sin
parent e6b3af07cf
commit 0ba879cdba

30
grep.c
View File

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