]> git.saurik.com Git - apple/libc.git/blame - gen/FreeBSD/fnmatch.c.patch
Libc-583.tar.gz
[apple/libc.git] / gen / FreeBSD / fnmatch.c.patch
CommitLineData
3d9156a7 1--- fnmatch.c.orig 2004-11-25 11:38:00.000000000 -0800
224c7076 2+++ fnmatch.c 2005-03-30 14:33:09.000000000 -0800
3d9156a7
A
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.
224c7076
A
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
3d9156a7
A
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);
224c7076 25+__private_extern__ int rangematch(const char *, wchar_t, const char *, int, char **, char **, mbstate_t *, mbstate_t *, locale_t);
3d9156a7
A
26+static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t, locale_t);
27
28 int
29 fnmatch(pattern, string, flags)
224c7076 30@@ -80,27 +85,32 @@
3d9156a7
A
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;
224c7076
A
47- char *newp;
48+ char *newp, *news;
49 char c;
50 wchar_t pc, sc;
3d9156a7
A
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)
224c7076
A
57+#if __DARWIN_UNIX03
58+ return (RETURN_ERROR);
59+#else /* !__DARWIN_UNIX03 */
3d9156a7 60 return (FNM_NOMATCH);
224c7076 61+#endif /* __DARWIN_UNIX03 */
3d9156a7
A
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;
224c7076 68@@ -150,10 +160,10 @@
3d9156a7
A
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;
224c7076
A
82@@ -175,35 +185,45 @@
83 ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
3d9156a7
A
84 return (FNM_NOMATCH);
85
224c7076 86- switch (rangematch(pattern, sc, flags, &newp,
3d9156a7 87- &patmbs)) {
224c7076
A
88+ switch (rangematch(pattern, sc, string + sclen, flags,
89+ &newp, &news, &patmbs, &strmbs, loc)) {
3d9156a7 90 case RANGE_ERROR:
224c7076
A
91+#if __DARWIN_UNIX03
92+ return (RETURN_ERROR);
93+#else /* !__DARWIN_UNIX03 */
3d9156a7 94 goto norm;
224c7076 95+#endif /* __DARWIN_UNIX03 */
3d9156a7 96 case RANGE_MATCH:
224c7076
A
97 pattern = newp;
98+ string = news;
99 break;
100 case RANGE_NOMATCH:
101 return (FNM_NOMATCH);
102 }
103- string += sclen;
3d9156a7
A
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)
224c7076
A
112+#if __DARWIN_UNIX03
113+ return (RETURN_ERROR);
114+#else /* !__DARWIN_UNIX03 */
3d9156a7 115 return (FNM_NOMATCH);
224c7076 116+#endif /* __DARWIN_UNIX03 */
3d9156a7 117 if (pclen == 0)
224c7076
A
118 pc = '\\';
119 pattern += pclen;
120 }
121 /* FALLTHROUGH */
122 default:
123+#if !__DARWIN_UNIX03
124 norm:
125+#endif /* !__DARWIN_UNIX03 */
3d9156a7
A
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);
224c7076
A
134@@ -214,18 +234,22 @@
135 /* NOTREACHED */
3d9156a7
A
136 }
137
224c7076 138-static int
3d9156a7 139-rangematch(pattern, test, flags, newp, patmbs)
224c7076
A
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;
3d9156a7
A
145 wchar_t test;
146 int flags;
224c7076
A
147- char **newp;
148- mbstate_t *patmbs;
149+ char **newp, **news;
150+ mbstate_t *patmbs, *strmbs;
3d9156a7
A
151+ locale_t loc;
152 {
224c7076
A
153- int negate, ok;
154+ int negate, ok, special;
3d9156a7 155 wchar_t c, c2;
224c7076
A
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 @@
3d9156a7
A
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
224c7076
A
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 @@
3d9156a7
A
185 return (RANGE_NOMATCH);
186 } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE))
187 pattern++;
188- pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs);
224c7076
A
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+ }
3d9156a7
A
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)
224c7076
A
307- return (RANGE_NOMATCH);
308+ return (RANGE_ERROR);
3d9156a7 309 pattern += pclen;
224c7076 310 if (c2 == EOS)
3d9156a7
A
311 return (RANGE_ERROR);
312
224c7076
A
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+
3d9156a7
A
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
224c7076 342- )
3d9156a7
A
343+ __collate_range_cmp(c, test, loc) <= 0
344+ && __collate_range_cmp(test, c2, loc) <= 0
224c7076 345+ ) {
3d9156a7 346 ok = 1;
224c7076
A
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 */