diff options
author | ache <ache@FreeBSD.org> | 1997-06-06 21:48:55 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1997-06-06 21:48:55 +0000 |
commit | 2d0c88c35471fde754e5c18e01499b529961347d (patch) | |
tree | d8b01b631023c8f312b336cfecf3e4e750c79cc7 /lib | |
parent | 0f5feb168980de55afb814f20c7f8b4160d554f6 (diff) | |
download | FreeBSD-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 'lib')
-rw-r--r-- | lib/libc/gen/fnmatch.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index 0512b43..28ec196 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/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); } |