diff options
Diffstat (limited to 'lib/libc/gen/fnmatch.c')
| -rw-r--r-- | lib/libc/gen/fnmatch.c | 85 |
1 files changed, 57 insertions, 28 deletions
diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index 7b54c3b7254a..9d64cf5573ad 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/fnmatch.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. @@ -35,11 +35,12 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fnmatch.c 5.6 (Berkeley) 6/28/92"; +/* from: static char sccsid[] = "@(#)fnmatch.c 8.1 (Berkeley) 6/4/93"; */ +static char *rcsid = "$Id: fnmatch.c,v 1.3 1993/11/23 00:10:09 jtc Exp $"; #endif /* LIBC_SCCS and not lint */ /* - * Function fnmatch() as proposed in POSIX 1003.2 B.6 (D11.2). + * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. * Compares a filename or pathname to a pattern. */ @@ -48,12 +49,14 @@ static char sccsid[] = "@(#)fnmatch.c 5.6 (Berkeley) 6/28/92"; #define EOS '\0' -static const char *rangematch __P((const char *, int)); +static const char *rangematch __P((const char *, int, int)); +int fnmatch(pattern, string, flags) register const char *pattern, *string; int flags; { + const char *stringstart = string; register char c; char test; @@ -62,9 +65,14 @@ fnmatch(pattern, string, flags) case EOS: return (*string == EOS ? 0 : FNM_NOMATCH); case '?': - if ((test = *string++) == EOS || - test == '/' && flags & FNM_PATHNAME) + if (*string == EOS) return (FNM_NOMATCH); + if (*string == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + ++string; break; case '*': c = *pattern; @@ -72,6 +80,10 @@ fnmatch(pattern, string, flags) while (c == '*') c = *++pattern; + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + /* Optimize for pattern with * at end or before /. */ if (c == EOS) if (flags & FNM_PATHNAME) @@ -87,7 +99,7 @@ fnmatch(pattern, string, flags) /* General case, use recursion. */ while ((test = *string) != EOS) { - if (!fnmatch(pattern, string, flags)) + if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) return (0); if (test == '/' && flags & FNM_PATHNAME) break; @@ -95,11 +107,13 @@ fnmatch(pattern, string, flags) } return (FNM_NOMATCH); case '[': - if ((test = *string++) == EOS || - test == '/' && flags & FNM_PATHNAME) + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && flags & FNM_PATHNAME) return (FNM_NOMATCH); - if ((pattern = rangematch(pattern, test)) == NULL) + if ((pattern = rangematch(pattern, *string, flags)) == NULL) return (FNM_NOMATCH); + ++string; break; case '\\': if (!(flags & FNM_NOESCAPE)) { @@ -107,9 +121,6 @@ fnmatch(pattern, string, flags) c = '\\'; --pattern; } - if (c != *string++) - return (FNM_NOMATCH); - break; } /* FALLTHROUGH */ default: @@ -121,30 +132,48 @@ fnmatch(pattern, string, flags) } static const char * -rangematch(pattern, test) +rangematch(pattern, test, flags) register const char *pattern; register int test; + int flags; { register char c, c2; int negate, ok; - if (negate = (*pattern == '!')) - ++pattern; - - /* - * XXX - * TO DO: quoting + /* A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). I have chosen to treat it like '!', for + * consistancy with regular expression syntax. */ + if (negate = (*pattern == '!' || *pattern == '^')) { + pattern++; + } + for (ok = 0; (c = *pattern++) != ']';) { - if (c == EOS) - return (NULL); /* Illegal pattern. */ - if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') { - if (c <= test && test <= c2) - ok = 1; - pattern += 2; + if (c == '\\' && !(flags & FNM_NOESCAPE)) { + c = *pattern++; + } + if (c == EOS) { + return (NULL); } - else if (c == test) + + if (*pattern == '-' + && (c2 = *(pattern+1)) != EOS && c2 != ']') { + pattern += 2; + if (c2 == '\\' && !(flags & FNM_NOESCAPE)) { + c2 = *pattern++; + } + if (c2 == EOS) { + return (NULL); + } + + if (c <= test && test <= c2) { + ok = 1; + } + } else if (c == test) { ok = 1; + } } + return (ok == negate ? NULL : pattern); } |
