diff options
author | Matthias Kilian <kili@cvs.openbsd.org> | 2007-02-13 21:48:21 +0000 |
---|---|---|
committer | Matthias Kilian <kili@cvs.openbsd.org> | 2007-02-13 21:48:21 +0000 |
commit | dc47ed54edcad7832fe0403f0d3a3ddefd4397ff (patch) | |
tree | e54d630d24e4456a7facdca9f9704f4754aaac25 | |
parent | 77abb3cc848e95932412e3ce6f2766d0f5494fe9 (diff) |
- Be explicit on command line checking, instead of relying on patterns,
which may be NULL (e.g. -e '').
- let add_pattern() decide how to deal with empty patterns, don't do
magic in read_patterns().
This unbreaks stuff like grep -e '', and makes grep -f <file> more
POSIX compliant. Semantics for grep -f /dev/null (or any other empty
file) may be questionable, but this case isn't specified by POSIX,
and matching nothing at all seems to be sane.
Thanks to otto@, who mentioned potential problems related to the
-x option with the first patch i sent.
ok jaredy@ (some time ago), otto@, millert@
-rw-r--r-- | regress/usr.bin/grep/Makefile | 10 | ||||
-rw-r--r-- | usr.bin/grep/grep.1 | 10 | ||||
-rw-r--r-- | usr.bin/grep/grep.c | 27 |
3 files changed, 25 insertions, 22 deletions
diff --git a/regress/usr.bin/grep/Makefile b/regress/usr.bin/grep/Makefile index e590df2bb6a..4785a837f89 100644 --- a/regress/usr.bin/grep/Makefile +++ b/regress/usr.bin/grep/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.12 2005/04/03 19:15:17 otto Exp $ +# $OpenBSD: Makefile,v 1.13 2007/02/13 21:48:20 kili Exp $ REGRESS_TARGETS=t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 \ t18 t19 t20 t21 t22 t23 @@ -91,7 +91,13 @@ t22: t23: egrep -w 'word1|word2|word3' ${.CURDIR}/t23.in +t24: + grep -e '' < in | diff - in + grep -x -e '' < in | diff - /dev/null + grep -f /dev/null < in | diff - /dev/null + + .PHONY: t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 t19 t20 -.PHONY: t21 t22 t23 +.PHONY: t21 t22 t23 t24 .include <bsd.regress.mk> diff --git a/usr.bin/grep/grep.1 b/usr.bin/grep/grep.1 index a1287c42817..385a30643e2 100644 --- a/usr.bin/grep/grep.1 +++ b/usr.bin/grep/grep.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: grep.1,v 1.32 2006/03/07 12:23:50 jmc Exp $ +.\" $OpenBSD: grep.1,v 1.33 2007/02/13 21:48:20 kili Exp $ .\" Copyright (c) 1980, 1990, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -170,7 +170,11 @@ to behave as .It Fl f Ar file Read one or more newline separated patterns from .Ar file . +Empty pattern lines match every input line. Newlines are not considered part of a pattern. +If +.Ar file +is empty, nothing is matched. .It Fl G Interpret .Ar pattern @@ -364,7 +368,9 @@ specification. .Pp The flags .Op Fl AaBbCGHhILoPRSUVwZ -are extensions to that specification. +are extensions to that specification, and the behaviour of the +.Fl f +flag when used with an empty pattern file is left undefined. .Pp All long options are provided for compatibility with GNU versions of this utility. diff --git a/usr.bin/grep/grep.c b/usr.bin/grep/grep.c index a8a8618b8c4..a8a35e3b702 100644 --- a/usr.bin/grep/grep.c +++ b/usr.bin/grep/grep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grep.c,v 1.37 2006/11/02 18:00:03 ray Exp $ */ +/* $OpenBSD: grep.c,v 1.38 2007/02/13 21:48:20 kili Exp $ */ /*- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav @@ -221,23 +221,11 @@ read_patterns(const char *fn) FILE *f; char *line; size_t len; - int nl; if ((f = fopen(fn, "r")) == NULL) err(2, "%s", fn); - nl = 0; - while ((line = fgetln(f, &len)) != NULL) { - if (*line == '\n') { - ++nl; - continue; - } - if (nl) { - matchall = 1; - break; - } - nl = 0; - add_pattern(line, len); - } + while ((line = fgetln(f, &len)) != NULL) + add_pattern(line, *line == '\n' ? 0 : len); if (ferror(f)) err(2, "%s", fn); fclose(f); @@ -246,7 +234,7 @@ read_patterns(const char *fn) int main(int argc, char *argv[]) { - int c, lastc, prevoptind, newarg, i; + int c, lastc, prevoptind, newarg, i, needpattern; struct patfile *patfile, *pf_next; long l; char *ep; @@ -283,6 +271,7 @@ main(int argc, char *argv[]) lastc = '\0'; newarg = 1; prevoptind = 1; + needpattern = 1; while ((c = getopt_long(argc, argv, optstr, long_options, NULL)) != -1) { switch (c) { @@ -372,11 +361,13 @@ main(int argc, char *argv[]) break; case 'e': add_patterns(optarg); + needpattern = 0; break; case 'f': patfile = grep_malloc(sizeof(*patfile)); patfile->pf_file = optarg; SLIST_INSERT_HEAD(&patfilelh, patfile, pf_next); + needpattern = 0; break; case 'h': oflag = 0; @@ -448,10 +439,10 @@ main(int argc, char *argv[]) free(patfile); } - if (argc == 0 && patterns == 0) + if (argc == 0 && needpattern) usage(); - if (patterns == 0) { + if (argc != 0 && needpattern) { add_patterns(*argv); --argc; ++argv; |