Go to the source code of this file.
Functions | |
char * | getenv () |
int internal_function | internal_fnmatch (const char *pattern, const char *string, int no_leading_period, int flags) |
int | fnmatch (pattern, string, flags) const char *pattern |
Variables | |
int | errno |
const char * | string |
int | flags |
|
Referenced by add_cvs_excludes(), auth_client(), do_cmd(), get_panic_action(), getpassf(), internal_fnmatch(), open_socket_out(), open_socket_out_wrapped(), and start_socket_client(). |
|
Definition at line 144 of file fnmatch.c. References flags, getenv(), and string.
00146 { 00147 register const char *p = pattern, *n = string; 00148 register unsigned char c; 00149 00150 /* Note that this evaluates C many times. */ 00151 # ifdef _LIBC 00152 # define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) 00153 # else 00154 # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) 00155 # endif 00156 00157 while ((c = *p++) != '\0') 00158 { 00159 c = FOLD (c); 00160 00161 switch (c) 00162 { 00163 case '?': 00164 if (*n == '\0') 00165 return FNM_NOMATCH; 00166 else if (*n == '/' && (flags & FNM_FILE_NAME)) 00167 return FNM_NOMATCH; 00168 else if (*n == '.' && no_leading_period 00169 && (n == string 00170 || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) 00171 return FNM_NOMATCH; 00172 break; 00173 00174 case '\\': 00175 if (!(flags & FNM_NOESCAPE)) 00176 { 00177 c = *p++; 00178 if (c == '\0') 00179 /* Trailing \ loses. */ 00180 return FNM_NOMATCH; 00181 c = FOLD (c); 00182 } 00183 if (FOLD ((unsigned char) *n) != c) 00184 return FNM_NOMATCH; 00185 break; 00186 00187 case '*': 00188 if (*n == '.' && no_leading_period 00189 && (n == string 00190 || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) 00191 return FNM_NOMATCH; 00192 00193 for (c = *p++; c == '?' || c == '*'; c = *p++) 00194 { 00195 if (*n == '/' && (flags & FNM_FILE_NAME)) 00196 /* A slash does not match a wildcard under FNM_FILE_NAME. */ 00197 return FNM_NOMATCH; 00198 else if (c == '?') 00199 { 00200 /* A ? needs to match one character. */ 00201 if (*n == '\0') 00202 /* There isn't another character; no match. */ 00203 return FNM_NOMATCH; 00204 else 00205 /* One character of the string is consumed in matching 00206 this ? wildcard, so *??? won't match if there are 00207 less than three characters. */ 00208 ++n; 00209 } 00210 } 00211 00212 if (c == '\0') 00213 /* The wildcard(s) is/are the last element of the pattern. 00214 If the name is a file name and contains another slash 00215 this does mean it cannot match. */ 00216 return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL 00217 ? FNM_NOMATCH : 0); 00218 else 00219 { 00220 const char *endp; 00221 00222 #if 0 00223 endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0'); 00224 #else 00225 /* replace call to internal glibc function with equivalent */ 00226 if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL)) 00227 endp = n + strlen(n); 00228 #endif 00229 00230 if (c == '[') 00231 { 00232 int flags2 = ((flags & FNM_FILE_NAME) 00233 ? flags : (flags & ~FNM_PERIOD)); 00234 00235 for (--p; n < endp; ++n) 00236 if (internal_fnmatch (p, n, 00237 (no_leading_period 00238 && (n == string 00239 || (n[-1] == '/' 00240 && (flags 00241 & FNM_FILE_NAME)))), 00242 flags2) 00243 == 0) 00244 return 0; 00245 } 00246 else if (c == '/' && (flags & FNM_FILE_NAME)) 00247 { 00248 while (*n != '\0' && *n != '/') 00249 ++n; 00250 if (*n == '/' 00251 && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD, 00252 flags) == 0)) 00253 return 0; 00254 } 00255 else 00256 { 00257 int flags2 = ((flags & FNM_FILE_NAME) 00258 ? flags : (flags & ~FNM_PERIOD)); 00259 00260 if (c == '\\' && !(flags & FNM_NOESCAPE)) 00261 c = *p; 00262 c = FOLD (c); 00263 for (--p; n < endp; ++n) 00264 if (FOLD ((unsigned char) *n) == c 00265 && (internal_fnmatch (p, n, 00266 (no_leading_period 00267 && (n == string 00268 || (n[-1] == '/' 00269 && (flags 00270 & FNM_FILE_NAME)))), 00271 flags2) == 0)) 00272 return 0; 00273 } 00274 } 00275 00276 /* If we come here no match is possible with the wildcard. */ 00277 return FNM_NOMATCH; 00278 00279 case '[': 00280 { 00281 /* Nonzero if the sense of the character class is inverted. */ 00282 static int posixly_correct; 00283 register int not; 00284 char cold; 00285 00286 if (posixly_correct == 0) 00287 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; 00288 00289 if (*n == '\0') 00290 return FNM_NOMATCH; 00291 00292 if (*n == '.' && no_leading_period && (n == string 00293 || (n[-1] == '/' 00294 && (flags 00295 & FNM_FILE_NAME)))) 00296 return FNM_NOMATCH; 00297 00298 if (*n == '/' && (flags & FNM_FILE_NAME)) 00299 /* `/' cannot be matched. */ 00300 return FNM_NOMATCH; 00301 00302 not = (*p == '!' || (posixly_correct < 0 && *p == '^')); 00303 if (not) 00304 ++p; 00305 00306 c = *p++; 00307 for (;;) 00308 { 00309 unsigned char fn = FOLD ((unsigned char) *n); 00310 00311 if (!(flags & FNM_NOESCAPE) && c == '\\') 00312 { 00313 if (*p == '\0') 00314 return FNM_NOMATCH; 00315 c = FOLD ((unsigned char) *p); 00316 ++p; 00317 00318 if (c == fn) 00319 goto matched; 00320 } 00321 else if (c == '[' && *p == ':') 00322 { 00323 /* Leave room for the null. */ 00324 char str[CHAR_CLASS_MAX_LENGTH + 1]; 00325 size_t c1 = 0; 00326 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) 00327 wctype_t wt; 00328 # endif 00329 const char *startp = p; 00330 00331 for (;;) 00332 { 00333 if (c1 == CHAR_CLASS_MAX_LENGTH) 00334 /* The name is too long and therefore the pattern 00335 is ill-formed. */ 00336 return FNM_NOMATCH; 00337 00338 c = *++p; 00339 if (c == ':' && p[1] == ']') 00340 { 00341 p += 2; 00342 break; 00343 } 00344 if (c < 'a' || c >= 'z') 00345 { 00346 /* This cannot possibly be a character class name. 00347 Match it as a normal range. */ 00348 p = startp; 00349 c = '['; 00350 goto normal_bracket; 00351 } 00352 str[c1++] = c; 00353 } 00354 str[c1] = '\0'; 00355 00356 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) 00357 wt = IS_CHAR_CLASS (str); 00358 if (wt == 0) 00359 /* Invalid character class name. */ 00360 return FNM_NOMATCH; 00361 00362 if (__iswctype (__btowc ((unsigned char) *n), wt)) 00363 goto matched; 00364 # else 00365 if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n)) 00366 || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n)) 00367 || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n)) 00368 || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n)) 00369 || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n)) 00370 || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n)) 00371 || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n)) 00372 || (STREQ (str, "print") && ISPRINT ((unsigned char) *n)) 00373 || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n)) 00374 || (STREQ (str, "space") && ISSPACE ((unsigned char) *n)) 00375 || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n)) 00376 || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n))) 00377 goto matched; 00378 # endif 00379 } 00380 else if (c == '\0') 00381 /* [ (unterminated) loses. */ 00382 return FNM_NOMATCH; 00383 else 00384 { 00385 normal_bracket: 00386 if (FOLD (c) == fn) 00387 goto matched; 00388 00389 cold = c; 00390 c = *p++; 00391 00392 if (c == '-' && *p != ']') 00393 { 00394 /* It is a range. */ 00395 unsigned char cend = *p++; 00396 if (!(flags & FNM_NOESCAPE) && cend == '\\') 00397 cend = *p++; 00398 if (cend == '\0') 00399 return FNM_NOMATCH; 00400 00401 if (cold <= fn && fn <= FOLD (cend)) 00402 goto matched; 00403 00404 c = *p++; 00405 } 00406 } 00407 00408 if (c == ']') 00409 break; 00410 } 00411 00412 if (!not) 00413 return FNM_NOMATCH; 00414 break; 00415 00416 matched: 00417 /* Skip the rest of the [...] that already matched. */ 00418 while (c != ']') 00419 { 00420 if (c == '\0') 00421 /* [... (unterminated) loses. */ 00422 return FNM_NOMATCH; 00423 00424 c = *p++; 00425 if (!(flags & FNM_NOESCAPE) && c == '\\') 00426 { 00427 if (*p == '\0') 00428 return FNM_NOMATCH; 00429 /* XXX 1003.2d11 is unclear if this is right. */ 00430 ++p; 00431 } 00432 else if (c == '[' && *p == ':') 00433 { 00434 do 00435 if (*++p == '\0') 00436 return FNM_NOMATCH; 00437 while (*p != ':' || p[1] == ']'); 00438 p += 2; 00439 c = *p; 00440 } 00441 } 00442 if (not) 00443 return FNM_NOMATCH; 00444 } 00445 break; 00446 00447 default: 00448 if (c != FOLD ((unsigned char) *n)) 00449 return FNM_NOMATCH; 00450 } 00451 00452 ++n; 00453 } 00454 00455 if (*n == '\0') 00456 return 0; 00457 00458 if ((flags & FNM_LEADING_DIR) && *n == '/') 00459 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ 00460 return 0; 00461 00462 return FNM_NOMATCH; 00463 00464 # undef FOLD 00465 } |
|
Referenced by auth_server(), check_one_exclude(), make_exclude(), match_hostname(), and set_compression(). |
|
|
|
Definition at line 471 of file fnmatch.c. Referenced by internal_fnmatch(). |
|
Definition at line 472 of file fnmatch.c. Referenced by internal_fnmatch(). |