10
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
14
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; if not, write to the Free Software Foundation,
15
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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. */
18
21
# include <config.h>
21
24
/* Enable GNU extensions in fnmatch.h. */
22
25
#ifndef _GNU_SOURCE
23
# define _GNU_SOURCE 1
26
# define _GNU_SOURCE 1
29
#if ! defined __builtin_expect && __GNUC__ < 3
30
# define __builtin_expect(expr, expected) (expr)
27
33
#include <fnmatch.h>
30
#if defined STDC_HEADERS || !defined isascii
31
# define IN_CTYPE_DOMAIN(c) 1
33
# define IN_CTYPE_DOMAIN(c) isascii (c)
36
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
43
/* Match STRING against the filename pattern PATTERN, returning zero if
44
it matches, nonzero if not. */
44
#define WIDE_CHAR_SUPPORT \
45
(HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \
46
&& HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY))
48
/* For platform which support the ISO C amendement 1 functionality we
49
support user defined character classes. */
50
#if defined _LIBC || WIDE_CHAR_SUPPORT
55
/* We need some of the locale data (the collation sequence information)
56
but there is no interface to get this information in general. Therefore
57
we support a correct implementation only in glibc. */
59
# include "../locale/localeinfo.h"
60
# include "../locale/elem-hash.h"
61
# include "../locale/coll-lookup.h"
62
# include <shlib-compat.h>
64
# define CONCAT(a,b) __CONCAT(a,b)
65
# define mbsrtowcs __mbsrtowcs
66
# define fnmatch __fnmatch
67
extern int fnmatch (const char *pattern, const char *string, int flags);
71
# define SIZE_MAX ((size_t) -1)
74
/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */
75
#define NO_LEADING_PERIOD(flags) \
76
((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
78
/* Comment out all this code if we are using the GNU C Library, and are not
79
actually compiling the library itself, and have not detected a bug
80
in the library. This code is part of the GNU C
81
Library, but also included in many other GNU distributions. Compiling
82
and linking in this code is a waste when using the GNU C library
83
(especially if it is a shared library). Rather than having every GNU
84
program understand `configure --with-gnu-libc' and omit the object files,
85
it is simpler to just do this in the source for each such file. */
87
#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU
90
# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
91
# define isblank(c) ((c) == ' ' || (c) == '\t')
94
# define STREQ(s1, s2) (strcmp (s1, s2) == 0)
96
# if defined _LIBC || WIDE_CHAR_SUPPORT
97
/* The GNU C library provides support for user-defined character classes
98
and the functions from ISO C amendement 1. */
99
# ifdef CHARCLASS_NAME_MAX
100
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
102
/* This shouldn't happen but some implementation might still have this
103
problem. Use a reasonable default value. */
104
# define CHAR_CLASS_MAX_LENGTH 256
108
# define IS_CHAR_CLASS(string) __wctype (string)
110
# define IS_CHAR_CLASS(string) wctype (string)
114
# define ISWCTYPE(WC, WT) __iswctype (WC, WT)
116
# define ISWCTYPE(WC, WT) iswctype (WC, WT)
119
# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
120
/* In this case we are implementing the multibyte character handling. */
121
# define HANDLE_MULTIBYTE 1
125
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
127
# define IS_CHAR_CLASS(string) \
128
(STREQ (string, "alpha") || STREQ (string, "upper") \
129
|| STREQ (string, "lower") || STREQ (string, "digit") \
130
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
131
|| STREQ (string, "space") || STREQ (string, "print") \
132
|| STREQ (string, "punct") || STREQ (string, "graph") \
133
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
136
/* Avoid depending on library functions or files
137
whose names are inconsistent. */
139
/* Global variable. */
140
static int posixly_correct;
142
# ifndef internal_function
143
/* Inside GNU libc we mark some function in a special way. In other
144
environments simply ignore the marking. */
145
# define internal_function
148
/* Note that this evaluates C many times. */
149
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
151
# define UCHAR unsigned char
153
# define FCT internal_fnmatch
154
# define EXT ext_match
155
# define END end_pattern
158
# define BTOWC(C) __btowc (C)
160
# define BTOWC(C) btowc (C)
162
# define STRLEN(S) strlen (S)
163
# define STRCAT(D, S) strcat (D, S)
165
# define MEMPCPY(D, S, N) __mempcpy (D, S, N)
168
# define MEMPCPY(D, S, N) mempcpy (D, S, N)
170
# define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
173
# define MEMCHR(S, C, N) memchr (S, C, N)
174
# define STRCOLL(S1, S2) strcoll (S1, S2)
175
# include "fnmatch_loop.c"
178
# if HANDLE_MULTIBYTE
179
# define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
180
# define CHAR wchar_t
181
# define UCHAR wint_t
183
# define FCT internal_fnwmatch
184
# define EXT ext_wmatch
185
# define END end_wpattern
186
# define L_(CS) L##CS
187
# define BTOWC(C) (C)
189
# define STRLEN(S) __wcslen (S)
190
# define STRCAT(D, S) __wcscat (D, S)
191
# define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
193
# define STRLEN(S) wcslen (S)
194
# define STRCAT(D, S) wcscat (D, S)
196
# define MEMPCPY(D, S, N) wmempcpy (D, S, N)
198
# define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N))
201
# define MEMCHR(S, C, N) wmemchr (S, C, N)
202
# define STRCOLL(S1, S2) wcscoll (S1, S2)
203
# define WIDE_CHAR_VERSION 1
205
# undef IS_CHAR_CLASS
206
/* We have to convert the wide character string in a multibyte string. But
207
we know that the character class names consist of alphanumeric characters
208
from the portable character set, and since the wide character encoding
209
for a member of the portable character set is the same code point as
210
its single-byte encoding, we can use a simplified method to convert the
211
string to a multibyte character string. */
213
is_char_class (const wchar_t *wcs)
215
char s[CHAR_CLASS_MAX_LENGTH + 1];
220
/* Test for a printable character from the portable character set. */
222
if (*wcs < 0x20 || *wcs > 0x7e
223
|| *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
228
case L' ': case L'!': case L'"': case L'#': case L'%':
229
case L'&': case L'\'': case L'(': case L')': case L'*':
230
case L'+': case L',': case L'-': case L'.': case L'/':
231
case L'0': case L'1': case L'2': case L'3': case L'4':
232
case L'5': case L'6': case L'7': case L'8': case L'9':
233
case L':': case L';': case L'<': case L'=': case L'>':
235
case L'A': case L'B': case L'C': case L'D': case L'E':
236
case L'F': case L'G': case L'H': case L'I': case L'J':
237
case L'K': case L'L': case L'M': case L'N': case L'O':
238
case L'P': case L'Q': case L'R': case L'S': case L'T':
239
case L'U': case L'V': case L'W': case L'X': case L'Y':
241
case L'[': case L'\\': case L']': case L'^': case L'_':
242
case L'a': case L'b': case L'c': case L'd': case L'e':
243
case L'f': case L'g': case L'h': case L'i': case L'j':
244
case L'k': case L'l': case L'm': case L'n': case L'o':
245
case L'p': case L'q': case L'r': case L's': case L't':
246
case L'u': case L'v': case L'w': case L'x': case L'y':
247
case L'z': case L'{': case L'|': case L'}': case L'~':
254
/* Avoid overrunning the buffer. */
255
if (cp == s + CHAR_CLASS_MAX_LENGTH)
258
*cp++ = (char) *wcs++;
260
while (*wcs != L'\0');
270
# define IS_CHAR_CLASS(string) is_char_class (string)
272
# include "fnmatch_loop.c"
46
277
fnmatch (const char *pattern, const char *string, int flags)
48
register const char *p = pattern, *n = string;
51
/* Note that this evaluates C many times. */
52
#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER ((unsigned char) (c)) \
53
? tolower ((unsigned char) (c)) \
56
while ((c = *p++) != '\0')
279
# if HANDLE_MULTIBYTE
280
# define ALLOCA_LIMIT 2000
281
if (__builtin_expect (MB_CUR_MAX, 1) != 1)
65
else if ((flags & FNM_FILE_NAME) && *n == '/')
67
else if ((flags & FNM_PERIOD) && *n == '.' &&
68
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
73
if (!(flags & FNM_NOESCAPE))
77
/* Trailing \ loses. */
86
if ((flags & FNM_PERIOD) && *n == '.' &&
87
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
90
for (c = *p++; c == '?' || c == '*'; c = *p++)
94
/* A ? needs to match one character. */
95
if (*n == '\0' || (*n == '/' && (flags & FNM_FILE_NAME)))
96
/* There isn't another character; no match. */
99
/* One character of the string is consumed in matching
100
this ? wildcard, so *??? won't match if there are
101
less than three characters. */
108
if ((flags & (FNM_FILE_NAME | FNM_LEADING_DIR)) == FNM_FILE_NAME)
109
for (; *n != '\0'; n++)
116
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
118
for (--p; *n != '\0'; ++n)
119
if ((c == '[' || FOLD (*n) == c1) &&
120
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
122
else if (*n == '/' && (flags & FNM_FILE_NAME))
129
/* Nonzero if the sense of the character class is inverted. */
135
if ((flags & FNM_PERIOD) && *n == '.' &&
136
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
139
not = (*p == '!' || *p == '^');
146
register char cstart = c, cend = c;
148
if (!(flags & FNM_NOESCAPE) && c == '\\')
152
cstart = cend = *p++;
155
cstart = cend = FOLD (cstart);
158
/* [ (unterminated) loses. */
164
if ((flags & FNM_FILE_NAME) && c == '/')
165
/* [/] can never match. */
168
if (c == '-' && *p != ']')
171
if (!(flags & FNM_NOESCAPE) && cend == '\\')
180
if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
191
/* Skip the rest of the [...] that already matched. */
195
/* [... (unterminated) loses. */
199
if (!(flags & FNM_NOESCAPE) && c == '\\')
203
/* XXX 1003.2d11 is unclear if this is right. */
291
/* Calculate the size needed to convert the strings to
293
memset (&ps, '\0', sizeof (ps));
294
patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1;
295
if (__builtin_expect (patsize != 0, 1))
297
assert (mbsinit (&ps));
298
strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1;
299
if (__builtin_expect (strsize != 0, 1))
301
assert (mbsinit (&ps));
302
totsize = patsize + strsize;
303
if (__builtin_expect (! (patsize <= totsize
304
&& totsize <= SIZE_MAX / sizeof (wchar_t)),
311
/* Allocate room for the wide characters. */
312
if (__builtin_expect (totsize < ALLOCA_LIMIT, 1))
313
wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t));
316
wpattern = malloc (totsize * sizeof (wchar_t));
317
if (__builtin_expect (! wpattern, 0))
323
wstring = wpattern + patsize;
325
/* Convert the strings into wide characters. */
326
mbsrtowcs (wpattern, &pattern, patsize, &ps);
327
assert (mbsinit (&ps));
328
mbsrtowcs (wstring, &string, strsize, &ps);
330
res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1,
331
flags & FNM_PERIOD, flags);
333
if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0))
223
if ((flags & FNM_LEADING_DIR) && *n == '/')
224
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
340
# endif /* HANDLE_MULTIBYTE */
342
return internal_fnmatch (pattern, string, string + strlen (string),
343
flags & FNM_PERIOD, flags);
348
versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
349
# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
350
strong_alias (__fnmatch, __fnmatch_old)
351
compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
353
libc_hidden_ver (__fnmatch, fnmatch)
356
#endif /* _LIBC or not __GNU_LIBRARY__. */