blob: 2874413ec8e56cb2096943dc14776f24be829c6f [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24/* unistd.h must be included with _LIBC defined: we need smallint */
25#include <unistd.h>
26#include <features.h>
27#ifdef __UCLIBC__
28# undef _LIBC
29# define HAVE_STRING_H 1
30# define STDC_HEADERS
31# define HAVE___STRCHRNUL 1
32# ifdef __UCLIBC_HAS_WCHAR__
33# define HAVE_WCHAR_H 1
34# define HAVE_WCTYPE_H 1
35# ifdef __UCLIBC_HAS_LOCALE__
36# define HAVE_MBSTATE_T 1
37# define HAVE_MBSRTOWCS 1
38# endif
39# endif
40#endif
41
42#include <assert.h>
43#include <errno.h>
44#include <fnmatch.h>
45#include <ctype.h>
46
47#if HAVE_STRING_H || defined _LIBC
48# include <string.h>
49#else
50# include <strings.h>
51#endif
52
53#if defined STDC_HEADERS || defined _LIBC
54# include <stdlib.h>
55#endif
56
57#ifdef __UCLIBC__
58# define __memset memset
59#endif
60
61/* For platform which support the ISO C amendement 1 functionality we
62 support user defined character classes. */
63#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
64/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
65# include <wchar.h>
66# include <wctype.h>
67#endif
68
69/* We need some of the locale data (the collation sequence information)
70 but there is no interface to get this information in general. Therefore
71 we support a correct implementation only in glibc. */
72#ifdef _LIBC
73# include "../locale/localeinfo.h"
74# include "../locale/elem-hash.h"
75# include "../locale/coll-lookup.h"
76# include <shlib-compat.h>
77
78# define CONCAT(a,b) __CONCAT(a,b)
79# define mbsrtowcs __mbsrtowcs
80# define fnmatch __fnmatch
81extern int fnmatch (const char *pattern, const char *string, int flags);
82#endif
83
84/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */
85#define NO_LEADING_PERIOD(flags) \
86 ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
87
88/* Comment out all this code if we are using the GNU C Library, and are not
89 actually compiling the library itself. This code is part of the GNU C
90 Library, but also included in many other GNU distributions. Compiling
91 and linking in this code is a waste when using the GNU C library
92 (especially if it is a shared library). Rather than having every GNU
93 program understand `configure --with-gnu-libc' and omit the object files,
94 it is simpler to just do this in the source for each such file. */
95
96#if defined _LIBC || !defined __GNU_LIBRARY__
97
98
99# if defined STDC_HEADERS || !defined isascii
100# define ISASCII(c) 1
101# else
102# define ISASCII(c) isascii(c)
103# endif
104
105# ifdef isblank
106# define ISBLANK(c) (ISASCII (c) && isblank (c))
107# else
108# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
109# endif
110# ifdef isgraph
111# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
112# else
113# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
114# endif
115
116# define ISPRINT(c) (ISASCII (c) && isprint (c))
117# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
118# define ISALNUM(c) (ISASCII (c) && isalnum (c))
119# define ISALPHA(c) (ISASCII (c) && isalpha (c))
120# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
121# define ISLOWER(c) (ISASCII (c) && islower (c))
122# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
123# define ISSPACE(c) (ISASCII (c) && isspace (c))
124# define ISUPPER(c) (ISASCII (c) && isupper (c))
125# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
126
127# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
128
129# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
130/* The GNU C library provides support for user-defined character classes
131 and the functions from ISO C amendement 1. */
132# ifdef CHARCLASS_NAME_MAX
133# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
134# else
135/* This shouldn't happen but some implementation might still have this
136 problem. Use a reasonable default value. */
137# define CHAR_CLASS_MAX_LENGTH 256
138# endif
139
140# ifdef _LIBC
141# define IS_CHAR_CLASS(string) __wctype (string)
142# else
143# define IS_CHAR_CLASS(string) wctype (string)
144# endif
145
146# ifdef _LIBC
147# define ISWCTYPE(WC, WT) __iswctype (WC, WT)
148# else
149# define ISWCTYPE(WC, WT) iswctype (WC, WT)
150# endif
151
152# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
153/* In this case we are implementing the multibyte character handling. */
154# define HANDLE_MULTIBYTE 1
155# endif
156
157# else
158# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
159
160# define IS_CHAR_CLASS(string) \
161 (STREQ (string, "alpha") || STREQ (string, "upper") \
162 || STREQ (string, "lower") || STREQ (string, "digit") \
163 || STREQ (string, "alnum") || STREQ (string, "xdigit") \
164 || STREQ (string, "space") || STREQ (string, "print") \
165 || STREQ (string, "punct") || STREQ (string, "graph") \
166 || STREQ (string, "cntrl") || STREQ (string, "blank"))
167# endif
168
169/* Avoid depending on library functions or files
170 whose names are inconsistent. */
171
172# if !defined _LIBC && !defined getenv && !defined __UCLIBC__
173extern char *getenv ();
174# endif
175
176# ifndef errno
177extern int errno;
178# endif
179
180/* Global variable. */
181static smallint posixly_correct;
182
183/* This function doesn't exist on most systems. */
184
185# if !defined HAVE___STRCHRNUL && !defined _LIBC
186static char *
187__strchrnul (s, c)
188 const char *s;
189 int c;
190{
191 char *result = strchr (s, c);
192 if (result == NULL)
193 result = strchr (s, '\0');
194 return result;
195}
196# endif
197
198# if HANDLE_MULTIBYTE && !defined HAVE___STRCHRNUL && !defined _LIBC
199static wchar_t *
200__wcschrnul (s, c)
201 const wchar_t *s;
202 wint_t c;
203{
204 wchar_t *result = wcschr (s, c);
205 if (result == NULL)
206 result = wcschr (s, '\0');
207 return result;
208}
209# endif
210
211# ifndef internal_function
212/* Inside GNU libc we mark some function in a special way. In other
213 environments simply ignore the marking. */
214# define internal_function
215# endif
216
217/* Note that this evaluates C many times. */
218# ifdef _LIBC
219# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
220# else
221# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
222# endif
223# define CHAR char
224# define UCHAR unsigned char
225# define INT int
226# define FCT internal_fnmatch
227# define EXT ext_match
228# define END end_pattern
229# define L(CS) CS
230# ifdef _LIBC
231# define BTOWC(C) __btowc (C)
232# else
233# define BTOWC(C) btowc (C)
234# endif
235# define STRLEN(S) strlen (S)
236# define STRCAT(D, S) strcat (D, S)
237# define MEMPCPY(D, S, N) mempcpy (D, S, N)
238# define MEMCHR(S, C, N) memchr (S, C, N)
239# define STRCOLL(S1, S2) strcoll (S1, S2)
240# include "fnmatch_loop.c"
241
242
243# if HANDLE_MULTIBYTE
244/* Note that this evaluates C many times. */
245# ifdef _LIBC
246# define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
247# else
248# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : (c))
249# endif
250# define CHAR wchar_t
251# define UCHAR wint_t
252# define INT wint_t
253# define FCT internal_fnwmatch
254# define EXT ext_wmatch
255# define END end_wpattern
256# define L(CS) L##CS
257# define BTOWC(C) (C)
258# define STRLEN(S) wcslen (S)
259# define STRCAT(D, S) wcscat (D, S)
260# define MEMPCPY(D, S, N) wmempcpy (D, S, N)
261# define MEMCHR(S, C, N) wmemchr (S, C, N)
262# define STRCOLL(S1, S2) wcscoll (S1, S2)
263# ifndef __UCLIBC__
264# define WIDE_CHAR_VERSION 1
265# endif
266
267# undef IS_CHAR_CLASS
268/* We have to convert the wide character string in a multibyte string. But
269 we know that the character class names consist of alphanumeric characters
270 from the portable character set, and since the wide character encoding
271 for a member of the portable character set is the same code point as
272 its single-byte encoding, we can use a simplified method to convert the
273 string to a multibyte character string. */
274static wctype_t
275is_char_class (const wchar_t *wcs)
276{
277 char s[CHAR_CLASS_MAX_LENGTH + 1];
278 char *cp = s;
279
280 do
281 {
282 /* Test for a printable character from the portable character set. */
283# if defined _LIBC || defined __UCLIBC__
284 if (*wcs < 0x20 || *wcs > 0x7e
285 || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
286 return (wctype_t) 0;
287# else
288 switch (*wcs)
289 {
290 case L' ': case L'!': case L'"': case L'#': case L'%':
291 case L'&': case L'\'': case L'(': case L')': case L'*':
292 case L'+': case L',': case L'-': case L'.': case L'/':
293 case L'0': case L'1': case L'2': case L'3': case L'4':
294 case L'5': case L'6': case L'7': case L'8': case L'9':
295 case L':': case L';': case L'<': case L'=': case L'>':
296 case L'?':
297 case L'A': case L'B': case L'C': case L'D': case L'E':
298 case L'F': case L'G': case L'H': case L'I': case L'J':
299 case L'K': case L'L': case L'M': case L'N': case L'O':
300 case L'P': case L'Q': case L'R': case L'S': case L'T':
301 case L'U': case L'V': case L'W': case L'X': case L'Y':
302 case L'Z':
303 case L'[': case L'\\': case L']': case L'^': case L'_':
304 case L'a': case L'b': case L'c': case L'd': case L'e':
305 case L'f': case L'g': case L'h': case L'i': case L'j':
306 case L'k': case L'l': case L'm': case L'n': case L'o':
307 case L'p': case L'q': case L'r': case L's': case L't':
308 case L'u': case L'v': case L'w': case L'x': case L'y':
309 case L'z': case L'{': case L'|': case L'}': case L'~':
310 break;
311 default:
312 return (wctype_t) 0;
313 }
314# endif
315
316 /* Avoid overrunning the buffer. */
317 if (cp == s + CHAR_CLASS_MAX_LENGTH)
318 return (wctype_t) 0;
319
320 *cp++ = (char) *wcs++;
321 }
322 while (*wcs != L'\0');
323
324 *cp = '\0';
325
326# ifdef _LIBC
327 return __wctype (s);
328# else
329 return wctype (s);
330# endif
331}
332# define IS_CHAR_CLASS(string) is_char_class (string)
333
334# include "fnmatch_loop.c"
335# endif
336
337int
338fnmatch (const char *pattern, const char *string, int flags)
339{
340# if HANDLE_MULTIBYTE
341 if (__builtin_expect (MB_CUR_MAX, 1) != 1)
342 {
343 mbstate_t ps;
344 size_t n;
345 const char *p;
346 wchar_t *wpattern = NULL;
347 wchar_t *wstring = NULL;
348
349 /* Convert the strings into wide characters. */
350 __memset (&ps, '\0', sizeof (ps));
351 p = pattern;
352#ifdef _LIBC
353 n = strnlen (pattern, 1024);
354#else
355 n = strlen (pattern);
356#endif
357 if (__builtin_expect (n < 1024, 1))
358 {
359 wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
360 n = mbsrtowcs (wpattern, &p, n + 1, &ps);
361 if (__builtin_expect (n == (size_t) -1, 0))
362 /* Something wrong.
363 XXX Do we have to set `errno' to something which mbsrtows hasn't
364 already done? */
365 return -1;
366 if (p)
367 __memset (&ps, '\0', sizeof (ps));
368 }
369 if (__builtin_expect (p != NULL, 0))
370 {
371 n = mbsrtowcs (NULL, &pattern, 0, &ps);
372 if (__builtin_expect (n == (size_t) -1, 0))
373 /* Something wrong.
374 XXX Do we have to set `errno' to something which mbsrtows hasn't
375 already done? */
376 return -1;
377 wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
378 assert (mbsinit (&ps));
379 (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
380 }
381
382 assert (mbsinit (&ps));
383#ifdef _LIBC
384 n = strnlen (string, 1024);
385#else
386 n = strlen (string);
387#endif
388 p = string;
389 if (__builtin_expect (n < 1024, 1))
390 {
391 wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
392 n = mbsrtowcs (wstring, &p, n + 1, &ps);
393 if (__builtin_expect (n == (size_t) -1, 0))
394 /* Something wrong.
395 XXX Do we have to set `errno' to something which mbsrtows hasn't
396 already done? */
397 return -1;
398 if (p)
399 __memset (&ps, '\0', sizeof (ps));
400 }
401 if (__builtin_expect (p != NULL, 0))
402 {
403 n = mbsrtowcs (NULL, &string, 0, &ps);
404 if (__builtin_expect (n == (size_t) -1, 0))
405 /* Something wrong.
406 XXX Do we have to set `errno' to something which mbsrtows hasn't
407 already done? */
408 return -1;
409 wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
410 assert (mbsinit (&ps));
411 (void) mbsrtowcs (wstring, &string, n + 1, &ps);
412 }
413
414 return internal_fnwmatch (wpattern, wstring, wstring + n,
415 flags & FNM_PERIOD, flags);
416 }
417# endif /* mbstate_t and mbsrtowcs or _LIBC. */
418
419 return internal_fnmatch (pattern, string, string + strlen (string),
420 flags & FNM_PERIOD, flags);
421}
422
423# ifdef _LIBC
424# undef fnmatch
425versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
426# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
427strong_alias (__fnmatch, __fnmatch_old)
428compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
429# endif
430libc_hidden_ver (__fnmatch, fnmatch)
431# else
432libc_hidden_def(fnmatch)
433# endif
434
435#endif /* _LIBC or not __GNU_LIBRARY__. */