45#include <sys/libkern.h>
50#define RANGE_NOMATCH 0
51#define RANGE_ERROR (-1)
53static int rangematch(
const char *,
char,
int,
char **);
56fnmatch(
const char *pattern,
const char *
string,
int flags)
58 const char *stringstart;
62 for (stringstart =
string;;)
63 switch (
c = *pattern++) {
65 if ((flags & FNM_LEADING_DIR) && *
string ==
'/')
67 return (*
string ==
EOS ? 0 : FNM_NOMATCH);
71 if (*
string ==
'/' && (flags & FNM_PATHNAME))
73 if (*
string ==
'.' && (flags & FNM_PERIOD) &&
74 (
string == stringstart ||
75 ((flags & FNM_PATHNAME) && *(
string - 1) ==
'/')))
85 if (*
string ==
'.' && (flags & FNM_PERIOD) &&
86 (
string == stringstart ||
87 ((flags & FNM_PATHNAME) && *(
string - 1) ==
'/')))
92 if (flags & FNM_PATHNAME)
93 return ((flags & FNM_LEADING_DIR) ||
94 strchr(
string,
'/') == NULL ?
98 else if (
c ==
'/' && flags & FNM_PATHNAME) {
99 if ((
string =
strchr(
string,
'/')) == NULL)
100 return (FNM_NOMATCH);
105 while ((test = *
string) !=
EOS) {
106 if (!
fnmatch(pattern,
string, flags & ~FNM_PERIOD))
108 if (test ==
'/' && flags & FNM_PATHNAME)
112 return (FNM_NOMATCH);
115 return (FNM_NOMATCH);
116 if (*
string ==
'/' && (flags & FNM_PATHNAME))
117 return (FNM_NOMATCH);
118 if (*
string ==
'.' && (flags & FNM_PERIOD) &&
119 (
string == stringstart ||
120 ((flags & FNM_PATHNAME) && *(
string - 1) ==
'/')))
121 return (FNM_NOMATCH);
123 switch (
rangematch(pattern, *
string, flags, &newp)) {
130 return (FNM_NOMATCH);
135 if (!(flags & FNM_NOESCAPE)) {
136 if ((
c = *pattern++) ==
EOS) {
146 else if ((flags & FNM_CASEFOLD) &&
148 tolower((
unsigned char)*
string)))
151 return (FNM_NOMATCH);
159rangematch(
const char *pattern,
char test,
int flags,
char **newp)
171 if ( (negate = (*pattern ==
'!' || *pattern ==
'^')) )
174 if (flags & FNM_CASEFOLD)
175 test =
tolower((
unsigned char)test);
185 if (
c ==
'\\' && !(flags & FNM_NOESCAPE))
190 if (
c ==
'/' && (flags & FNM_PATHNAME))
193 if (flags & FNM_CASEFOLD)
197 && (c2 = *(pattern+1)) !=
EOS && c2 !=
']') {
199 if (c2 ==
'\\' && !(flags & FNM_NOESCAPE))
204 if (flags & FNM_CASEFOLD)
205 c2 =
tolower((
unsigned char)c2);
207 if (
c <= test && test <= c2)
209 }
else if (
c == test)
211 }
while ((
c = *pattern++) !=
']');
213 *newp = (
char *)(uintptr_t)pattern;
int fnmatch(const char *pattern, const char *string, int flags)
static int rangematch(const char *, char, int, char **)
char * strchr(const char *cp, int ch)