Blender  V3.3
fnmatch.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc. */
3 
7 #ifdef WIN32
8 
9 /* Maintained by GLIBC. */
10 /* clang-format off */
11 
12 /* Enable GNU extensions in fnmatch.h. */
13 #ifndef _GNU_SOURCE
14 # define _GNU_SOURCE 1
15 #endif
16 
17 #include <ctype.h>
18 #include <errno.h>
19 
20 #include "BLI_fnmatch.h"
21 
22 
23 /* Comment out all this code if we are using the GNU C Library, and are not
24  * actually compiling the library itself. This code is part of the GNU C
25  * Library, but also included in many other GNU distributions. Compiling
26  * and linking in this code is a waste when using the GNU C library
27  * (especially if it is a shared library). Rather than having every GNU
28  * program understand `configure --with-gnu-libc' and omit the object files,
29  * it is simpler to just do this in the source for each such file. */
30 
31 #if defined _LIBC || !defined __GNU_LIBRARY__
32 
33 
34 # if defined STDC_HEADERS || !defined isascii
35 # define ISASCII(c) 1
36 # else
37 # define ISASCII(c) isascii(c)
38 # endif
39 
40 # define ISUPPER(c) (ISASCII (c) && isupper (c))
41 
42 
43 # ifndef errno
44 extern int errno;
45 # endif
46 
47 /* Match STRING against the filename pattern PATTERN, returning zero if
48  it matches, nonzero if not. */
49 int
50 fnmatch (const char *pattern, const char *string, int flags)
51 {
52  register const char *p = pattern, *n = string;
53  register char c;
54 
55 /* Note that this evaluates C many times. */
56 # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
57 
58  while ((c = *p++) != '\0')
59  {
60  c = FOLD (c);
61 
62  switch (c)
63  {
64  case '?':
65  if (*n == '\0')
66  return FNM_NOMATCH;
67  else if ((flags & FNM_FILE_NAME) && *n == '/')
68  return FNM_NOMATCH;
69  else if ((flags & FNM_PERIOD) && *n == '.' &&
70  (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
71  return FNM_NOMATCH;
72  break;
73 
74  case '\\':
75  if (!(flags & FNM_NOESCAPE))
76  {
77  c = *p++;
78  if (c == '\0')
79  /* Trailing \ loses. */
80  return FNM_NOMATCH;
81  c = FOLD (c);
82  }
83  if (FOLD (*n) != c)
84  return FNM_NOMATCH;
85  break;
86 
87  case '*':
88  if ((flags & FNM_PERIOD) && *n == '.' &&
89  (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
90  return FNM_NOMATCH;
91 
92  for (c = *p++; c == '?' || c == '*'; c = *p++)
93  {
94  if ((flags & FNM_FILE_NAME) && *n == '/')
95  /* A slash does not match a wildcard under FNM_FILE_NAME. */
96  return FNM_NOMATCH;
97  else if (c == '?')
98  {
99  /* A ? needs to match one character. */
100  if (*n == '\0')
101  /* There isn't another character; no match. */
102  return FNM_NOMATCH;
103  else
104  /* One character of the string is consumed in matching
105  this ? wildcard, so *??? won't match if there are
106  less than three characters. */
107  ++n;
108  }
109  }
110 
111  if (c == '\0')
112  return 0;
113 
114  {
115  char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
116  c1 = FOLD (c1);
117  for (--p; *n != '\0'; ++n)
118  if ((c == '[' || FOLD (*n) == c1) &&
119  fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
120  return 0;
121  return FNM_NOMATCH;
122  }
123 
124  case '[':
125  {
126  /* Nonzero if the sense of the character class is inverted. */
127  register int not;
128 
129  if (*n == '\0')
130  return FNM_NOMATCH;
131 
132  if ((flags & FNM_PERIOD) && *n == '.' &&
133  (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
134  return FNM_NOMATCH;
135 
136  not = (*p == '!' || *p == '^');
137  if (not)
138  ++p;
139 
140  c = *p++;
141  for (;;)
142  {
143  register char cstart = c, cend = c;
144 
145  if (!(flags & FNM_NOESCAPE) && c == '\\')
146  {
147  if (*p == '\0')
148  return FNM_NOMATCH;
149  cstart = cend = *p++;
150  }
151 
152  cstart = cend = FOLD (cstart);
153 
154  if (c == '\0')
155  /* [ (unterminated) loses. */
156  return FNM_NOMATCH;
157 
158  c = *p++;
159  c = FOLD (c);
160 
161  if ((flags & FNM_FILE_NAME) && c == '/')
162  /* [/] can never match. */
163  return FNM_NOMATCH;
164 
165  if (c == '-' && *p != ']')
166  {
167  cend = *p++;
168  if (!(flags & FNM_NOESCAPE) && cend == '\\')
169  cend = *p++;
170  if (cend == '\0')
171  return FNM_NOMATCH;
172  cend = FOLD (cend);
173 
174  c = *p++;
175  }
176 
177  if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
178  goto matched;
179 
180  if (c == ']')
181  break;
182  }
183  if (!not)
184  return FNM_NOMATCH;
185  break;
186 
187  matched:;
188  /* Skip the rest of the [...] that already matched. */
189  while (c != ']')
190  {
191  if (c == '\0')
192  /* [... (unterminated) loses. */
193  return FNM_NOMATCH;
194 
195  c = *p++;
196  if (!(flags & FNM_NOESCAPE) && c == '\\')
197  {
198  if (*p == '\0')
199  return FNM_NOMATCH;
200  /* XXX 1003.2d11 is unclear if this is right. */
201  ++p;
202  }
203  }
204  if (not)
205  return FNM_NOMATCH;
206  }
207  break;
208 
209  default:
210  if (c != FOLD (*n))
211  return FNM_NOMATCH;
212  }
213 
214  ++n;
215  }
216 
217  if (*n == '\0')
218  return 0;
219 
220  if ((flags & FNM_LEADING_DIR) && *n == '/')
221  /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
222  return 0;
223 
224  return FNM_NOMATCH;
225 
226 # undef FOLD
227 }
228 
229 #endif /* _LIBC or not __GNU_LIBRARY__. */
230 
231 /* clang-format on */
232 
233 #else
234 
235 /* intentionally empty for UNIX */
236 
237 #endif /* WIN32 */
static unsigned c
Definition: RandGen.cpp:83