[dev] [sbase] [PATCH 3/3] grep: Fix -v output and exit status

From: Michael Forney <mforney_AT_mforney.org>
Date: Fri, 13 May 2016 23:34:52 -0700

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
---
 grep.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/grep.c b/grep.c
index fb911ff..c322a32 100644
--- a/grep.c
+++ b/grep.c
_AT_@ -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++;
_AT_@ -150,7 +153,6 @@ grep(FILE *fp, const char *str)
 				break;
 			}
 			result = Match;
-			break;
 		}
 	}
 	if (mode == 'c')
-- 
2.6.2
Received on Sat May 14 2016 - 08:34:52 CEST

This archive was generated by hypermail 2.3.0 : Sat May 14 2016 - 08:36:27 CEST