rpm 5.3.7
|
00001 /*@-bounds@*/ 00002 /*@-retalias@*/ 00003 /*@-shiftimplementation@*/ 00004 /*@-temptrans@*/ 00005 /*@-unreachable@*/ 00006 /* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2007 00007 Free Software Foundation, Inc. 00008 This file is part of the GNU C Library. 00009 00010 The GNU C Library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Lesser General Public 00012 License as published by the Free Software Foundation; either 00013 version 2.1 of the License, or (at your option) any later version. 00014 00015 The GNU C Library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public 00021 License along with the GNU C Library; if not, write to the Free 00022 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 00023 02111-1307 USA. */ 00024 00025 #include "system.h" 00026 00027 #include <string.h> 00028 00029 #include "debug.h" 00030 00031 /* XXX Don't bother with wide and multibyte characters ... */ 00032 #undef HAVE_WCTYPE_H 00033 #undef HAVE_WCHAR_H 00034 #undef HAVE_MBSTATE_T 00035 #undef HAVE_MBSRTOWCS 00036 00037 /* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */ 00038 #define NO_LEADING_PERIOD(flags) \ 00039 ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD)) 00040 00041 /* Comment out all this code if we are using the GNU C Library, and are not 00042 actually compiling the library itself. This code is part of the GNU C 00043 Library, but also included in many other GNU distributions. Compiling 00044 and linking in this code is a waste when using the GNU C library 00045 (especially if it is a shared library). Rather than having every GNU 00046 program understand `configure --with-gnu-libc' and omit the object files, 00047 it is simpler to just do this in the source for each such file. */ 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 /* The GNU C library provides support for user-defined character classes 00084 and the functions from ISO C amendement 1. */ 00085 # ifdef CHARCLASS_NAME_MAX 00086 # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX 00087 # else 00088 /* This shouldn't happen but some implementation might still have this 00089 problem. Use a reasonable default value. */ 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 /* In this case we are implementing the multibyte character handling. */ 00107 # define HANDLE_MULTIBYTE 1 00108 # endif 00109 00110 # else 00111 # define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ 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 /* Avoid depending on library functions or files 00123 whose names are inconsistent. */ 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 /* Global variable. */ 00134 static int posixly_correct; 00135 00136 # ifndef internal_function 00137 /* Inside GNU libc we mark some function in a special way. In other 00138 environments simply ignore the marking. */ 00139 # define internal_function 00140 # endif 00141 00142 /* Note that this evaluates C many times. */ 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 /* Note that this evaluates C many times. */ 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 /* We have to convert the wide character string in a multibyte string. But 00203 we know that the character class names consist of alphanumeric characters 00204 from the portable character set, and since the wide character encoding 00205 for a member of the portable character set is the same code point as 00206 its single-byte encoding, we can use a simplified method to convert the 00207 string to a multibyte character string. */ 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 /* Test for a printable character from the portable character set. */ 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 /* Avoid overrunning the buffer. */ 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 /* Convert the strings into wide characters. */ 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 /* Something wrong. 00301 XXX Do we have to set `errno' to something which mbsrtows hasn't 00302 already done? */ 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 /* Something wrong. 00316 XXX Do we have to set `errno' to something which mbsrtows hasn't 00317 already done? */ 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 /* Something wrong. 00337 XXX Do we have to set `errno' to something which mbsrtows hasn't 00338 already done? */ 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 /* Something wrong. 00352 XXX Do we have to set `errno' to something which mbsrtows hasn't 00353 already done? */ 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 /* mbstate_t and mbsrtowcs or _LIBC. */ 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 /* _LIBC or not __GNU_LIBRARY__. */ 00380 /*@=unreachable@*/ 00381 /*@=temptrans@*/ 00382 /*@=shiftimplementation@*/ 00383 /*@=retalias@*/ 00384 /*@=bounds@*/