4096
|
1 /* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc. |
|
2 This file is part of the GNU C Library. |
1313
|
3 |
4096
|
4 This library is free software; you can redistribute it and/or |
|
5 modify it under the terms of the GNU Library General Public License as |
|
6 published by the Free Software Foundation; either version 2 of the |
|
7 License, or (at your option) any later version. |
1313
|
8 |
4096
|
9 This library is distributed in the hope that it will be useful, |
|
10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
12 Library General Public License for more details. |
1313
|
13 |
4096
|
14 You should have received a copy of the GNU Library General Public |
|
15 License along with this library; see the file COPYING.LIB. If not, |
|
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
17 Boston, MA 02111-1307, USA. */ |
1313
|
18 |
4096
|
19 #if HAVE_CONFIG_H |
|
20 # include <config.h> |
1313
|
21 #endif |
|
22 |
2755
|
23 /* Enable GNU extensions in fnmatch.h. */ |
|
24 #ifndef _GNU_SOURCE |
4096
|
25 # define _GNU_SOURCE 1 |
2755
|
26 #endif |
|
27 |
1313
|
28 #include <errno.h> |
|
29 #include <fnmatch.h> |
|
30 #include <ctype.h> |
|
31 |
4096
|
32 #if HAVE_STRING_H || defined _LIBC |
|
33 # include <string.h> |
|
34 #else |
|
35 # include <strings.h> |
|
36 #endif |
|
37 |
|
38 #if defined STDC_HEADERS || defined _LIBC |
|
39 # include <stdlib.h> |
|
40 #endif |
|
41 |
|
42 /* For platform which support the ISO C amendement 1 functionality we |
|
43 support user defined character classes. */ |
|
44 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) |
|
45 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ |
|
46 # include <wchar.h> |
|
47 # include <wctype.h> |
|
48 #endif |
1313
|
49 |
|
50 /* Comment out all this code if we are using the GNU C Library, and are not |
|
51 actually compiling the library itself. This code is part of the GNU C |
|
52 Library, but also included in many other GNU distributions. Compiling |
|
53 and linking in this code is a waste when using the GNU C library |
|
54 (especially if it is a shared library). Rather than having every GNU |
|
55 program understand `configure --with-gnu-libc' and omit the object files, |
|
56 it is simpler to just do this in the source for each such file. */ |
|
57 |
4096
|
58 #if defined _LIBC || !defined __GNU_LIBRARY__ |
1313
|
59 |
|
60 |
4096
|
61 # if defined STDC_HEADERS || !defined isascii |
|
62 # define ISASCII(c) 1 |
|
63 # else |
|
64 # define ISASCII(c) isascii(c) |
|
65 # endif |
|
66 |
|
67 # ifdef isblank |
|
68 # define ISBLANK(c) (ISASCII (c) && isblank (c)) |
|
69 # else |
|
70 # define ISBLANK(c) ((c) == ' ' || (c) == '\t') |
|
71 # endif |
|
72 # ifdef isgraph |
|
73 # define ISGRAPH(c) (ISASCII (c) && isgraph (c)) |
|
74 # else |
|
75 # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) |
|
76 # endif |
|
77 |
|
78 # define ISPRINT(c) (ISASCII (c) && isprint (c)) |
|
79 # define ISDIGIT(c) (ISASCII (c) && isdigit (c)) |
|
80 # define ISALNUM(c) (ISASCII (c) && isalnum (c)) |
|
81 # define ISALPHA(c) (ISASCII (c) && isalpha (c)) |
|
82 # define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) |
|
83 # define ISLOWER(c) (ISASCII (c) && islower (c)) |
|
84 # define ISPUNCT(c) (ISASCII (c) && ispunct (c)) |
|
85 # define ISSPACE(c) (ISASCII (c) && isspace (c)) |
|
86 # define ISUPPER(c) (ISASCII (c) && isupper (c)) |
|
87 # define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) |
|
88 |
|
89 # define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) |
|
90 |
|
91 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) |
|
92 /* The GNU C library provides support for user-defined character classes |
|
93 and the functions from ISO C amendement 1. */ |
|
94 # ifdef CHARCLASS_NAME_MAX |
|
95 # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX |
|
96 # else |
|
97 /* This shouldn't happen but some implementation might still have this |
|
98 problem. Use a reasonable default value. */ |
|
99 # define CHAR_CLASS_MAX_LENGTH 256 |
|
100 # endif |
|
101 |
|
102 # ifdef _LIBC |
|
103 # define IS_CHAR_CLASS(string) __wctype (string) |
|
104 # else |
|
105 # define IS_CHAR_CLASS(string) wctype (string) |
|
106 # endif |
|
107 # else |
|
108 # define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ |
|
109 |
|
110 # define IS_CHAR_CLASS(string) \ |
|
111 (STREQ (string, "alpha") || STREQ (string, "upper") \ |
|
112 || STREQ (string, "lower") || STREQ (string, "digit") \ |
|
113 || STREQ (string, "alnum") || STREQ (string, "xdigit") \ |
|
114 || STREQ (string, "space") || STREQ (string, "print") \ |
|
115 || STREQ (string, "punct") || STREQ (string, "graph") \ |
|
116 || STREQ (string, "cntrl") || STREQ (string, "blank")) |
|
117 # endif |
|
118 |
|
119 /* Avoid depending on library functions or files |
|
120 whose names are inconsistent. */ |
|
121 |
|
122 # if !defined _LIBC && !defined getenv |
|
123 extern char *getenv (); |
|
124 # endif |
|
125 |
|
126 # ifndef errno |
1313
|
127 extern int errno; |
4096
|
128 # endif |
|
129 |
|
130 /* This function doesn't exist on most systems. */ |
|
131 |
|
132 # if !defined HAVE___STRCHRNUL && !defined _LIBC |
|
133 static char * |
|
134 __strchrnul (s, c) |
|
135 const char *s; |
|
136 int c; |
|
137 { |
|
138 char *result = strchr (s, c); |
|
139 if (result == NULL) |
|
140 result = strchr (s, '\0'); |
|
141 return result; |
|
142 } |
|
143 # endif |
|
144 |
|
145 # ifndef internal_function |
|
146 /* Inside GNU libc we mark some function in a special way. In other |
|
147 environments simply ignore the marking. */ |
|
148 # define internal_function |
|
149 # endif |
1313
|
150 |
|
151 /* Match STRING against the filename pattern PATTERN, returning zero if |
|
152 it matches, nonzero if not. */ |
4096
|
153 static int internal_fnmatch __P ((const char *pattern, const char *string, |
|
154 int no_leading_period, int flags)) |
|
155 internal_function; |
|
156 static int |
|
157 internal_function |
|
158 internal_fnmatch (pattern, string, no_leading_period, flags) |
1313
|
159 const char *pattern; |
|
160 const char *string; |
4096
|
161 int no_leading_period; |
1313
|
162 int flags; |
|
163 { |
|
164 register const char *p = pattern, *n = string; |
4096
|
165 register unsigned char c; |
1313
|
166 |
4096
|
167 /* Note that this evaluates C many times. */ |
|
168 # ifdef _LIBC |
|
169 # define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) |
|
170 # else |
|
171 # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) |
|
172 # endif |
1313
|
173 |
|
174 while ((c = *p++) != '\0') |
|
175 { |
|
176 c = FOLD (c); |
|
177 |
|
178 switch (c) |
|
179 { |
|
180 case '?': |
|
181 if (*n == '\0') |
|
182 return FNM_NOMATCH; |
4096
|
183 else if (*n == '/' && (flags & FNM_FILE_NAME)) |
1313
|
184 return FNM_NOMATCH; |
4096
|
185 else if (*n == '.' && no_leading_period |
|
186 && (n == string |
|
187 || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) |
1313
|
188 return FNM_NOMATCH; |
|
189 break; |
|
190 |
|
191 case '\\': |
|
192 if (!(flags & FNM_NOESCAPE)) |
|
193 { |
|
194 c = *p++; |
2755
|
195 if (c == '\0') |
|
196 /* Trailing \ loses. */ |
|
197 return FNM_NOMATCH; |
1313
|
198 c = FOLD (c); |
|
199 } |
4096
|
200 if (FOLD ((unsigned char) *n) != c) |
1313
|
201 return FNM_NOMATCH; |
|
202 break; |
|
203 |
|
204 case '*': |
4096
|
205 if (*n == '.' && no_leading_period |
|
206 && (n == string |
|
207 || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) |
1313
|
208 return FNM_NOMATCH; |
|
209 |
2755
|
210 for (c = *p++; c == '?' || c == '*'; c = *p++) |
|
211 { |
4096
|
212 if (*n == '/' && (flags & FNM_FILE_NAME)) |
2755
|
213 /* A slash does not match a wildcard under FNM_FILE_NAME. */ |
|
214 return FNM_NOMATCH; |
|
215 else if (c == '?') |
|
216 { |
|
217 /* A ? needs to match one character. */ |
|
218 if (*n == '\0') |
|
219 /* There isn't another character; no match. */ |
|
220 return FNM_NOMATCH; |
|
221 else |
|
222 /* One character of the string is consumed in matching |
|
223 this ? wildcard, so *??? won't match if there are |
|
224 less than three characters. */ |
|
225 ++n; |
|
226 } |
|
227 } |
1313
|
228 |
|
229 if (c == '\0') |
4096
|
230 /* The wildcard(s) is/are the last element of the pattern. |
|
231 If the name is a file name and contains another slash |
|
232 this does mean it cannot match. */ |
|
233 return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL |
|
234 ? FNM_NOMATCH : 0); |
|
235 else |
|
236 { |
|
237 const char *endp; |
|
238 |
|
239 endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0'); |
|
240 |
|
241 if (c == '[') |
|
242 { |
|
243 int flags2 = ((flags & FNM_FILE_NAME) |
|
244 ? flags : (flags & ~FNM_PERIOD)); |
1313
|
245 |
4096
|
246 for (--p; n < endp; ++n) |
|
247 if (internal_fnmatch (p, n, |
|
248 (no_leading_period |
|
249 && (n == string |
|
250 || (n[-1] == '/' |
|
251 && (flags |
|
252 & FNM_FILE_NAME)))), |
|
253 flags2) |
|
254 == 0) |
|
255 return 0; |
|
256 } |
|
257 else if (c == '/' && (flags & FNM_FILE_NAME)) |
|
258 { |
|
259 while (*n != '\0' && *n != '/') |
|
260 ++n; |
|
261 if (*n == '/' |
|
262 && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD, |
|
263 flags) == 0)) |
|
264 return 0; |
|
265 } |
|
266 else |
|
267 { |
|
268 int flags2 = ((flags & FNM_FILE_NAME) |
|
269 ? flags : (flags & ~FNM_PERIOD)); |
|
270 |
|
271 if (c == '\\' && !(flags & FNM_NOESCAPE)) |
|
272 c = *p; |
|
273 c = FOLD (c); |
|
274 for (--p; n < endp; ++n) |
|
275 if (FOLD ((unsigned char) *n) == c |
|
276 && (internal_fnmatch (p, n, |
|
277 (no_leading_period |
|
278 && (n == string |
|
279 || (n[-1] == '/' |
|
280 && (flags |
|
281 & FNM_FILE_NAME)))), |
|
282 flags2) == 0)) |
|
283 return 0; |
|
284 } |
|
285 } |
|
286 |
|
287 /* If we come here no match is possible with the wildcard. */ |
|
288 return FNM_NOMATCH; |
1313
|
289 |
|
290 case '[': |
|
291 { |
|
292 /* Nonzero if the sense of the character class is inverted. */ |
4096
|
293 static int posixly_correct; |
1313
|
294 register int not; |
4096
|
295 char cold; |
|
296 |
|
297 if (posixly_correct == 0) |
|
298 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; |
1313
|
299 |
|
300 if (*n == '\0') |
|
301 return FNM_NOMATCH; |
|
302 |
4096
|
303 if (*n == '.' && no_leading_period && (n == string |
|
304 || (n[-1] == '/' |
|
305 && (flags |
|
306 & FNM_FILE_NAME)))) |
1313
|
307 return FNM_NOMATCH; |
|
308 |
4096
|
309 if (*n == '/' && (flags & FNM_FILE_NAME)) |
|
310 /* `/' cannot be matched. */ |
|
311 return FNM_NOMATCH; |
|
312 |
|
313 not = (*p == '!' || (posixly_correct < 0 && *p == '^')); |
1313
|
314 if (not) |
|
315 ++p; |
|
316 |
|
317 c = *p++; |
|
318 for (;;) |
|
319 { |
4096
|
320 unsigned char fn = FOLD ((unsigned char) *n); |
1313
|
321 |
|
322 if (!(flags & FNM_NOESCAPE) && c == '\\') |
2755
|
323 { |
|
324 if (*p == '\0') |
|
325 return FNM_NOMATCH; |
4096
|
326 c = FOLD ((unsigned char) *p); |
|
327 ++p; |
|
328 |
|
329 if (c == fn) |
|
330 goto matched; |
2755
|
331 } |
4096
|
332 else if (c == '[' && *p == ':') |
|
333 { |
|
334 /* Leave room for the null. */ |
|
335 char str[CHAR_CLASS_MAX_LENGTH + 1]; |
|
336 size_t c1 = 0; |
|
337 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) |
|
338 wctype_t wt; |
|
339 # endif |
|
340 const char *startp = p; |
|
341 |
|
342 for (;;) |
|
343 { |
|
344 if (c1 == CHAR_CLASS_MAX_LENGTH) |
|
345 /* The name is too long and therefore the pattern |
|
346 is ill-formed. */ |
|
347 return FNM_NOMATCH; |
1313
|
348 |
4096
|
349 c = *++p; |
|
350 if (c == ':' && p[1] == ']') |
|
351 { |
|
352 p += 2; |
|
353 break; |
|
354 } |
|
355 if (c < 'a' || c >= 'z') |
|
356 { |
|
357 /* This cannot possibly be a character class name. |
|
358 Match it as a normal range. */ |
|
359 p = startp; |
|
360 c = '['; |
|
361 goto normal_bracket; |
|
362 } |
|
363 str[c1++] = c; |
|
364 } |
|
365 str[c1] = '\0'; |
1313
|
366 |
4096
|
367 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) |
|
368 wt = IS_CHAR_CLASS (str); |
|
369 if (wt == 0) |
|
370 /* Invalid character class name. */ |
|
371 return FNM_NOMATCH; |
|
372 |
|
373 if (__iswctype (__btowc ((unsigned char) *n), wt)) |
|
374 goto matched; |
|
375 # else |
|
376 if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n)) |
|
377 || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n)) |
|
378 || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n)) |
|
379 || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n)) |
|
380 || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n)) |
|
381 || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n)) |
|
382 || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n)) |
|
383 || (STREQ (str, "print") && ISPRINT ((unsigned char) *n)) |
|
384 || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n)) |
|
385 || (STREQ (str, "space") && ISSPACE ((unsigned char) *n)) |
|
386 || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n)) |
|
387 || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n))) |
|
388 goto matched; |
|
389 # endif |
|
390 } |
|
391 else if (c == '\0') |
1313
|
392 /* [ (unterminated) loses. */ |
|
393 return FNM_NOMATCH; |
4096
|
394 else |
1313
|
395 { |
4096
|
396 normal_bracket: |
|
397 if (FOLD (c) == fn) |
|
398 goto matched; |
|
399 |
|
400 cold = c; |
|
401 c = *p++; |
1313
|
402 |
4096
|
403 if (c == '-' && *p != ']') |
|
404 { |
|
405 /* It is a range. */ |
|
406 unsigned char cend = *p++; |
|
407 if (!(flags & FNM_NOESCAPE) && cend == '\\') |
|
408 cend = *p++; |
|
409 if (cend == '\0') |
|
410 return FNM_NOMATCH; |
1313
|
411 |
4096
|
412 if (cold <= fn && fn <= FOLD (cend)) |
|
413 goto matched; |
|
414 |
|
415 c = *p++; |
|
416 } |
|
417 } |
1313
|
418 |
|
419 if (c == ']') |
|
420 break; |
|
421 } |
4096
|
422 |
1313
|
423 if (!not) |
|
424 return FNM_NOMATCH; |
|
425 break; |
|
426 |
4096
|
427 matched: |
1313
|
428 /* Skip the rest of the [...] that already matched. */ |
|
429 while (c != ']') |
|
430 { |
|
431 if (c == '\0') |
|
432 /* [... (unterminated) loses. */ |
|
433 return FNM_NOMATCH; |
|
434 |
|
435 c = *p++; |
|
436 if (!(flags & FNM_NOESCAPE) && c == '\\') |
2755
|
437 { |
|
438 if (*p == '\0') |
|
439 return FNM_NOMATCH; |
|
440 /* XXX 1003.2d11 is unclear if this is right. */ |
|
441 ++p; |
|
442 } |
4096
|
443 else if (c == '[' && *p == ':') |
|
444 { |
|
445 do |
|
446 if (*++p == '\0') |
|
447 return FNM_NOMATCH; |
|
448 while (*p != ':' || p[1] == ']'); |
|
449 p += 2; |
|
450 c = *p; |
|
451 } |
1313
|
452 } |
|
453 if (not) |
|
454 return FNM_NOMATCH; |
|
455 } |
|
456 break; |
|
457 |
|
458 default: |
4096
|
459 if (c != FOLD ((unsigned char) *n)) |
1313
|
460 return FNM_NOMATCH; |
|
461 } |
|
462 |
|
463 ++n; |
|
464 } |
|
465 |
|
466 if (*n == '\0') |
|
467 return 0; |
|
468 |
|
469 if ((flags & FNM_LEADING_DIR) && *n == '/') |
|
470 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ |
|
471 return 0; |
|
472 |
|
473 return FNM_NOMATCH; |
4096
|
474 |
|
475 # undef FOLD |
|
476 } |
|
477 |
|
478 |
|
479 int |
|
480 fnmatch (pattern, string, flags) |
|
481 const char *pattern; |
|
482 const char *string; |
|
483 int flags; |
|
484 { |
|
485 return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags); |
1313
|
486 } |
|
487 |
|
488 #endif /* _LIBC or not __GNU_LIBRARY__. */ |