33 #include <sys/cdefs.h>
41 #include <sys/param.h>
42 #include <sys/ctype.h>
43 #include <sys/libkern.h>
48 #define RANGE_NOMATCH 0
49 #define RANGE_ERROR (-1)
51 static int rangematch(
const char *,
char,
int,
char **);
54 fnmatch(
const char *pattern,
const char *
string,
int flags)
56 const char *stringstart;
60 for (stringstart =
string;;)
61 switch (c = *pattern++) {
63 if ((flags & FNM_LEADING_DIR) && *
string ==
'/')
65 return (*
string ==
EOS ? 0 : FNM_NOMATCH);
69 if (*
string ==
'/' && (flags & FNM_PATHNAME))
71 if (*
string ==
'.' && (flags & FNM_PERIOD) &&
72 (
string == stringstart ||
73 ((flags & FNM_PATHNAME) && *(
string - 1) ==
'/')))
83 if (*
string ==
'.' && (flags & FNM_PERIOD) &&
84 (
string == stringstart ||
85 ((flags & FNM_PATHNAME) && *(
string - 1) ==
'/')))
90 if (flags & FNM_PATHNAME)
91 return ((flags & FNM_LEADING_DIR) ||
92 index(
string,
'/') == NULL ?
96 else if (c ==
'/' && flags & FNM_PATHNAME) {
97 if ((
string =
index(
string,
'/')) == NULL)
103 while ((test = *
string) !=
EOS) {
104 if (!
fnmatch(pattern,
string, flags & ~FNM_PERIOD))
106 if (test ==
'/' && flags & FNM_PATHNAME)
110 return (FNM_NOMATCH);
113 return (FNM_NOMATCH);
114 if (*
string ==
'/' && (flags & FNM_PATHNAME))
115 return (FNM_NOMATCH);
116 if (*
string ==
'.' && (flags & FNM_PERIOD) &&
117 (
string == stringstart ||
118 ((flags & FNM_PATHNAME) && *(
string - 1) ==
'/')))
119 return (FNM_NOMATCH);
121 switch (
rangematch(pattern, *
string, flags, &newp)) {
128 return (FNM_NOMATCH);
133 if (!(flags & FNM_NOESCAPE)) {
134 if ((c = *pattern++) ==
EOS) {
144 else if ((flags & FNM_CASEFOLD) &&
146 tolower((
unsigned char)*
string)))
149 return (FNM_NOMATCH);
157 rangematch(
const char *pattern,
char test,
int flags,
char **newp)
169 if ( (negate = (*pattern ==
'!' || *pattern ==
'^')) )
172 if (flags & FNM_CASEFOLD)
173 test =
tolower((
unsigned char)test);
183 if (c ==
'\\' && !(flags & FNM_NOESCAPE))
188 if (c ==
'/' && (flags & FNM_PATHNAME))
191 if (flags & FNM_CASEFOLD)
195 && (c2 = *(pattern+1)) !=
EOS && c2 !=
']') {
197 if (c2 ==
'\\' && !(flags & FNM_NOESCAPE))
202 if (flags & FNM_CASEFOLD)
203 c2 =
tolower((
unsigned char)c2);
205 if (c <= test && test <= c2)
207 }
else if (c == test)
209 }
while ((c = *pattern++) !=
']');
211 *newp = (
char *)(uintptr_t)pattern;
int fnmatch(const char *pattern, const char *string, int flags)
static int rangematch(const char *, char, int, char **)
char * index(char *p, int ch) const