Implement grep -x

This commit is contained in:
sin 2014-11-20 14:47:26 +00:00
parent e34ce44192
commit 7627a5069c
2 changed files with 25 additions and 4 deletions

6
grep.1
View File

@ -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)

23
grep.c
View File

@ -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;
}