X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ffnmatch.c;h=9bff8c220a2f1aaa03f54d7599aa390f3c083eca;hb=b3024d9c5ab39fcce8d7aa8069c4d5bcd139a70b;hp=f772ecc970884517d5ba06d8ba94b42e8744e48b;hpb=5b212401037d18c1843af1b13c8cfe7f2b0756dc;p=gnulib.git diff --git a/lib/fnmatch.c b/lib/fnmatch.c index f772ecc97..9bff8c220 100644 --- a/lib/fnmatch.c +++ b/lib/fnmatch.c @@ -1,55 +1,57 @@ -/* Copyright (C) 1991, 1992, 1993, 1997 Free Software Foundation, Inc. +/* Copyright 1991, 1992, 1993, 1996, 1997, 2000 Free Software Foundation, Inc. - NOTE: The canonical source of this file is maintained with the GNU C - Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if HAVE_CONFIG_H # include #endif +/* Enable GNU extensions in fnmatch.h. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + #include #include #include -#if defined (STDC_HEADERS) || !defined (isascii) -# define ISASCII(c) 1 +#if defined STDC_HEADERS || !defined isascii +# define IN_CTYPE_DOMAIN(c) 1 #else -# define ISASCII(c) isascii(c) +# define IN_CTYPE_DOMAIN(c) isascii (c) #endif -#define ISUPPER(c) (ISASCII (c) && isupper (c)) +#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) + -# ifndef errno +#ifndef errno extern int errno; -# endif +#endif /* Match STRING against the filename pattern PATTERN, returning zero if it matches, nonzero if not. */ int -fnmatch (pattern, string, flags) - const char *pattern; - const char *string; - int flags; +fnmatch (const char *pattern, const char *string, int flags) { register const char *p = pattern, *n = string; register char c; /* Note that this evaluates C many times. */ -# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) +#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER ((unsigned char) (c)) \ + ? tolower ((unsigned char) (c)) \ + : (c)) while ((c = *p++) != '\0') { @@ -71,6 +73,9 @@ fnmatch (pattern, string, flags) if (!(flags & FNM_NOESCAPE)) { c = *p++; + if (c == '\0') + /* Trailing \ loses. */ + return FNM_NOMATCH; c = FOLD (c); } if (FOLD (*n) != c) @@ -82,13 +87,30 @@ fnmatch (pattern, string, flags) (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) return FNM_NOMATCH; - for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) - if (((flags & FNM_FILE_NAME) && *n == '/') || - (c == '?' && *n == '\0')) - return FNM_NOMATCH; + for (c = *p++; c == '?' || c == '*'; c = *p++) + { + if (c == '?') + { + /* A ? needs to match one character. */ + if (*n == '\0' || (*n == '/' && (flags & FNM_FILE_NAME))) + /* There isn't another character; no match. */ + return FNM_NOMATCH; + else + /* One character of the string is consumed in matching + this ? wildcard, so *??? won't match if there are + less than three characters. */ + ++n; + } + } if (c == '\0') - return 0; + { + if ((flags & (FNM_FILE_NAME | FNM_LEADING_DIR)) == FNM_FILE_NAME) + for (; *n != '\0'; n++) + if (*n == '/') + return FNM_NOMATCH; + return 0; + } { char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; @@ -97,6 +119,8 @@ fnmatch (pattern, string, flags) if ((c == '[' || FOLD (*n) == c1) && fnmatch (p, n, flags & ~FNM_PERIOD) == 0) return 0; + else if (*n == '/' && (flags & FNM_FILE_NAME)) + break; return FNM_NOMATCH; } @@ -122,7 +146,11 @@ fnmatch (pattern, string, flags) register char cstart = c, cend = c; if (!(flags & FNM_NOESCAPE) && c == '\\') - cstart = cend = *p++; + { + if (*p == '\0') + return FNM_NOMATCH; + cstart = cend = *p++; + } cstart = cend = FOLD (cstart); @@ -169,8 +197,12 @@ fnmatch (pattern, string, flags) c = *p++; if (!(flags & FNM_NOESCAPE) && c == '\\') - /* XXX 1003.2d11 is unclear if this is right. */ - ++p; + { + if (*p == '\0') + return FNM_NOMATCH; + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } } if (not) return FNM_NOMATCH; @@ -194,5 +226,5 @@ fnmatch (pattern, string, flags) return FNM_NOMATCH; -# undef FOLD +#undef FOLD }