Blender V2.61 - r43446

fnmatch.c

Go to the documentation of this file.
00001 
00004 /* Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2, or (at your option)
00009    any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016   You should have received a copy of the GNU General Public License
00017   along with this program; if not, write to the Free Software Foundation,
00018   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
00019 
00020 #ifdef WIN32
00021 
00022 /* Enable GNU extensions in fnmatch.h.  */
00023 #ifndef _GNU_SOURCE
00024 # define _GNU_SOURCE    1
00025 #endif
00026 
00027 #include <errno.h>
00028 #include <BLI_fnmatch.h>
00029 #include <ctype.h>
00030 
00031 
00032 /* Comment out all this code if we are using the GNU C Library, and are not
00033    actually compiling the library itself.  This code is part of the GNU C
00034    Library, but also included in many other GNU distributions.  Compiling
00035    and linking in this code is a waste when using the GNU C library
00036    (especially if it is a shared library).  Rather than having every GNU
00037    program understand `configure --with-gnu-libc' and omit the object files,
00038    it is simpler to just do this in the source for each such file.  */
00039 
00040 #if defined _LIBC || !defined __GNU_LIBRARY__
00041 
00042 
00043 # if defined STDC_HEADERS || !defined isascii
00044 #  define ISASCII(c) 1
00045 # else
00046 #  define ISASCII(c) isascii(c)
00047 # endif
00048 
00049 # define ISUPPER(c) (ISASCII (c) && isupper (c))
00050 
00051 
00052 # ifndef errno
00053 extern int errno;
00054 # endif
00055 
00056 /* Match STRING against the filename pattern PATTERN, returning zero if
00057    it matches, nonzero if not.  */
00058 int
00059 fnmatch (const char *pattern, const char *string, int flags)
00060 {
00061   register const char *p = pattern, *n = string;
00062   register char c;
00063 
00064 /* Note that this evaluates C many times.  */
00065 # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
00066 
00067   while ((c = *p++) != '\0')
00068     {
00069       c = FOLD (c);
00070 
00071       switch (c)
00072     {
00073     case '?':
00074       if (*n == '\0')
00075         return FNM_NOMATCH;
00076       else if ((flags & FNM_FILE_NAME) && *n == '/')
00077         return FNM_NOMATCH;
00078       else if ((flags & FNM_PERIOD) && *n == '.' &&
00079            (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
00080         return FNM_NOMATCH;
00081       break;
00082 
00083     case '\\':
00084       if (!(flags & FNM_NOESCAPE))
00085         {
00086           c = *p++;
00087           if (c == '\0')
00088         /* Trailing \ loses.  */
00089         return FNM_NOMATCH;
00090           c = FOLD (c);
00091         }
00092       if (FOLD (*n) != c)
00093         return FNM_NOMATCH;
00094       break;
00095 
00096     case '*':
00097       if ((flags & FNM_PERIOD) && *n == '.' &&
00098           (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
00099         return FNM_NOMATCH;
00100 
00101       for (c = *p++; c == '?' || c == '*'; c = *p++)
00102         {
00103           if ((flags & FNM_FILE_NAME) && *n == '/')
00104         /* A slash does not match a wildcard under FNM_FILE_NAME.  */
00105         return FNM_NOMATCH;
00106           else if (c == '?')
00107         {
00108           /* A ? needs to match one character.  */
00109           if (*n == '\0')
00110             /* There isn't another character; no match.  */
00111             return FNM_NOMATCH;
00112           else
00113             /* One character of the string is consumed in matching
00114                this ? wildcard, so *??? won't match if there are
00115                less than three characters.  */
00116             ++n;
00117         }
00118         }
00119 
00120       if (c == '\0')
00121         return 0;
00122 
00123       {
00124         char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
00125         c1 = FOLD (c1);
00126         for (--p; *n != '\0'; ++n)
00127           if ((c == '[' || FOLD (*n) == c1) &&
00128           fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
00129         return 0;
00130         return FNM_NOMATCH;
00131       }
00132 
00133     case '[':
00134       {
00135         /* Nonzero if the sense of the character class is inverted.  */
00136         register int not;
00137 
00138         if (*n == '\0')
00139           return FNM_NOMATCH;
00140 
00141         if ((flags & FNM_PERIOD) && *n == '.' &&
00142         (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
00143           return FNM_NOMATCH;
00144 
00145         not = (*p == '!' || *p == '^');
00146         if (not)
00147           ++p;
00148 
00149         c = *p++;
00150         for (;;)
00151           {
00152         register char cstart = c, cend = c;
00153 
00154         if (!(flags & FNM_NOESCAPE) && c == '\\')
00155           {
00156             if (*p == '\0')
00157               return FNM_NOMATCH;
00158             cstart = cend = *p++;
00159           }
00160 
00161         cstart = cend = FOLD (cstart);
00162 
00163         if (c == '\0')
00164           /* [ (unterminated) loses.  */
00165           return FNM_NOMATCH;
00166 
00167         c = *p++;
00168         c = FOLD (c);
00169 
00170         if ((flags & FNM_FILE_NAME) && c == '/')
00171           /* [/] can never match.  */
00172           return FNM_NOMATCH;
00173 
00174         if (c == '-' && *p != ']')
00175           {
00176             cend = *p++;
00177             if (!(flags & FNM_NOESCAPE) && cend == '\\')
00178               cend = *p++;
00179             if (cend == '\0')
00180               return FNM_NOMATCH;
00181             cend = FOLD (cend);
00182 
00183             c = *p++;
00184           }
00185 
00186         if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
00187           goto matched;
00188 
00189         if (c == ']')
00190           break;
00191           }
00192         if (!not)
00193           return FNM_NOMATCH;
00194         break;
00195 
00196       matched:;
00197         /* Skip the rest of the [...] that already matched.  */
00198         while (c != ']')
00199           {
00200         if (c == '\0')
00201           /* [... (unterminated) loses.  */
00202           return FNM_NOMATCH;
00203 
00204         c = *p++;
00205         if (!(flags & FNM_NOESCAPE) && c == '\\')
00206           {
00207             if (*p == '\0')
00208               return FNM_NOMATCH;
00209             /* XXX 1003.2d11 is unclear if this is right.  */
00210             ++p;
00211           }
00212           }
00213         if (not)
00214           return FNM_NOMATCH;
00215       }
00216       break;
00217 
00218     default:
00219       if (c != FOLD (*n))
00220         return FNM_NOMATCH;
00221     }
00222 
00223       ++n;
00224     }
00225 
00226   if (*n == '\0')
00227     return 0;
00228 
00229   if ((flags & FNM_LEADING_DIR) && *n == '/')
00230     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
00231     return 0;
00232 
00233   return FNM_NOMATCH;
00234 
00235 # undef FOLD
00236 }
00237 
00238 #endif  /* _LIBC or not __GNU_LIBRARY__.  */
00239 
00240 #else
00241 
00242 /* intentionally empty for UNIX */
00243 
00244 #endif /* WIN32 */
00245 
00246