]> git.saurik.com Git - apple/libc.git/blob - gen/FreeBSD/fnmatch.c.patch
Libc-594.9.4.tar.gz
[apple/libc.git] / gen / FreeBSD / fnmatch.c.patch
1 --- fnmatch.c.orig 2004-11-25 11:38:00.000000000 -0800
2 +++ fnmatch.c 2005-03-30 14:33:09.000000000 -0800
3 @@ -40,6 +40,8 @@
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.16 2004/07/29 03:13:10 tjr Exp $");
6
7 +#include "xlocale_private.h"
8 +
9 /*
10 * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
11 * Compares a filename or pathname to a pattern.
12 @@ -66,12 +68,15 @@
13
14 #define EOS '\0'
15
16 +#if __DARWIN_UNIX03
17 +#define RETURN_ERROR 2 /* neither 0 or FNM_NOMATCH */
18 +#endif /* __DARWIN_UNIX03 */
19 #define RANGE_MATCH 1
20 #define RANGE_NOMATCH 0
21 #define RANGE_ERROR (-1)
22
23 -static int rangematch(const char *, wchar_t, int, char **, mbstate_t *);
24 -static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t);
25 +__private_extern__ int rangematch(const char *, wchar_t, const char *, int, char **, char **, mbstate_t *, mbstate_t *, locale_t);
26 +static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t, locale_t);
27
28 int
29 fnmatch(pattern, string, flags)
30 @@ -80,27 +85,32 @@
31 {
32 static const mbstate_t initial;
33
34 - return (fnmatch1(pattern, string, flags, initial, initial));
35 + return (fnmatch1(pattern, string, flags, initial, initial, __current_locale()));
36 }
37
38 static int
39 -fnmatch1(pattern, string, flags, patmbs, strmbs)
40 +fnmatch1(pattern, string, flags, patmbs, strmbs, loc)
41 const char *pattern, *string;
42 int flags;
43 mbstate_t patmbs, strmbs;
44 + locale_t loc;
45 {
46 const char *stringstart;
47 - char *newp;
48 + char *newp, *news;
49 char c;
50 wchar_t pc, sc;
51 size_t pclen, sclen;
52
53 for (stringstart = string;;) {
54 - pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs);
55 + pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX, &patmbs, loc);
56 if (pclen == (size_t)-1 || pclen == (size_t)-2)
57 +#if __DARWIN_UNIX03
58 + return (RETURN_ERROR);
59 +#else /* !__DARWIN_UNIX03 */
60 return (FNM_NOMATCH);
61 +#endif /* __DARWIN_UNIX03 */
62 pattern += pclen;
63 - sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs);
64 + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, &strmbs, loc);
65 if (sclen == (size_t)-1 || sclen == (size_t)-2) {
66 sc = (unsigned char)*string;
67 sclen = 1;
68 @@ -150,10 +160,10 @@
69 /* General case, use recursion. */
70 while (sc != EOS) {
71 if (!fnmatch1(pattern, string,
72 - flags & ~FNM_PERIOD, patmbs, strmbs))
73 + flags & ~FNM_PERIOD, patmbs, strmbs, loc))
74 return (0);
75 - sclen = mbrtowc(&sc, string, MB_LEN_MAX,
76 - &strmbs);
77 + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX,
78 + &strmbs, loc);
79 if (sclen == (size_t)-1 ||
80 sclen == (size_t)-2) {
81 sc = (unsigned char)*string;
82 @@ -175,35 +185,45 @@
83 ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
84 return (FNM_NOMATCH);
85
86 - switch (rangematch(pattern, sc, flags, &newp,
87 - &patmbs)) {
88 + switch (rangematch(pattern, sc, string + sclen, flags,
89 + &newp, &news, &patmbs, &strmbs, loc)) {
90 case RANGE_ERROR:
91 +#if __DARWIN_UNIX03
92 + return (RETURN_ERROR);
93 +#else /* !__DARWIN_UNIX03 */
94 goto norm;
95 +#endif /* __DARWIN_UNIX03 */
96 case RANGE_MATCH:
97 pattern = newp;
98 + string = news;
99 break;
100 case RANGE_NOMATCH:
101 return (FNM_NOMATCH);
102 }
103 - string += sclen;
104 break;
105 case '\\':
106 if (!(flags & FNM_NOESCAPE)) {
107 - pclen = mbrtowc(&pc, pattern, MB_LEN_MAX,
108 - &patmbs);
109 + pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX,
110 + &patmbs, loc);
111 if (pclen == (size_t)-1 || pclen == (size_t)-2)
112 +#if __DARWIN_UNIX03
113 + return (RETURN_ERROR);
114 +#else /* !__DARWIN_UNIX03 */
115 return (FNM_NOMATCH);
116 +#endif /* __DARWIN_UNIX03 */
117 if (pclen == 0)
118 pc = '\\';
119 pattern += pclen;
120 }
121 /* FALLTHROUGH */
122 default:
123 +#if !__DARWIN_UNIX03
124 norm:
125 +#endif /* !__DARWIN_UNIX03 */
126 if (pc == sc)
127 ;
128 else if ((flags & FNM_CASEFOLD) &&
129 - (towlower(pc) == towlower(sc)))
130 + (towlower_l(pc, loc) == towlower_l(sc, loc)))
131 ;
132 else
133 return (FNM_NOMATCH);
134 @@ -214,18 +234,22 @@
135 /* NOTREACHED */
136 }
137
138 -static int
139 -rangematch(pattern, test, flags, newp, patmbs)
140 - const char *pattern;
141 +#ifndef BUILDING_VARIANT
142 +__private_extern__ int
143 +rangematch(pattern, test, string, flags, newp, news, patmbs, strmbs, loc)
144 + const char *pattern, *string;
145 wchar_t test;
146 int flags;
147 - char **newp;
148 - mbstate_t *patmbs;
149 + char **newp, **news;
150 + mbstate_t *patmbs, *strmbs;
151 + locale_t loc;
152 {
153 - int negate, ok;
154 + int negate, ok, special;
155 wchar_t c, c2;
156 - size_t pclen;
157 - const char *origpat;
158 + wchar_t buf[STR_LEN]; /* STR_LEN defined in collate.h */
159 + size_t pclen, sclen, len;
160 + const char *origpat, *cp, *savestring;
161 + mbstate_t save;
162
163 /*
164 * A bracket expression starting with an unquoted circumflex
165 @@ -238,7 +262,7 @@
166 ++pattern;
167
168 if (flags & FNM_CASEFOLD)
169 - test = towlower(test);
170 + test = towlower_l(test, loc);
171
172 /*
173 * A right bracket shall lose its special meaning and represent
174 @@ -248,8 +272,8 @@
175 ok = 0;
176 origpat = pattern;
177 for (;;) {
178 + c = 0;
179 if (*pattern == ']' && pattern > origpat) {
180 - pattern++;
181 break;
182 } else if (*pattern == '\0') {
183 return (RANGE_ERROR);
184 @@ -258,39 +282,188 @@
185 return (RANGE_NOMATCH);
186 } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE))
187 pattern++;
188 - pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs);
189 - if (pclen == (size_t)-1 || pclen == (size_t)-2)
190 - return (RANGE_NOMATCH);
191 - pattern += pclen;
192 + else if (*pattern == '[' && ((special = *(pattern + 1)) == '.' || special == '=' || special == ':')) {
193 + cp = (pattern += 2);
194 + while(cp = strchr(cp, special)) {
195 + if (*(cp + 1) == ']')
196 + break;
197 + cp++;
198 + }
199 + if (!cp)
200 + return (RANGE_ERROR);
201 + if (special == '.') {
202 +treat_like_collating_symbol:
203 + len = __collate_collating_symbol(buf, STR_LEN, pattern, cp - pattern, patmbs, loc);
204 + if (len == (size_t)-1 || len == 0)
205 + return (RANGE_ERROR);
206 + pattern = cp + 2;
207 + if (len > 1) {
208 + wchar_t *wp, sc;
209 + /* no multi-character collation symbols as start of range */
210 + if (*(cp + 2) == '-' && *(cp + 3) != EOS
211 + && *(cp + 3) != ']')
212 + return (RANGE_ERROR);
213 + wp = buf;
214 + if (test != *wp++)
215 + continue;
216 + if (len == 1) {
217 + ok = 1;
218 + break;
219 + }
220 + memcpy(&save, strmbs, sizeof(save));
221 + savestring = string;
222 + while (--len > 0) {
223 + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX, strmbs, loc);
224 + if (sclen == (size_t)-1 || sclen == (size_t)-2) {
225 + sc = (unsigned char)*string;
226 + sclen = 1;
227 + memset(&strmbs, 0, sizeof(strmbs));
228 + }
229 + if (sc != *wp++) {
230 + memcpy(strmbs, &save, sizeof(save));
231 + string = savestring;
232 + break;
233 + }
234 + string += sclen;
235 + }
236 + if (len == 0) {
237 + ok = 1;
238 + break;
239 + }
240 + continue; /* no match */
241 + }
242 + c = *buf;
243 + } else if (special == '=') {
244 + int ec;
245 + memcpy(&save, patmbs, sizeof(save));
246 + ec = __collate_equiv_class(pattern, cp - pattern, patmbs, loc);
247 + if (ec < 0)
248 + return (RANGE_ERROR);
249 + if (ec == 0) {
250 + memcpy(patmbs, &save, sizeof(save));
251 + goto treat_like_collating_symbol;
252 + }
253 + pattern = cp + 2;
254 + /* no equivalence classes as start of range */
255 + if (*(cp + 2) == '-' && *(cp + 3) != EOS &&
256 + *(cp + 3) != ']')
257 + return (RANGE_ERROR);
258 + len = __collate_equiv_match(ec, NULL, 0, test, string, strlen(string), strmbs, &sclen, loc);
259 + if (len < 0)
260 + return (RANGE_ERROR);
261 + if (len > 0) {
262 + ok = 1;
263 + string += sclen;
264 + break;
265 + }
266 + continue;
267 + } else { /* special == ':' */
268 + wctype_t charclass;
269 + char name[CHARCLASS_NAME_MAX + 1];
270 + /* no character classes as start of range */
271 + if (*(cp + 2) == '-' && *(cp + 3) != EOS &&
272 + *(cp + 3) != ']')
273 + return (RANGE_ERROR);
274 + /* assume character class names are ascii */
275 + if (cp - pattern > CHARCLASS_NAME_MAX)
276 + return (RANGE_ERROR);
277 + strlcpy(name, pattern, cp - pattern + 1);
278 + pattern = cp + 2;
279 + if ((charclass = wctype(name)) == 0)
280 + return (RANGE_ERROR);
281 + if (iswctype_l(test, charclass, loc)) {
282 + ok = 1;
283 + break;
284 + }
285 + continue;
286 + }
287 + }
288 + if (!c) {
289 + pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc);
290 + if (pclen == (size_t)-1 || pclen == (size_t)-2)
291 + return (RANGE_ERROR);
292 + pattern += pclen;
293 + }
294
295 if (flags & FNM_CASEFOLD)
296 - c = towlower(c);
297 + c = towlower_l(c, loc);
298
299 if (*pattern == '-' && *(pattern + 1) != EOS &&
300 *(pattern + 1) != ']') {
301 if (*++pattern == '\\' && !(flags & FNM_NOESCAPE))
302 if (*pattern != EOS)
303 pattern++;
304 - pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs);
305 + pclen = mbrtowc_l(&c2, pattern, MB_LEN_MAX, patmbs, loc);
306 if (pclen == (size_t)-1 || pclen == (size_t)-2)
307 - return (RANGE_NOMATCH);
308 + return (RANGE_ERROR);
309 pattern += pclen;
310 if (c2 == EOS)
311 return (RANGE_ERROR);
312
313 + if (c2 == '[' && (special = *pattern) == '.' || special == '=' || special == ':') {
314 + /* no equivalence classes or character classes as end of range */
315 + if (special == '=' || special == ':')
316 + return (RANGE_ERROR);
317 + cp = ++pattern;
318 + while(cp = strchr(cp, special)) {
319 + if (*(cp + 1) == ']')
320 + break;
321 + cp++;
322 + }
323 + if (!cp)
324 + return (RANGE_ERROR);
325 + len = __collate_collating_symbol(buf, STR_LEN, pattern, cp - pattern, patmbs, loc);
326 + /* no multi-character collation symbols as end of range */
327 + if (len != 1)
328 + return (RANGE_ERROR);
329 + pattern = cp + 2;
330 + c2 = *buf;
331 + }
332 +
333 if (flags & FNM_CASEFOLD)
334 - c2 = towlower(c2);
335 + c2 = towlower_l(c2, loc);
336
337 - if (__collate_load_error ?
338 + if (loc->__collate_load_error ?
339 c <= test && test <= c2 :
340 - __collate_range_cmp(c, test) <= 0
341 - && __collate_range_cmp(test, c2) <= 0
342 - )
343 + __collate_range_cmp(c, test, loc) <= 0
344 + && __collate_range_cmp(test, c2, loc) <= 0
345 + ) {
346 ok = 1;
347 - } else if (c == test)
348 + break;
349 + }
350 + } else if (c == test) {
351 ok = 1;
352 + break;
353 + }
354 }
355 + /* go to end of bracket expression */
356 + special = 0;
357 + while(*pattern != ']') {
358 + if (*pattern == 0)
359 + return (RANGE_ERROR);
360 + if (*pattern == special) {
361 + if (*++pattern == ']') {
362 + special = 0;
363 + pattern++;
364 + }
365 + continue;
366 + }
367 + if (!special && *pattern == '[') {
368 + special = *++pattern;
369 + if (special != '.' && special != '=' && special != ':')
370 + special = 0;
371 + else
372 + pattern++;
373 + continue;
374 + }
375 + pclen = mbrtowc_l(&c, pattern, MB_LEN_MAX, patmbs, loc);
376 + if (pclen == (size_t)-1 || pclen == (size_t)-2)
377 + return (RANGE_ERROR);
378 + pattern += pclen;
379 + }
380
381 - *newp = (char *)pattern;
382 + *newp = (char *)++pattern;
383 + *news = (char *)string;
384 return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
385 }
386 +#endif /* BUILDING_VARIANT */