diff --git a/grep.1 b/grep.1 index 7eef257..b939f7c 100644 --- a/grep.1 +++ b/grep.1 @@ -3,7 +3,7 @@ grep \- search files for a pattern .SH SYNOPSIS .B grep -.RB [ \-EFHchilnqsv ] +.RB [ \-EFHchilnqsvx ] .RB [ \-e .I pattern ] .I pattern @@ -64,5 +64,9 @@ Suppress the error messages ordinarily written for nonexistent or unreadable fil Selects lines which do .B not Match the pattern. +.TP +.B \-x +Consider only input lines that use all characters in the line excluding the terminating to +match an entire fixed string or regular expression to be matching lines. .SH SEE ALSO .IR regex (7) diff --git a/grep.c b/grep.c index 3dbf9b8..153f8f7 100644 --- a/grep.c +++ b/grep.c @@ -20,6 +20,7 @@ static int eflag; static int hflag; static int sflag; static int vflag; +static int xflag; static int many; static char mode; @@ -34,7 +35,7 @@ static SLIST_HEAD(phead, pattern) phead; static void usage(void) { - enprintf(Error, "usage: %s [-EFHcilnqsv] [-e pattern] pattern [files...]\n", argv0); + enprintf(Error, "usage: %s [-EFHcilnqsvx] [-e pattern] pattern [files...]\n", argv0); } int @@ -78,6 +79,9 @@ main(int argc, char *argv[]) case 'v': vflag = 1; break; + case 'x': + xflag = 1; + break; default: usage(); } ARGEND; @@ -128,9 +132,19 @@ static void addpattern(const char *pattern) { struct pattern *pnode; + char *tmp; pnode = emalloc(sizeof(*pnode)); - pnode->pattern = estrdup(pattern); + if (!Fflag && xflag) { + tmp = emalloc(strlen(pattern) + 3); + snprintf(tmp, strlen(pattern) + 3, "%s%s%s", + pattern[0] == '^' ? "" : "^", + pattern, + pattern[strlen(pattern) - 1] == '$' ? "" : "$"); + pnode->pattern = tmp; + } else { + pnode->pattern = estrdup(pattern); + } SLIST_INSERT_HEAD(&phead, pnode, entry); } @@ -152,7 +166,10 @@ grep(FILE *fp, const char *str) if (regexec(&pnode->preg, buf, 0, NULL, 0) ^ vflag) continue; } else { - match = strstr(buf, pnode->pattern) ? Match : NoMatch; + if (!xflag) + match = strstr(buf, pnode->pattern) ? Match : NoMatch; + else + match = strcmp(buf, pnode->pattern); if (match ^ vflag) continue; }