aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/gen/fnmatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/gen/fnmatch.c')
-rw-r--r--lib/libc/gen/fnmatch.c85
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);
}