1 --- fnmatch.c.orig 2004-11-25 11:38:00.000000000 -0800
2 +++ fnmatch.c 2005-03-30 14:33:09.000000000 -0800
5 __FBSDID("$FreeBSD: src/lib/libc/gen/fnmatch.c,v 1.16 2004/07/29 03:13:10 tjr Exp $");
7 +#include "xlocale_private.h"
10 * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
11 * Compares a filename or pathname to a pattern.
17 +#define RETURN_ERROR 2 /* neither 0 or FNM_NOMATCH */
18 +#endif /* __DARWIN_UNIX03 */
20 #define RANGE_NOMATCH 0
21 #define RANGE_ERROR (-1)
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);
29 fnmatch(pattern, string, flags)
32 static const mbstate_t initial;
34 - return (fnmatch1(pattern, string, flags, initial, initial));
35 + return (fnmatch1(pattern, string, flags, initial, initial, __current_locale()));
39 -fnmatch1(pattern, string, flags, patmbs, strmbs)
40 +fnmatch1(pattern, string, flags, patmbs, strmbs, loc)
41 const char *pattern, *string;
43 mbstate_t patmbs, strmbs;
46 const char *stringstart;
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)
58 + return (RETURN_ERROR);
59 +#else /* !__DARWIN_UNIX03 */
61 +#endif /* __DARWIN_UNIX03 */
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;
69 /* General case, use recursion. */
71 if (!fnmatch1(pattern, string,
72 - flags & ~FNM_PERIOD, patmbs, strmbs))
73 + flags & ~FNM_PERIOD, patmbs, strmbs, loc))
75 - sclen = mbrtowc(&sc, string, MB_LEN_MAX,
77 + sclen = mbrtowc_l(&sc, string, MB_LEN_MAX,
79 if (sclen == (size_t)-1 ||
80 sclen == (size_t)-2) {
81 sc = (unsigned char)*string;
83 ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
86 - switch (rangematch(pattern, sc, flags, &newp,
88 + switch (rangematch(pattern, sc, string + sclen, flags,
89 + &newp, &news, &patmbs, &strmbs, loc)) {
92 + return (RETURN_ERROR);
93 +#else /* !__DARWIN_UNIX03 */
95 +#endif /* __DARWIN_UNIX03 */
101 return (FNM_NOMATCH);
106 if (!(flags & FNM_NOESCAPE)) {
107 - pclen = mbrtowc(&pc, pattern, MB_LEN_MAX,
109 + pclen = mbrtowc_l(&pc, pattern, MB_LEN_MAX,
111 if (pclen == (size_t)-1 || pclen == (size_t)-2)
113 + return (RETURN_ERROR);
114 +#else /* !__DARWIN_UNIX03 */
115 return (FNM_NOMATCH);
116 +#endif /* __DARWIN_UNIX03 */
123 +#if !__DARWIN_UNIX03
125 +#endif /* !__DARWIN_UNIX03 */
128 else if ((flags & FNM_CASEFOLD) &&
129 - (towlower(pc) == towlower(sc)))
130 + (towlower_l(pc, loc) == towlower_l(sc, loc)))
133 return (FNM_NOMATCH);
134 @@ -214,18 +234,22 @@
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;
149 + char **newp, **news;
150 + mbstate_t *patmbs, *strmbs;
154 + int negate, ok, special;
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;
164 * A bracket expression starting with an unquoted circumflex
168 if (flags & FNM_CASEFOLD)
169 - test = towlower(test);
170 + test = towlower_l(test, loc);
173 * A right bracket shall lose its special meaning and represent
179 if (*pattern == ']' && pattern > origpat) {
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))
188 - pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs);
189 - if (pclen == (size_t)-1 || pclen == (size_t)-2)
190 - return (RANGE_NOMATCH);
192 + else if (*pattern == '[' && ((special = *(pattern + 1)) == '.' || special == '=' || special == ':')) {
193 + cp = (pattern += 2);
194 + while(cp = strchr(cp, special)) {
195 + if (*(cp + 1) == ']')
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);
209 + /* no multi-character collation symbols as start of range */
210 + if (*(cp + 2) == '-' && *(cp + 3) != EOS
211 + && *(cp + 3) != ']')
212 + return (RANGE_ERROR);
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;
227 + memset(&strmbs, 0, sizeof(strmbs));
230 + memcpy(strmbs, &save, sizeof(save));
231 + string = savestring;
240 + continue; /* no match */
243 + } else if (special == '=') {
245 + memcpy(&save, patmbs, sizeof(save));
246 + ec = __collate_equiv_class(pattern, cp - pattern, patmbs, loc);
248 + return (RANGE_ERROR);
250 + memcpy(patmbs, &save, sizeof(save));
251 + goto treat_like_collating_symbol;
254 + /* no equivalence classes as start of range */
255 + if (*(cp + 2) == '-' && *(cp + 3) != EOS &&
257 + return (RANGE_ERROR);
258 + len = __collate_equiv_match(ec, NULL, 0, test, string, strlen(string), strmbs, &sclen, loc);
260 + return (RANGE_ERROR);
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 &&
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);
279 + if ((charclass = wctype(name)) == 0)
280 + return (RANGE_ERROR);
281 + if (iswctype_l(test, charclass, loc)) {
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);
295 if (flags & FNM_CASEFOLD)
297 + c = towlower_l(c, loc);
299 if (*pattern == '-' && *(pattern + 1) != EOS &&
300 *(pattern + 1) != ']') {
301 if (*++pattern == '\\' && !(flags & FNM_NOESCAPE))
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);
311 return (RANGE_ERROR);
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);
318 + while(cp = strchr(cp, special)) {
319 + if (*(cp + 1) == ']')
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 */
328 + return (RANGE_ERROR);
333 if (flags & FNM_CASEFOLD)
335 + c2 = towlower_l(c2, loc);
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
343 + __collate_range_cmp(c, test, loc) <= 0
344 + && __collate_range_cmp(test, c2, loc) <= 0
347 - } else if (c == test)
350 + } else if (c == test) {
355 + /* go to end of bracket expression */
357 + while(*pattern != ']') {
359 + return (RANGE_ERROR);
360 + if (*pattern == special) {
361 + if (*++pattern == ']') {
367 + if (!special && *pattern == '[') {
368 + special = *++pattern;
369 + if (special != '.' && special != '=' && special != ':')
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);
381 - *newp = (char *)pattern;
382 + *newp = (char *)++pattern;
383 + *news = (char *)string;
384 return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
386 +#endif /* BUILDING_VARIANT */