8 static int next(const char **s)
11 int l = mbtowc(&c, *s, MB_LEN_MAX);
12 /* hack to allow literal matches of invalid byte sequences */
13 if (l < 0) return (unsigned char)*(*s)++ - 0x100;
18 #define BRACKET_ERROR -0x100
19 #define BRACKET_NOCHAR -0x101
21 static int bracket_next(const char **s)
27 if (type == '.' || type == '=') {
30 if (c <= 0) return BRACKET_ERROR;
31 if (**s == type && *(*s+1) == ']') {
35 for (; **s && (**s != type || *(*s+1) != ']'); (*s)++);
36 if (!**s) return BRACKET_ERROR;
38 return BRACKET_NOCHAR;
42 if (c <= 0) return BRACKET_ERROR;
46 #define __FNM_CONT 0x8000
48 int fnmatch(const char *p, const char *s, int flags)
54 int no_slash = (flags & FNM_PATHNAME) ? '/' : 0;
55 int no_period = (flags & FNM_PERIOD) && !(flags & __FNM_CONT) ? '.' : 0x100;
63 if (!k || k == no_period || k == no_slash)
67 if (!(flags & FNM_NOESCAPE)) {
71 if (*s++ != c) return FNM_NOMATCH;
74 for (; *p == '*'; p++);
75 if (*p && !*s) return FNM_NOMATCH;
78 if (!*p && (!no_slash || !strchr(s, no_slash)))
81 if (!fnmatch(p, s, flags))
83 else if (*s == no_slash)
87 not = (*p == '!' || *p == '^');
90 if (!k || k == no_slash || k == no_period)
95 if (!*p) return FNM_NOMATCH;
96 if (*p == ']' && !first) break;
98 if (*p == '[' && *(p+1) == ':') {
101 for (z=p; *z && (*z != ':' || *(z+1) != ']'); z++);
102 if (!*z || z-p > 32) { /* FIXME: symbolic const? */
106 memcpy(class, p, z-p);
108 if (iswctype(k, wctype(class)))
114 c = bracket_next(&p);
115 if (c == BRACKET_ERROR)
117 if (c == BRACKET_NOCHAR)
119 if (*p == '-' && *(p+1) != ']') {
121 d = bracket_next(&p);
122 if (d == BRACKET_ERROR)
124 if (d == BRACKET_NOCHAR)
126 if (k >= c && k <= d)
130 if (k == c) match = 1;
140 if (c == no_slash && (flags & FNM_PERIOD)) {
148 if (*s) return FNM_NOMATCH;