sbase

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

commit 7627a5069cb14c66d8ba964e4a02ce5b56ff6180
parent e34ce441928a4670b5e62c0fa8f0f0f7ce631965
Author: sin <sin@2f30.org>
Date:   Thu, 20 Nov 2014 14:47:26 +0000

Implement grep -x

Diffstat:
Mgrep.1 | 6+++++-
Mgrep.c | 23++++++++++++++++++++---
2 files changed, 25 insertions(+), 4 deletions(-)

diff --git 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 <newline> 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 @@ -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; }