1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #if HAVE_CONFIG_H
21: # include <config.h>
22: #endif
23:
24:
25: #ifndef _GNU_SOURCE
26: # define _GNU_SOURCE 1
27: #endif
28:
29: #include <assert.h>
30: #include <errno.h>
31: #include <fnmatch.h>
32: #include <ctype.h>
33:
34: #if HAVE_STRING_H || defined _LIBC
35: # include <string.h>
36: #else
37: # include <strings.h>
38: #endif
39:
40: #if defined STDC_HEADERS || defined _LIBC
41: # include <stdlib.h>
42: #endif
43:
44:
45:
46: #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
47:
48: # include <wchar.h>
49: # include <wctype.h>
50: #endif
51:
52:
53:
54:
55: #ifdef _LIBC
56: # include "../locale/localeinfo.h"
57: # include "../locale/elem-hash.h"
58: # include "../locale/coll-lookup.h"
59: # include <shlib-compat.h>
60:
61: # define CONCAT(a,b) __CONCAT(a,b)
62: # define mbsrtowcs __mbsrtowcs
63: # define fnmatch __fnmatch
64: extern int fnmatch (const char *pattern, const char *string, int flags);
65: #endif
66:
67:
68: #define NO_LEADING_PERIOD(flags) \
69: ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
70:
71:
72:
73:
74:
75:
76:
77:
78:
79: #if defined _LIBC || !defined __GNU_LIBRARY__
80:
81:
82: # if defined STDC_HEADERS || !defined isascii
83: # define ISASCII(c) 1
84: # else
85: # define ISASCII(c) isascii(c)
86: # endif
87:
88: # ifdef isblank
89: # define ISBLANK(c) (ISASCII (c) && isblank (c))
90: # else
91: # define ISBLANK(c) ((c) == ' ' || (c) == '\t')
92: # endif
93: # ifdef isgraph
94: # define ISGRAPH(c) (ISASCII (c) && isgraph (c))
95: # else
96: # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
97: # endif
98:
99: # define ISPRINT(c) (ISASCII (c) && isprint (c))
100: # define ISDIGIT(c) (ISASCII (c) && isdigit (c))
101: # define ISALNUM(c) (ISASCII (c) && isalnum (c))
102: # define ISALPHA(c) (ISASCII (c) && isalpha (c))
103: # define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
104: # define ISLOWER(c) (ISASCII (c) && islower (c))
105: # define ISPUNCT(c) (ISASCII (c) && ispunct (c))
106: # define ISSPACE(c) (ISASCII (c) && isspace (c))
107: # define ISUPPER(c) (ISASCII (c) && isupper (c))
108: # define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
109:
110: # define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
111:
112: # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
113:
114:
115: # ifdef CHARCLASS_NAME_MAX
116: # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
117: # else
118:
119:
120: # define CHAR_CLASS_MAX_LENGTH 256
121: # endif
122:
123: # ifdef _LIBC
124: # define IS_CHAR_CLASS(string) __wctype (string)
125: # else
126: # define IS_CHAR_CLASS(string) wctype (string)
127: # endif
128:
129: # ifdef _LIBC
130: # define ISWCTYPE(WC, WT) __iswctype (WC, WT)
131: # else
132: # define ISWCTYPE(WC, WT) iswctype (WC, WT)
133: # endif
134:
135: # if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
136:
137: # define HANDLE_MULTIBYTE 1
138: # endif
139:
140: # else
141: # define CHAR_CLASS_MAX_LENGTH 6
142:
143: # define IS_CHAR_CLASS(string) \
144: (STREQ (string, "alpha") || STREQ (string, "upper") \
145: || STREQ (string, "lower") || STREQ (string, "digit") \
146: || STREQ (string, "alnum") || STREQ (string, "xdigit") \
147: || STREQ (string, "space") || STREQ (string, "print") \
148: || STREQ (string, "punct") || STREQ (string, "graph") \
149: || STREQ (string, "cntrl") || STREQ (string, "blank"))
150: # endif
151:
152:
153:
154:
155: # if !defined _LIBC && !defined getenv
156: extern char *getenv ();
157: # endif
158:
159: # ifndef errno
160: extern int errno;
161: # endif
162:
163:
164: static int posixly_correct;
165:
166:
167:
168: # if !defined HAVE___STRCHRNUL && !defined _LIBC
169: static char *
170: __strchrnul (s, c)
171: const char *s;
172: int c;
173: {
174: char *result = strchr (s, c);
175: if (result == NULL)
176: result = strchr (s, '\0');
177: return result;
178: }
179: # endif
180:
181: # if HANDLE_MULTIBYTE && !defined HAVE___STRCHRNUL && !defined _LIBC
182: static wchar_t *
183: __wcschrnul (s, c)
184: const wchar_t *s;
185: wint_t c;
186: {
187: wchar_t *result = wcschr (s, c);
188: if (result == NULL)
189: result = wcschr (s, '\0');
190: return result;
191: }
192: # endif
193:
194: # ifndef internal_function
195:
196:
197: # define internal_function
198: # endif
199:
200:
201: # ifdef _LIBC
202: # define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
203: # else
204: # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
205: # endif
206: # define CHAR char
207: # define UCHAR unsigned char
208: # define INT int
209: # define FCT internal_fnmatch
210: # define EXT ext_match
211: # define END end_pattern
212: # define STRUCT fnmatch_struct
213: # define L(CS) CS
214: # ifdef _LIBC
215: # define BTOWC(C) __btowc (C)
216: # else
217: # define BTOWC(C) btowc (C)
218: # endif
219: # define STRLEN(S) strlen (S)
220: # define STRCAT(D, S) strcat (D, S)
221: # define MEMPCPY(D, S, N) __mempcpy (D, S, N)
222: # define MEMCHR(S, C, N) memchr (S, C, N)
223: # define STRCOLL(S1, S2) strcoll (S1, S2)
224: # include "fnmatch_loop.c"
225:
226:
227: # if HANDLE_MULTIBYTE
228:
229: # ifdef _LIBC
230: # define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
231: # else
232: # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : (c))
233: # endif
234: # define CHAR wchar_t
235: # define UCHAR wint_t
236: # define INT wint_t
237: # define FCT internal_fnwmatch
238: # define EXT ext_wmatch
239: # define END end_wpattern
240: # define STRUCT fnwmatch_struct
241: # define L(CS) L##CS
242: # define BTOWC(C) (C)
243: # define STRLEN(S) __wcslen (S)
244: # define STRCAT(D, S) __wcscat (D, S)
245: # define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
246: # define MEMCHR(S, C, N) wmemchr (S, C, N)
247: # define STRCOLL(S1, S2) wcscoll (S1, S2)
248: # define WIDE_CHAR_VERSION 1
249:
250: # undef IS_CHAR_CLASS
251:
252:
253:
254:
255:
256:
257: static wctype_t
258: is_char_class (const wchar_t *wcs)
259: {
260: char s[CHAR_CLASS_MAX_LENGTH + 1];
261: char *cp = s;
262:
263: do
264: {
265:
266: # ifdef _LIBC
267: if (*wcs < 0x20 || *wcs > 0x7e
268: || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
269: return (wctype_t) 0;
270: # else
271: switch (*wcs)
272: {
273: case L' ': case L'!': case L'"': case L'#': case L'%':
274: case L'&': case L'\'': case L'(': case L')': case L'*':
275: case L'+': case L',': case L'-': case L'.': case L'/':
276: case L'0': case L'1': case L'2': case L'3': case L'4':
277: case L'5': case L'6': case L'7': case L'8': case L'9':
278: case L':': case L';': case L'<': case L'=': case L'>':
279: case L'?':
280: case L'A': case L'B': case L'C': case L'D': case L'E':
281: case L'F': case L'G': case L'H': case L'I': case L'J':
282: case L'K': case L'L': case L'M': case L'N': case L'O':
283: case L'P': case L'Q': case L'R': case L'S': case L'T':
284: case L'U': case L'V': case L'W': case L'X': case L'Y':
285: case L'Z':
286: case L'[': case L'\\': case L']': case L'^': case L'_':
287: case L'a': case L'b': case L'c': case L'd': case L'e':
288: case L'f': case L'g': case L'h': case L'i': case L'j':
289: case L'k': case L'l': case L'm': case L'n': case L'o':
290: case L'p': case L'q': case L'r': case L's': case L't':
291: case L'u': case L'v': case L'w': case L'x': case L'y':
292: case L'z': case L'{': case L'|': case L'}': case L'~':
293: break;
294: default:
295: return (wctype_t) 0;
296: }
297: # endif
298:
299:
300: if (cp == s + CHAR_CLASS_MAX_LENGTH)
301: return (wctype_t) 0;
302:
303: *cp++ = (char) *wcs++;
304: }
305: while (*wcs != L'\0');
306:
307: *cp = '\0';
308:
309: # ifdef _LIBC
310: return __wctype (s);
311: # else
312: return wctype (s);
313: # endif
314: }
315: # define IS_CHAR_CLASS(string) is_char_class (string)
316:
317: # include "fnmatch_loop.c"
318: # endif
319:
320:
321: int
322: fnmatch (pattern, string, flags)
323: const char *pattern;
324: const char *string;
325: int flags;
326: {
327: # if HANDLE_MULTIBYTE
328: if (__builtin_expect (MB_CUR_MAX, 1) != 1)
329: {
330: mbstate_t ps;
331: size_t n;
332: const char *p;
333: wchar_t *wpattern;
334: wchar_t *wstring;
335:
336:
337: memset (&ps, '\0', sizeof (ps));
338: p = pattern;
339: #ifdef _LIBC
340: n = strnlen (pattern, 1024);
341: #else
342: n = strlen (pattern);
343: #endif
344: if (__builtin_expect (n < 1024, 1))
345: {
346: wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
347: n = mbsrtowcs (wpattern, &p, n + 1, &ps);
348: if (__builtin_expect (n == (size_t) -1, 0))
349:
350:
351:
352: return -1;
353: if (p)
354: {
355: memset (&ps, '\0', sizeof (ps));
356: goto prepare_wpattern;
357: }
358: }
359: else
360: {
361: prepare_wpattern:
362: n = mbsrtowcs (NULL, &pattern, 0, &ps);
363: if (__builtin_expect (n == (size_t) -1, 0))
364:
365:
366:
367: return -1;
368: wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
369: assert (mbsinit (&ps));
370: (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
371: }
372:
373: assert (mbsinit (&ps));
374: #ifdef _LIBC
375: n = strnlen (string, 1024);
376: #else
377: n = strlen (string);
378: #endif
379: p = string;
380: if (__builtin_expect (n < 1024, 1))
381: {
382: wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
383: n = mbsrtowcs (wstring, &p, n + 1, &ps);
384: if (__builtin_expect (n == (size_t) -1, 0))
385:
386:
387:
388: return -1;
389: if (p)
390: {
391: memset (&ps, '\0', sizeof (ps));
392: goto prepare_wstring;
393: }
394: }
395: else
396: {
397: prepare_wstring:
398: n = mbsrtowcs (NULL, &string, 0, &ps);
399: if (__builtin_expect (n == (size_t) -1, 0))
400:
401:
402:
403: return -1;
404: wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
405: assert (mbsinit (&ps));
406: (void) mbsrtowcs (wstring, &string, n + 1, &ps);
407: }
408:
409: return internal_fnwmatch (wpattern, wstring, wstring + n,
410: flags & FNM_PERIOD, flags, NULL);
411: }
412: # endif
413:
414: return internal_fnmatch (pattern, string, string + strlen (string),
415: flags & FNM_PERIOD, flags, NULL);
416: }
417:
418: # ifdef _LIBC
419: # undef fnmatch
420: versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
421: # if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
422: strong_alias (__fnmatch, __fnmatch_old)
423: compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
424: # endif
425: libc_hidden_ver (__fnmatch, fnmatch)
426: # endif
427:
428: #endif