Add grep -w support

Require to use abuild on Alpine Linux with sbase.
This commit is contained in:
sin 2015-01-22 17:07:57 +00:00
parent d475a6bdf2
commit e91d94a70e
2 changed files with 30 additions and 2 deletions

4
grep.1
View File

@ -58,6 +58,8 @@ Suppress the error messages ordinarily written for nonexistent or unreadable fil
Select lines which do Select lines which do
.B not .B not
Match the pattern. Match the pattern.
.It Fl w
The expression is search for as a word (as if surrounded by '[[:<:]]' and '[[:>:]]').
.It Fl x .It Fl x
Consider only input lines that use all characters in the line excluding the terminating <newline> to 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. match an entire fixed string or regular expression to be matching lines.
@ -82,5 +84,5 @@ utility is compliant with the
specification. specification.
.Pp .Pp
The flags The flags
.Op Fl Hh .Op Fl Hhw
are an extension to that specification. are an extension to that specification.

28
grep.c
View File

@ -16,6 +16,7 @@ static void addpattern(const char *);
static void addpatternfile(FILE *); static void addpatternfile(FILE *);
static int grep(FILE *, const char *); static int grep(FILE *, const char *);
static int Eflag;
static int Fflag; static int Fflag;
static int Hflag; static int Hflag;
static int eflag; static int eflag;
@ -24,6 +25,7 @@ static int hflag;
static int iflag; static int iflag;
static int sflag; static int sflag;
static int vflag; static int vflag;
static int wflag;
static int xflag; static int xflag;
static int many; static int many;
static int mode; static int mode;
@ -39,7 +41,7 @@ static SLIST_HEAD(phead, pattern) phead;
static void static void
usage(void) usage(void)
{ {
enprintf(Error, "usage: %s [-EFHchilnqsvx] [-e pattern] [-f file] [pattern] [file ...]\n", argv0); enprintf(Error, "usage: %s [-EFHchilnqsvwx] [-e pattern] [-f file] [pattern] [file ...]\n", argv0);
} }
int int
@ -54,6 +56,7 @@ main(int argc, char *argv[])
ARGBEGIN { ARGBEGIN {
case 'E': case 'E':
Eflag = 1;
flags |= REG_EXTENDED; flags |= REG_EXTENDED;
break; break;
case 'F': case 'F':
@ -99,6 +102,9 @@ main(int argc, char *argv[])
case 'v': case 'v':
vflag = 1; vflag = 1;
break; break;
case 'w':
wflag = 1;
break;
case 'x': case 'x':
xflag = 1; xflag = 1;
break; break;
@ -147,6 +153,8 @@ addpattern(const char *pattern)
{ {
struct pattern *pnode; struct pattern *pnode;
char *tmp; char *tmp;
int bol, eol;
size_t len;
/* a null BRE/ERE matches every line */ /* a null BRE/ERE matches every line */
if (!Fflag) if (!Fflag)
@ -161,6 +169,24 @@ addpattern(const char *pattern)
pattern[0] == '^' ? "" : "^", pattern[0] == '^' ? "" : "^",
pattern, pattern,
pattern[strlen(pattern) - 1] == '$' ? "" : "$"); pattern[strlen(pattern) - 1] == '$' ? "" : "$");
} else if (!Fflag && wflag) {
len = strlen(pattern) + 15 + (Eflag ? 2 : 4);
tmp = malloc(len);
if (!tmp)
enprintf(Error, "malloc:");
bol = eol = 0;
if (pattern[0] == '^')
bol = 1;
if (pattern[strlen(pattern) - 1] == '$')
eol = 1;
snprintf(tmp, len, "%s[[:<:]]%s%.*s%s[[:>:]]%s",
bol ? "^" : "",
Eflag ? "(" : "\\(",
(int)strlen(pattern) - bol - eol, pattern + bol,
Eflag ? ")" : "\\)",
eol ? "$" : "");
} else { } else {
tmp = strdup(pattern); tmp = strdup(pattern);
if (!tmp) if (!tmp)