00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 #if defined (CONFIG_BROKETS)
00023
00024
00025
00026 #include <config.h>
00027 #else
00028 #include "config.h"
00029 #endif
00030 #endif
00031
00032
00033 #ifndef _GNU_SOURCE
00034 #define _GNU_SOURCE
00035 #endif
00036
00037
00038 #ifndef __STDC__
00039
00040
00041 #ifndef const
00042 #define const
00043 #endif
00044 #endif
00045
00046 #include <errno.h>
00047 #include <fnmatch.h>
00048 #include <safe-ctype.h>
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
00059
00060
00061 #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
00062 extern int errno;
00063 #endif
00064
00065
00066
00067 int
00068 fnmatch (pattern, string, flags)
00069 const char *pattern;
00070 const char *string;
00071 int flags;
00072 {
00073 register const char *p = pattern, *n = string;
00074 register unsigned char c;
00075
00076 #define FOLD(c) ((flags & FNM_CASEFOLD) ? TOLOWER (c) : (c))
00077
00078 while ((c = *p++) != '\0')
00079 {
00080 c = FOLD (c);
00081
00082 switch (c)
00083 {
00084 case '?':
00085 if (*n == '\0')
00086 return FNM_NOMATCH;
00087 else if ((flags & FNM_FILE_NAME) && *n == '/')
00088 return FNM_NOMATCH;
00089 else if ((flags & FNM_PERIOD) && *n == '.' &&
00090 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
00091 return FNM_NOMATCH;
00092 break;
00093
00094 case '\\':
00095 if (!(flags & FNM_NOESCAPE))
00096 {
00097 c = *p++;
00098 c = FOLD (c);
00099 }
00100 if (FOLD ((unsigned char)*n) != c)
00101 return FNM_NOMATCH;
00102 break;
00103
00104 case '*':
00105 if ((flags & FNM_PERIOD) && *n == '.' &&
00106 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
00107 return FNM_NOMATCH;
00108
00109 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
00110 if (((flags & FNM_FILE_NAME) && *n == '/') ||
00111 (c == '?' && *n == '\0'))
00112 return FNM_NOMATCH;
00113
00114 if (c == '\0')
00115 return 0;
00116
00117 {
00118 unsigned char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
00119 c1 = FOLD (c1);
00120 for (--p; *n != '\0'; ++n)
00121 if ((c == '[' || FOLD ((unsigned char)*n) == c1) &&
00122 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
00123 return 0;
00124 return FNM_NOMATCH;
00125 }
00126
00127 case '[':
00128 {
00129
00130 register int not;
00131
00132 if (*n == '\0')
00133 return FNM_NOMATCH;
00134
00135 if ((flags & FNM_PERIOD) && *n == '.' &&
00136 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
00137 return FNM_NOMATCH;
00138
00139 not = (*p == '!' || *p == '^');
00140 if (not)
00141 ++p;
00142
00143 c = *p++;
00144 for (;;)
00145 {
00146 register unsigned char cstart = c, cend = c;
00147
00148 if (!(flags & FNM_NOESCAPE) && c == '\\')
00149 cstart = cend = *p++;
00150
00151 cstart = cend = FOLD (cstart);
00152
00153 if (c == '\0')
00154
00155 return FNM_NOMATCH;
00156
00157 c = *p++;
00158 c = FOLD (c);
00159
00160 if ((flags & FNM_FILE_NAME) && c == '/')
00161
00162 return FNM_NOMATCH;
00163
00164 if (c == '-' && *p != ']')
00165 {
00166 cend = *p++;
00167 if (!(flags & FNM_NOESCAPE) && cend == '\\')
00168 cend = *p++;
00169 if (cend == '\0')
00170 return FNM_NOMATCH;
00171 cend = FOLD (cend);
00172
00173 c = *p++;
00174 }
00175
00176 if (FOLD ((unsigned char)*n) >= cstart
00177 && FOLD ((unsigned char)*n) <= cend)
00178 goto matched;
00179
00180 if (c == ']')
00181 break;
00182 }
00183 if (!not)
00184 return FNM_NOMATCH;
00185 break;
00186
00187 matched:;
00188
00189 while (c != ']')
00190 {
00191 if (c == '\0')
00192
00193 return FNM_NOMATCH;
00194
00195 c = *p++;
00196 if (!(flags & FNM_NOESCAPE) && c == '\\')
00197
00198 ++p;
00199 }
00200 if (not)
00201 return FNM_NOMATCH;
00202 }
00203 break;
00204
00205 default:
00206 if (c != FOLD ((unsigned char)*n))
00207 return FNM_NOMATCH;
00208 }
00209
00210 ++n;
00211 }
00212
00213 if (*n == '\0')
00214 return 0;
00215
00216 if ((flags & FNM_LEADING_DIR) && *n == '/')
00217
00218 return 0;
00219
00220 return FNM_NOMATCH;
00221 }
00222
00223 #endif