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 grep \- search files for a pattern
.SH SYNOPSIS .SH SYNOPSIS
.B grep .B grep
.RB [ \-EFHchilnqsv ] .RB [ \-EFHchilnqsvx ]
.RB [ \-e .RB [ \-e
.I pattern ] .I pattern ]
.I pattern .I pattern
@ -64,5 +64,9 @@ Suppress the error messages ordinarily written for nonexistent or unreadable fil
Selects lines which do Selects lines which do
.B not .B not
Match the pattern. 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 .SH SEE ALSO
.IR regex (7) .IR regex (7)

23
grep.c
View File

@ -20,6 +20,7 @@ static int eflag;
static int hflag; static int hflag;
static int sflag; static int sflag;
static int vflag; static int vflag;
static int xflag;
static int many; static int many;
static char mode; static char mode;
@ -34,7 +35,7 @@ static SLIST_HEAD(phead, pattern) phead;
static void static void
usage(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 int
@ -78,6 +79,9 @@ main(int argc, char *argv[])
case 'v': case 'v':
vflag = 1; vflag = 1;
break; break;
case 'x':
xflag = 1;
break;
default: default:
usage(); usage();
} ARGEND; } ARGEND;
@ -128,9 +132,19 @@ static void
addpattern(const char *pattern) addpattern(const char *pattern)
{ {
struct pattern *pnode; struct pattern *pnode;
char *tmp;
pnode = emalloc(sizeof(*pnode)); 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); 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) if (regexec(&pnode->preg, buf, 0, NULL, 0) ^ vflag)
continue; continue;
} else { } 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) if (match ^ vflag)
continue; continue;
} }