00001 #include "../rsync.h"
00002 #ifndef HAVE_FNMATCH
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #if 0
00026
00027 #if HAVE_CONFIG_H
00028 # include <config.h>
00029 #endif
00030
00031
00032 #ifndef _GNU_SOURCE
00033 # define _GNU_SOURCE 1
00034 #endif
00035
00036 #include <errno.h>
00037 #include <fnmatch.h>
00038 #include <ctype.h>
00039
00040 #if HAVE_STRING_H || defined _LIBC
00041 # include <string.h>
00042 #else
00043 # include <strings.h>
00044 #endif
00045
00046 #if defined STDC_HEADERS || defined _LIBC
00047 # include <stdlib.h>
00048 #endif
00049
00050 #endif
00051
00052
00053 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
00054
00055 # include <wchar.h>
00056 # include <wctype.h>
00057 #endif
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #if 1
00068
00069 # if defined STDC_HEADERS || !defined isascii
00070 # define ISASCII(c) 1
00071 # else
00072 # define ISASCII(c) isascii(c)
00073 # endif
00074
00075 #ifdef isblank
00076 # define ISBLANK(c) (ISASCII (c) && isblank (c))
00077 #else
00078 # define ISBLANK(c) ((c) == ' ' || (c) == '\t')
00079 #endif
00080 #ifdef isgraph
00081 # define ISGRAPH(c) (ISASCII (c) && isgraph (c))
00082 #else
00083 # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
00084 #endif
00085
00086 #define ISPRINT(c) (ISASCII (c) && isprint (c))
00087 #define ISDIGIT(c) (ISASCII (c) && isdigit (c))
00088 #define ISALNUM(c) (ISASCII (c) && isalnum (c))
00089 #define ISALPHA(c) (ISASCII (c) && isalpha (c))
00090 #define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
00091 #define ISLOWER(c) (ISASCII (c) && islower (c))
00092 #define ISPUNCT(c) (ISASCII (c) && ispunct (c))
00093 #define ISSPACE(c) (ISASCII (c) && isspace (c))
00094 #define ISUPPER(c) (ISASCII (c) && isupper (c))
00095 #define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
00096
00097 # define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
00098
00099 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
00100
00101
00102 # ifdef CHARCLASS_NAME_MAX
00103 # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
00104 # else
00105
00106
00107 # define CHAR_CLASS_MAX_LENGTH 256
00108 # endif
00109
00110 # ifdef _LIBC
00111 # define IS_CHAR_CLASS(string) __wctype (string)
00112 # else
00113 # define IS_CHAR_CLASS(string) wctype (string)
00114 # endif
00115 # else
00116 # define CHAR_CLASS_MAX_LENGTH 6
00117
00118 # define IS_CHAR_CLASS(string) \
00119 (STREQ (string, "alpha") || STREQ (string, "upper") \
00120 || STREQ (string, "lower") || STREQ (string, "digit") \
00121 || STREQ (string, "alnum") || STREQ (string, "xdigit") \
00122 || STREQ (string, "space") || STREQ (string, "print") \
00123 || STREQ (string, "punct") || STREQ (string, "graph") \
00124 || STREQ (string, "cntrl") || STREQ (string, "blank"))
00125 # endif
00126
00127
00128
00129
00130 # if !defined _LIBC && !defined getenv
00131 extern char *getenv ();
00132 # endif
00133
00134 # ifndef errno
00135 extern int errno;
00136 # endif
00137
00138
00139
00140 static int
00141 #ifdef _LIBC
00142 internal_function
00143 #endif
00144 internal_fnmatch (const char *pattern, const char *string,
00145 int no_leading_period, int flags)
00146 {
00147 register const char *p = pattern, *n = string;
00148 register unsigned char c;
00149
00150
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
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
00197 return FNM_NOMATCH;
00198 else if (c == '?')
00199 {
00200
00201 if (*n == '\0')
00202
00203 return FNM_NOMATCH;
00204 else
00205
00206
00207
00208 ++n;
00209 }
00210 }
00211
00212 if (c == '\0')
00213
00214
00215
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
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
00277 return FNM_NOMATCH;
00278
00279 case '[':
00280 {
00281
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
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
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
00335
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
00347
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
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
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
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
00418 while (c != ']')
00419 {
00420 if (c == '\0')
00421
00422 return FNM_NOMATCH;
00423
00424 c = *p++;
00425 if (!(flags & FNM_NOESCAPE) && c == '\\')
00426 {
00427 if (*p == '\0')
00428 return FNM_NOMATCH;
00429
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
00460 return 0;
00461
00462 return FNM_NOMATCH;
00463
00464 # undef FOLD
00465 }
00466
00467
00468 int
00469 fnmatch (pattern, string, flags)
00470 const char *pattern;
00471 const char *string;
00472 int flags;
00473 {
00474 return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
00475 }
00476
00477 #endif
00478
00479
00480 #else
00481 void fnmatch_dummy(void) {}
00482 #endif