summaryrefslogtreecommitdiffstats
path: root/sys/libkern
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1997-06-06 21:48:55 +0000
committerache <ache@FreeBSD.org>1997-06-06 21:48:55 +0000
commit2d0c88c35471fde754e5c18e01499b529961347d (patch)
treed8b01b631023c8f312b336cfecf3e4e750c79cc7 /sys/libkern
parent0f5feb168980de55afb814f20c7f8b4160d554f6 (diff)
downloadFreeBSD-src-2d0c88c35471fde754e5c18e01499b529961347d.zip
FreeBSD-src-2d0c88c35471fde754e5c18e01499b529961347d.tar.gz
1) Now conforms POSIX.2 2.8.3.2 requirements about []] pattern
2) Treat unclosed [ range in pattern as regular characters (bash style)
Diffstat (limited to 'sys/libkern')
-rw-r--r--sys/libkern/fnmatch.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/sys/libkern/fnmatch.c b/sys/libkern/fnmatch.c
index 0512b43..28ec196 100644
--- a/sys/libkern/fnmatch.c
+++ b/sys/libkern/fnmatch.c
@@ -52,7 +52,11 @@ static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
#define EOS '\0'
-static const char *rangematch __P((const char *, char, int));
+#define RANGE_MATCH 1
+#define RANGE_NOMATCH 0
+#define RANGE_ERROR (-1)
+
+static int rangematch __P((const char *, char, int, char **));
int
fnmatch(pattern, string, flags)
@@ -60,6 +64,7 @@ fnmatch(pattern, string, flags)
int flags;
{
const char *stringstart;
+ char *newp;
char c, test;
for (stringstart = string;;)
@@ -118,9 +123,15 @@ fnmatch(pattern, string, flags)
return (FNM_NOMATCH);
if (*string == '/' && flags & FNM_PATHNAME)
return (FNM_NOMATCH);
- if ((pattern =
- rangematch(pattern, *string, flags)) == NULL)
+ switch (rangematch(pattern, *string, flags, &newp)) {
+ case RANGE_ERROR:
+ goto norm;
+ case RANGE_MATCH:
+ pattern = newp;
+ break;
+ case RANGE_NOMATCH:
return (FNM_NOMATCH);
+ }
++string;
break;
case '\\':
@@ -132,6 +143,7 @@ fnmatch(pattern, string, flags)
}
/* FALLTHROUGH */
default:
+ norm:
if (c == *string)
;
else if ((flags & FNM_CASEFOLD) &&
@@ -146,15 +158,18 @@ fnmatch(pattern, string, flags)
/* NOTREACHED */
}
-static const char *
-rangematch(pattern, test, flags)
+static int
+rangematch(pattern, test, flags, newp)
const char *pattern;
char test;
int flags;
+ char **newp;
{
- int negate, ok;
+ int negate, ok, first;
char c, c2;
+ first = 1;
+
/*
* A bracket expression starting with an unquoted circumflex
* character produces unspecified results (IEEE 1003.2-1992,
@@ -162,17 +177,25 @@ rangematch(pattern, test, flags)
* consistency with the regular expression syntax.
* J.T. Conklin (conklin@ngai.kaleida.com)
*/
- if ( (negate = (*pattern == '!' || *pattern == '^')) )
+ if ( (negate = (*pattern == '!' || *pattern == '^')) ) {
+ first = 0;
++pattern;
+ }
if (flags & FNM_CASEFOLD)
test = tolower((unsigned char)test);
- for (ok = 0; (c = *pattern++) != ']';) {
+ /*
+ * A right bracket shall lose its special meaning and represent
+ * itself in a bracket expression if it occurs first in the list.
+ * -- POSIX.2 2.8.3.2
+ */
+ for (ok = 0, c = *pattern++; c != ']' || first; c = *pattern++) {
+ first = 0;
if (c == '\\' && !(flags & FNM_NOESCAPE))
c = *pattern++;
if (c == EOS)
- return (NULL);
+ return (RANGE_ERROR);
if (flags & FNM_CASEFOLD)
c = tolower((unsigned char)c);
@@ -183,7 +206,7 @@ rangematch(pattern, test, flags)
if (c2 == '\\' && !(flags & FNM_NOESCAPE))
c2 = *pattern++;
if (c2 == EOS)
- return (NULL);
+ return (RANGE_ERROR);
if (flags & FNM_CASEFOLD)
c2 = tolower((unsigned char)c2);
@@ -197,5 +220,6 @@ rangematch(pattern, test, flags)
} else if (c == test)
ok = 1;
}
- return (ok == negate ? NULL : pattern);
+ *newp = (char *)pattern;
+ return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
}
OpenPOWER on IntegriCloud