| 179 | } |
| 180 | |
| 181 | static int |
| 182 | rangematch(const char *pattern, char test, int flags, char **newp) |
| 183 | { |
| 184 | int negate, ok; |
| 185 | char c, c2; |
| 186 | |
| 187 | /* |
| 188 | * A bracket expression starting with an unquoted circumflex |
| 189 | * character produces unspecified results (IEEE 1003.2-1992, |
| 190 | * 3.13.2). This implementation treats it like '!', for |
| 191 | * consistency with the regular expression syntax. |
| 192 | * J.T. Conklin (conklin@ngai.kaleida.com) |
| 193 | */ |
| 194 | if ( (negate = (*pattern == '!' || *pattern == '^')) ) |
| 195 | ++pattern; |
| 196 | |
| 197 | if (flags & FNM_CASEFOLD) |
| 198 | test = tolower((unsigned char)test); |
| 199 | |
| 200 | /* |
| 201 | * A right bracket shall lose its special meaning and represent |
| 202 | * itself in a bracket expression if it occurs first in the list. |
| 203 | * -- POSIX.2 2.8.3.2 |
| 204 | */ |
| 205 | ok = 0; |
| 206 | c = *pattern++; |
| 207 | do { |
| 208 | if (c == '\\' && !(flags & FNM_NOESCAPE)) |
| 209 | c = *pattern++; |
| 210 | if (c == EOS) |
| 211 | return (RANGE_ERROR); |
| 212 | |
| 213 | if (c == '/' && (flags & FNM_PATHNAME)) |
| 214 | return (RANGE_NOMATCH); |
| 215 | |
| 216 | if (flags & FNM_CASEFOLD) |
| 217 | c = tolower((unsigned char)c); |
| 218 | |
| 219 | if (*pattern == '-' |
| 220 | && (c2 = *(pattern+1)) != EOS && c2 != ']') { |
| 221 | pattern += 2; |
| 222 | if (c2 == '\\' && !(flags & FNM_NOESCAPE)) |
| 223 | c2 = *pattern++; |
| 224 | if (c2 == EOS) |
| 225 | return (RANGE_ERROR); |
| 226 | |
| 227 | if (flags & FNM_CASEFOLD) |
| 228 | c2 = tolower((unsigned char)c2); |
| 229 | |
| 230 | if (c <= test && test <= c2) |
| 231 | ok = 1; |
| 232 | } else if (c == test) |
| 233 | ok = 1; |
| 234 | } while ((c = *pattern++) != ']'); |
| 235 | |
| 236 | *newp = (char *)(uintptr_t)pattern; |
| 237 | return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); |
| 238 | } |