123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
- #endif
- #include <ctype.h>
- #include <string.h>
- #include <stdio.h>
- #include "fnmatch.h"
- #define EOS '\0'
- static const char *rangematch(const char *, char, int);
- PHPAPI int fnmatch(const char *pattern, const char *string, int flags)
- {
- const char *stringstart;
- char c, test;
- for (stringstart = string;;)
- switch (c = *pattern++) {
- case EOS:
- if ((flags & FNM_LEADING_DIR) && *string == '/')
- return (0);
- return (*string == EOS ? 0 : FNM_NOMATCH);
- case '?':
- if (*string == EOS)
- return (FNM_NOMATCH);
- if (*string == '/' && (flags & FNM_PATHNAME))
- return (FNM_NOMATCH);
- if (*string == '.' && (flags & FNM_PERIOD) &&
- (string == stringstart ||
- ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
- return (FNM_NOMATCH);
- ++string;
- break;
- case '*':
- c = *pattern;
-
- while (c == '*')
- c = *++pattern;
- if (*string == '.' && (flags & FNM_PERIOD) &&
- (string == stringstart ||
- ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
- return (FNM_NOMATCH);
-
- if (c == EOS)
- if (flags & FNM_PATHNAME)
- return ((flags & FNM_LEADING_DIR) ||
- strchr(string, '/') == NULL ?
- 0 : FNM_NOMATCH);
- else
- return (0);
- else if (c == '/' && flags & FNM_PATHNAME) {
- if ((string = strchr(string, '/')) == NULL)
- return (FNM_NOMATCH);
- break;
- }
-
- while ((test = *string) != EOS) {
- if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
- return (0);
- if (test == '/' && flags & FNM_PATHNAME)
- break;
- ++string;
- }
- return (FNM_NOMATCH);
- case '[':
- if (*string == EOS)
- return (FNM_NOMATCH);
- if (*string == '/' && flags & FNM_PATHNAME)
- return (FNM_NOMATCH);
- if ((pattern =
- rangematch(pattern, *string, flags)) == NULL)
- return (FNM_NOMATCH);
- ++string;
- break;
- case '\\':
- if (!(flags & FNM_NOESCAPE)) {
- if ((c = *pattern++) == EOS) {
- c = '\\';
- --pattern;
- }
- }
-
- default:
- if (c == *string)
- ;
- else if ((flags & FNM_CASEFOLD) &&
- (tolower((unsigned char)c) ==
- tolower((unsigned char)*string)))
- ;
- else if ((flags & FNM_PREFIX_DIRS) && *string == EOS &&
- (c == '/' && string != stringstart ||
- string == stringstart+1 && *stringstart == '/') )
- return (0);
- else
- return (FNM_NOMATCH);
- string++;
- break;
- }
-
- }
- static const char *
- rangematch(const char *pattern, char test, int flags)
- {
- int negate, ok;
- char c, c2;
-
- if ( (negate = (*pattern == '!' || *pattern == '^')) )
- ++pattern;
- if (flags & FNM_CASEFOLD)
- test = tolower((unsigned char)test);
- for (ok = 0; (c = *pattern++) != ']';) {
- if (c == '\\' && !(flags & FNM_NOESCAPE))
- c = *pattern++;
- if (c == EOS)
- return (NULL);
- if (flags & FNM_CASEFOLD)
- c = tolower((unsigned char)c);
- if (*pattern == '-'
- && (c2 = *(pattern+1)) != EOS && c2 != ']') {
- pattern += 2;
- if (c2 == '\\' && !(flags & FNM_NOESCAPE))
- c2 = *pattern++;
- if (c2 == EOS)
- return (NULL);
- if (flags & FNM_CASEFOLD)
- c2 = tolower((unsigned char)c2);
- if ((unsigned char)c <= (unsigned char)test &&
- (unsigned char)test <= (unsigned char)c2)
- ok = 1;
- } else if (c == test)
- ok = 1;
- }
- return (ok == negate ? NULL : pattern);
- }
|