00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "system.h"
00026
00027 #include <string.h>
00028
00029 #include "debug.h"
00030
00031
00032 #undef HAVE_WCTYPE_H
00033 #undef HAVE_WCHAR_H
00034 #undef HAVE_MBSTATE_T
00035 #undef HAVE_MBSRTOWCS
00036
00037
00038 #define NO_LEADING_PERIOD(flags) \
00039 ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #if defined _LIBC || !defined __GNU_LIBRARY__
00050
00051
00052 # if defined STDC_HEADERS || !defined isascii
00053 # define ISASCII(c) 1
00054 # else
00055 # define ISASCII(c) isascii(c)
00056 # endif
00057
00058 # ifdef isblank
00059 # define ISBLANK(c) (ISASCII (c) && isblank (c))
00060 # else
00061 # define ISBLANK(c) ((c) == ' ' || (c) == '\t')
00062 # endif
00063 # ifdef isgraph
00064 # define ISGRAPH(c) (ISASCII (c) && isgraph (c))
00065 # else
00066 # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
00067 # endif
00068
00069 # define ISPRINT(c) (ISASCII (c) && isprint (c))
00070 # define ISDIGIT(c) (ISASCII (c) && isdigit (c))
00071 # define ISALNUM(c) (ISASCII (c) && isalnum (c))
00072 # define ISALPHA(c) (ISASCII (c) && isalpha (c))
00073 # define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
00074 # define ISLOWER(c) (ISASCII (c) && islower (c))
00075 # define ISPUNCT(c) (ISASCII (c) && ispunct (c))
00076 # define ISSPACE(c) (ISASCII (c) && isspace (c))
00077 # define ISUPPER(c) (ISASCII (c) && isupper (c))
00078 # define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
00079
00080 # define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
00081
00082 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
00083
00084
00085 # ifdef CHARCLASS_NAME_MAX
00086 # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
00087 # else
00088
00089
00090 # define CHAR_CLASS_MAX_LENGTH 256
00091 # endif
00092
00093 # ifdef _LIBC
00094 # define IS_CHAR_CLASS(string) __wctype (string)
00095 # else
00096 # define IS_CHAR_CLASS(string) wctype (string)
00097 # endif
00098
00099 # ifdef _LIBC
00100 # define ISWCTYPE(WC, WT) __iswctype (WC, WT)
00101 # else
00102 # define ISWCTYPE(WC, WT) iswctype (WC, WT)
00103 # endif
00104
00105 # if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
00106
00107 # define HANDLE_MULTIBYTE 1
00108 # endif
00109
00110 # else
00111 # define CHAR_CLASS_MAX_LENGTH 6
00112
00113 # define IS_CHAR_CLASS(string) \
00114 (STREQ (string, "alpha") || STREQ (string, "upper") \
00115 || STREQ (string, "lower") || STREQ (string, "digit") \
00116 || STREQ (string, "alnum") || STREQ (string, "xdigit") \
00117 || STREQ (string, "space") || STREQ (string, "print") \
00118 || STREQ (string, "punct") || STREQ (string, "graph") \
00119 || STREQ (string, "cntrl") || STREQ (string, "blank"))
00120 # endif
00121
00122
00123
00124
00125 # if defined __linux__ && (!defined _LIBC && !defined getenv)
00126 extern char *getenv ();
00127 # endif
00128
00129 # ifndef errno
00130 extern int errno;
00131 # endif
00132
00133
00134 static int posixly_correct;
00135
00136 # ifndef internal_function
00137
00138
00139 # define internal_function
00140 # endif
00141
00142
00143 # ifdef _LIBC
00144 # define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
00145 # else
00146 # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
00147 # endif
00148 # define CHAR char
00149 # define UCHAR unsigned char
00150 # define INT int
00151 # define FCT internal_fnmatch
00152 # define EXT ext_match
00153 # define END end_pattern
00154 # define STRUCT fnmatch_struct
00155 # define L(CS) CS
00156 # ifdef _LIBC
00157 # define BTOWC(C) __btowc (C)
00158 # else
00159 # define BTOWC(C) btowc (C)
00160 # endif
00161 # define STRLEN(S) strlen (S)
00162 # define STRCAT(D, S) strcat (D, S)
00163 # if defined HAVE_MEMPCPY
00164 # define MEMPCPY(D, S, N) mempcpy (D, S, N)
00165 #else
00166 # define MEMPCPY(D, S, N) __fnmatch_mempcpy (D, S, N)
00167 static void *__fnmatch_mempcpy(void *, const void *, size_t);
00168 static void *__fnmatch_mempcpy(void *dest, const void *src, size_t n)
00169 {
00170 return (void *)((char *)memcpy(dest, src, n) + n);
00171 }
00172 #endif
00173 # define MEMCHR(S, C, N) memchr (S, C, N)
00174 # define STRCOLL(S1, S2) strcoll (S1, S2)
00175 # include "fnmatch_loop.c"
00176
00177
00178 # if HANDLE_MULTIBYTE
00179
00180 # ifdef _LIBC
00181 # define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
00182 # else
00183 # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : (c))
00184 # endif
00185 # define CHAR wchar_t
00186 # define UCHAR wint_t
00187 # define INT wint_t
00188 # define FCT internal_fnwmatch
00189 # define EXT ext_wmatch
00190 # define END end_wpattern
00191 # define STRUCT fnwmatch_struct
00192 # define L(CS) L##CS
00193 # define BTOWC(C) (C)
00194 # define STRLEN(S) __wcslen (S)
00195 # define STRCAT(D, S) __wcscat (D, S)
00196 # define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
00197 # define MEMCHR(S, C, N) wmemchr (S, C, N)
00198 # define STRCOLL(S1, S2) wcscoll (S1, S2)
00199 # define WIDE_CHAR_VERSION 1
00200
00201 # undef IS_CHAR_CLASS
00202
00203
00204
00205
00206
00207
00208 static wctype_t
00209 is_char_class (const wchar_t *wcs)
00210 {
00211 char s[CHAR_CLASS_MAX_LENGTH + 1];
00212 char *cp = s;
00213
00214 do
00215 {
00216
00217 # ifdef _LIBC
00218 if (*wcs < 0x20 || *wcs > 0x7e
00219 || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
00220 return (wctype_t) 0;
00221 # else
00222 switch (*wcs)
00223 {
00224 case L' ': case L'!': case L'"': case L'#': case L'%':
00225 case L'&': case L'\'': case L'(': case L')': case L'*':
00226 case L'+': case L',': case L'-': case L'.': case L'/':
00227 case L'0': case L'1': case L'2': case L'3': case L'4':
00228 case L'5': case L'6': case L'7': case L'8': case L'9':
00229 case L':': case L';': case L'<': case L'=': case L'>':
00230 case L'?':
00231 case L'A': case L'B': case L'C': case L'D': case L'E':
00232 case L'F': case L'G': case L'H': case L'I': case L'J':
00233 case L'K': case L'L': case L'M': case L'N': case L'O':
00234 case L'P': case L'Q': case L'R': case L'S': case L'T':
00235 case L'U': case L'V': case L'W': case L'X': case L'Y':
00236 case L'Z':
00237 case L'[': case L'\\': case L']': case L'^': case L'_':
00238 case L'a': case L'b': case L'c': case L'd': case L'e':
00239 case L'f': case L'g': case L'h': case L'i': case L'j':
00240 case L'k': case L'l': case L'm': case L'n': case L'o':
00241 case L'p': case L'q': case L'r': case L's': case L't':
00242 case L'u': case L'v': case L'w': case L'x': case L'y':
00243 case L'z': case L'{': case L'|': case L'}': case L'~':
00244 break;
00245 default:
00246 return (wctype_t) 0;
00247 }
00248 # endif
00249
00250
00251 if (cp == s + CHAR_CLASS_MAX_LENGTH)
00252 return (wctype_t) 0;
00253
00254 *cp++ = (char) *wcs++;
00255 }
00256 while (*wcs != L'\0');
00257
00258 *cp = '\0';
00259
00260 # ifdef _LIBC
00261 return __wctype (s);
00262 # else
00263 return wctype (s);
00264 # endif
00265 }
00266 # define IS_CHAR_CLASS(string) is_char_class (string)
00267
00268 # include "fnmatch_loop.c"
00269 # endif
00270
00271
00272 int
00273 fnmatch (pattern, string, flags)
00274 const char *pattern;
00275 const char *string;
00276 int flags;
00277 {
00278 # if HANDLE_MULTIBYTE
00279 if (__builtin_expect (MB_CUR_MAX, 1) != 1)
00280 {
00281 mbstate_t ps;
00282 size_t n;
00283 const char *p;
00284 wchar_t *wpattern;
00285 wchar_t *wstring;
00286
00287
00288 memset (&ps, '\0', sizeof (ps));
00289 p = pattern;
00290 #ifdef _LIBC
00291 n = strnlen (pattern, 1024);
00292 #else
00293 n = strlen (pattern);
00294 #endif
00295 if (__builtin_expect (n < 1024, 1))
00296 {
00297 wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
00298 n = mbsrtowcs (wpattern, &p, n + 1, &ps);
00299 if (__builtin_expect (n == (size_t) -1, 0))
00300
00301
00302
00303 return -1;
00304 if (p)
00305 {
00306 memset (&ps, '\0', sizeof (ps));
00307 goto prepare_wpattern;
00308 }
00309 }
00310 else
00311 {
00312 prepare_wpattern:
00313 n = mbsrtowcs (NULL, &pattern, 0, &ps);
00314 if (__builtin_expect (n == (size_t) -1, 0))
00315
00316
00317
00318 return -1;
00319 wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
00320 assert (mbsinit (&ps));
00321 (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
00322 }
00323
00324 assert (mbsinit (&ps));
00325 #ifdef _LIBC
00326 n = strnlen (string, 1024);
00327 #else
00328 n = strlen (string);
00329 #endif
00330 p = string;
00331 if (__builtin_expect (n < 1024, 1))
00332 {
00333 wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
00334 n = mbsrtowcs (wstring, &p, n + 1, &ps);
00335 if (__builtin_expect (n == (size_t) -1, 0))
00336
00337
00338
00339 return -1;
00340 if (p)
00341 {
00342 memset (&ps, '\0', sizeof (ps));
00343 goto prepare_wstring;
00344 }
00345 }
00346 else
00347 {
00348 prepare_wstring:
00349 n = mbsrtowcs (NULL, &string, 0, &ps);
00350 if (__builtin_expect (n == (size_t) -1, 0))
00351
00352
00353
00354 return -1;
00355 wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
00356 assert (mbsinit (&ps));
00357 (void) mbsrtowcs (wstring, &string, n + 1, &ps);
00358 }
00359
00360 return internal_fnwmatch (wpattern, wstring, wstring + n,
00361 flags & FNM_PERIOD, flags, NULL);
00362 }
00363 # endif
00364
00365 return internal_fnmatch (pattern, string, string + strlen (string),
00366 flags & FNM_PERIOD, flags, NULL);
00367 }
00368
00369 # ifdef _LIBC
00370 # undef fnmatch
00371 versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
00372 # if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
00373 strong_alias (__fnmatch, __fnmatch_old)
00374 compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
00375 # endif
00376 libc_hidden_ver (__fnmatch, fnmatch)
00377 # endif
00378
00379 #endif
00380
00381
00382
00383
00384