Blender  V2.59
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