Fixed the most major defect in fnmatch(): backslash-escape processing in
bracket expressions. Still need to implement FNM_PERIOD...
This commit is contained in:
parent
af72539915
commit
14925245d3
@ -32,7 +32,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)fnmatch.3 8.1 (Berkeley) 6/9/93
|
||||
.\" $Id: fnmatch.3,v 1.5 1993/11/06 00:34:46 cgd Exp $
|
||||
.\" $Id: fnmatch.3,v 1.6 1993/11/09 18:22:05 jtc Exp $
|
||||
.\"
|
||||
.Dd June 9, 1993
|
||||
.Dt FNMATCH 3
|
||||
@ -111,14 +111,16 @@ otherwise, it returns the value
|
||||
.Xr glob 3 ,
|
||||
.Xr wordexp 3 ,
|
||||
.Xr regexp 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn fnmatch
|
||||
function is expected to conform to
|
||||
.St -p1003.2-92 .
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn fnmatch
|
||||
function first appeared in 4.4BSD.
|
||||
.Sh BUGS
|
||||
Quotes and slashes in range patterns are not handled correctly by
|
||||
this implementation.
|
||||
.Pp
|
||||
The
|
||||
.Dv FNM_PERIOD
|
||||
flag is not implemented.
|
||||
|
@ -36,11 +36,11 @@
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/* from: static char sccsid[] = "@(#)fnmatch.c 8.1 (Berkeley) 6/4/93"; */
|
||||
static char *rcsid = "$Id: fnmatch.c,v 1.6 1993/11/06 00:52:40 cgd Exp $";
|
||||
static char *rcsid = "$Id: fnmatch.c,v 1.7 1993/11/09 18:22: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.
|
||||
*/
|
||||
|
||||
@ -49,7 +49,7 @@ static char *rcsid = "$Id: fnmatch.c,v 1.6 1993/11/06 00:52:40 cgd Exp $";
|
||||
|
||||
#define EOS '\0'
|
||||
|
||||
static const char *rangematch __P((const char *, int));
|
||||
static const char *rangematch __P((const char *, int, int));
|
||||
|
||||
fnmatch(pattern, string, flags)
|
||||
register const char *pattern, *string;
|
||||
@ -99,7 +99,7 @@ fnmatch(pattern, string, flags)
|
||||
if ((test = *string++) == EOS ||
|
||||
test == '/' && flags & FNM_PATHNAME)
|
||||
return (FNM_NOMATCH);
|
||||
if ((pattern = rangematch(pattern, test)) == NULL)
|
||||
if ((pattern = rangematch(pattern, test, flags)) == NULL)
|
||||
return (FNM_NOMATCH);
|
||||
break;
|
||||
case '\\':
|
||||
@ -108,9 +108,6 @@ fnmatch(pattern, string, flags)
|
||||
c = '\\';
|
||||
--pattern;
|
||||
}
|
||||
if (c != *string++)
|
||||
return (FNM_NOMATCH);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
@ -122,30 +119,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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
else if (c == test)
|
||||
ok = 1;
|
||||
if (negate = (*pattern == '!' || *pattern == '^')) {
|
||||
pattern++;
|
||||
}
|
||||
|
||||
for (ok = 0; (c = *pattern++) != ']';) {
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE)) {
|
||||
c = *pattern++;
|
||||
}
|
||||
if (c == EOS) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user