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