added --existing option, similar to one suggested by Gildas Quiniou <gildas@stip.fr>
[rsync/rsync.git] / lib / fnmatch.c
CommitLineData
c627d613
AT
1#include "../rsync.h"
2#ifndef HAVE_FNMATCH
3
9dce9b45 4/* ----- THE FOLLOWING UP TO 'END' is glibc-2.1.2 posix/fnmatch.c
c08bb0fb 5 except for the parts with '#if 0' */
c627d613 6
9dce9b45
DD
7/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
8 This file is part of the GNU C Library.
c627d613 9
9dce9b45
DD
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public License as
12 published by the Free Software Foundation; either version 2 of the
13 License, or (at your option) any later version.
c627d613 14
9dce9b45
DD
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
c627d613 19
9dce9b45
DD
20 You should have received a copy of the GNU Library General Public
21 License along with this library; see the file COPYING.LIB. If not,
22 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
c627d613 24
c08bb0fb
DD
25#if 0 /* header files included better by ../rsync.h */
26
9dce9b45
DD
27#if HAVE_CONFIG_H
28# include <config.h>
29#endif
30
31/* Enable GNU extensions in fnmatch.h. */
32#ifndef _GNU_SOURCE
33# define _GNU_SOURCE 1
34#endif
35
36#include <errno.h>
37#include <fnmatch.h>
38#include <ctype.h>
39
40#if HAVE_STRING_H || defined _LIBC
41# include <string.h>
c627d613 42#else
9dce9b45 43# include <strings.h>
c627d613
AT
44#endif
45
9dce9b45
DD
46#if defined STDC_HEADERS || defined _LIBC
47# include <stdlib.h>
48#endif
c627d613 49
c08bb0fb
DD
50#endif /* 0 */
51
9dce9b45
DD
52/* For platform which support the ISO C amendement 1 functionality we
53 support user defined character classes. */
54#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
55/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
56# include <wchar.h>
57# include <wctype.h>
58#endif
c627d613
AT
59
60/* Comment out all this code if we are using the GNU C Library, and are not
61 actually compiling the library itself. This code is part of the GNU C
62 Library, but also included in many other GNU distributions. Compiling
63 and linking in this code is a waste when using the GNU C library
64 (especially if it is a shared library). Rather than having every GNU
65 program understand `configure --with-gnu-libc' and omit the object files,
66 it is simpler to just do this in the source for each such file. */
67
9dce9b45
DD
68#if defined _LIBC || !defined __GNU_LIBRARY__
69
70
71# if defined STDC_HEADERS || !defined isascii
72# define ISASCII(c) 1
73# else
74# define ISASCII(c) isascii(c)
75# endif
76
77#ifdef isblank
78# define ISBLANK(c) (ISASCII (c) && isblank (c))
79#else
80# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
c627d613 81#endif
9dce9b45
DD
82#ifdef isgraph
83# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
84#else
85# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
86#endif
87
88#define ISPRINT(c) (ISASCII (c) && isprint (c))
89#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
90#define ISALNUM(c) (ISASCII (c) && isalnum (c))
91#define ISALPHA(c) (ISASCII (c) && isalpha (c))
92#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
93#define ISLOWER(c) (ISASCII (c) && islower (c))
94#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
95#define ISSPACE(c) (ISASCII (c) && isspace (c))
96#define ISUPPER(c) (ISASCII (c) && isupper (c))
97#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
98
99# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
100
101# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
102/* The GNU C library provides support for user-defined character classes
103 and the functions from ISO C amendement 1. */
104# ifdef CHARCLASS_NAME_MAX
105# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
106# else
107/* This shouldn't happen but some implementation might still have this
108 problem. Use a reasonable default value. */
109# define CHAR_CLASS_MAX_LENGTH 256
110# endif
111
112# ifdef _LIBC
113# define IS_CHAR_CLASS(string) __wctype (string)
114# else
115# define IS_CHAR_CLASS(string) wctype (string)
116# endif
117# else
118# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
119
120# define IS_CHAR_CLASS(string) \
121 (STREQ (string, "alpha") || STREQ (string, "upper") \
122 || STREQ (string, "lower") || STREQ (string, "digit") \
123 || STREQ (string, "alnum") || STREQ (string, "xdigit") \
124 || STREQ (string, "space") || STREQ (string, "print") \
125 || STREQ (string, "punct") || STREQ (string, "graph") \
126 || STREQ (string, "cntrl") || STREQ (string, "blank"))
127# endif
128
129/* Avoid depending on library functions or files
130 whose names are inconsistent. */
131
132# if !defined _LIBC && !defined getenv
133extern char *getenv ();
134# endif
135
136# ifndef errno
137extern int errno;
138# endif
c627d613
AT
139
140/* Match STRING against the filename pattern PATTERN, returning zero if
141 it matches, nonzero if not. */
9dce9b45
DD
142static int
143#ifdef _LIBC
144internal_function
145#endif
146internal_fnmatch (const char *pattern, const char *string,
147 int no_leading_period, int flags)
c627d613
AT
148{
149 register const char *p = pattern, *n = string;
9dce9b45 150 register unsigned char c;
c627d613 151
9dce9b45
DD
152/* Note that this evaluates C many times. */
153# ifdef _LIBC
154# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
155# else
156# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
157# endif
c627d613
AT
158
159 while ((c = *p++) != '\0')
160 {
161 c = FOLD (c);
162
163 switch (c)
164 {
165 case '?':
166 if (*n == '\0')
167 return FNM_NOMATCH;
9dce9b45 168 else if (*n == '/' && (flags & FNM_FILE_NAME))
c627d613 169 return FNM_NOMATCH;
9dce9b45
DD
170 else if (*n == '.' && no_leading_period
171 && (n == string
172 || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
c627d613
AT
173 return FNM_NOMATCH;
174 break;
175
176 case '\\':
177 if (!(flags & FNM_NOESCAPE))
178 {
179 c = *p++;
9dce9b45
DD
180 if (c == '\0')
181 /* Trailing \ loses. */
182 return FNM_NOMATCH;
c627d613
AT
183 c = FOLD (c);
184 }
9dce9b45 185 if (FOLD ((unsigned char) *n) != c)
c627d613
AT
186 return FNM_NOMATCH;
187 break;
188
189 case '*':
9dce9b45
DD
190 if (*n == '.' && no_leading_period
191 && (n == string
192 || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
c627d613
AT
193 return FNM_NOMATCH;
194
9dce9b45
DD
195 for (c = *p++; c == '?' || c == '*'; c = *p++)
196 {
197 if (*n == '/' && (flags & FNM_FILE_NAME))
198 /* A slash does not match a wildcard under FNM_FILE_NAME. */
199 return FNM_NOMATCH;
200 else if (c == '?')
201 {
202 /* A ? needs to match one character. */
203 if (*n == '\0')
204 /* There isn't another character; no match. */
205 return FNM_NOMATCH;
206 else
207 /* One character of the string is consumed in matching
208 this ? wildcard, so *??? won't match if there are
209 less than three characters. */
210 ++n;
211 }
212 }
c627d613
AT
213
214 if (c == '\0')
9dce9b45
DD
215 /* The wildcard(s) is/are the last element of the pattern.
216 If the name is a file name and contains another slash
217 this does mean it cannot match. */
218 return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
219 ? FNM_NOMATCH : 0);
220 else
221 {
222 const char *endp;
c627d613 223
9dce9b45
DD
224#if 0
225 endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
226#else
227/* replace call to internal glibc function with equivalent */
228 if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL))
229 endp = n + strlen(n);
230#endif
231
232 if (c == '[')
233 {
234 int flags2 = ((flags & FNM_FILE_NAME)
235 ? flags : (flags & ~FNM_PERIOD));
236
237 for (--p; n < endp; ++n)
238 if (internal_fnmatch (p, n,
239 (no_leading_period
240 && (n == string
241 || (n[-1] == '/'
242 && (flags
243 & FNM_FILE_NAME)))),
244 flags2)
245 == 0)
246 return 0;
247 }
248 else if (c == '/' && (flags & FNM_FILE_NAME))
249 {
250 while (*n != '\0' && *n != '/')
251 ++n;
252 if (*n == '/'
253 && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
254 flags) == 0))
255 return 0;
256 }
257 else
258 {
259 int flags2 = ((flags & FNM_FILE_NAME)
260 ? flags : (flags & ~FNM_PERIOD));
261
262 if (c == '\\' && !(flags & FNM_NOESCAPE))
263 c = *p;
264 c = FOLD (c);
265 for (--p; n < endp; ++n)
266 if (FOLD ((unsigned char) *n) == c
267 && (internal_fnmatch (p, n,
268 (no_leading_period
269 && (n == string
270 || (n[-1] == '/'
271 && (flags
272 & FNM_FILE_NAME)))),
273 flags2) == 0))
274 return 0;
275 }
276 }
277
278 /* If we come here no match is possible with the wildcard. */
279 return FNM_NOMATCH;
c627d613
AT
280
281 case '[':
282 {
283 /* Nonzero if the sense of the character class is inverted. */
9dce9b45 284 static int posixly_correct;
c627d613 285 register int not;
9dce9b45
DD
286 char cold;
287
288 if (posixly_correct == 0)
289 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
c627d613
AT
290
291 if (*n == '\0')
292 return FNM_NOMATCH;
293
9dce9b45
DD
294 if (*n == '.' && no_leading_period && (n == string
295 || (n[-1] == '/'
296 && (flags
297 & FNM_FILE_NAME))))
298 return FNM_NOMATCH;
299
300 if (*n == '/' && (flags & FNM_FILE_NAME))
301 /* `/' cannot be matched. */
c627d613
AT
302 return FNM_NOMATCH;
303
9dce9b45 304 not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
c627d613
AT
305 if (not)
306 ++p;
307
308 c = *p++;
309 for (;;)
310 {
9dce9b45 311 unsigned char fn = FOLD ((unsigned char) *n);
c627d613
AT
312
313 if (!(flags & FNM_NOESCAPE) && c == '\\')
9dce9b45
DD
314 {
315 if (*p == '\0')
316 return FNM_NOMATCH;
317 c = FOLD ((unsigned char) *p);
318 ++p;
c627d613 319
9dce9b45
DD
320 if (c == fn)
321 goto matched;
322 }
323 else if (c == '[' && *p == ':')
324 {
325 /* Leave room for the null. */
326 char str[CHAR_CLASS_MAX_LENGTH + 1];
327 size_t c1 = 0;
328# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
329 wctype_t wt;
330# endif
331 const char *startp = p;
332
333 for (;;)
334 {
335 if (c1 == CHAR_CLASS_MAX_LENGTH)
336 /* The name is too long and therefore the pattern
337 is ill-formed. */
338 return FNM_NOMATCH;
339
340 c = *++p;
341 if (c == ':' && p[1] == ']')
342 {
343 p += 2;
344 break;
345 }
346 if (c < 'a' || c >= 'z')
347 {
348 /* This cannot possibly be a character class name.
349 Match it as a normal range. */
350 p = startp;
351 c = '[';
352 goto normal_bracket;
353 }
354 str[c1++] = c;
355 }
356 str[c1] = '\0';
357
358# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
359 wt = IS_CHAR_CLASS (str);
360 if (wt == 0)
361 /* Invalid character class name. */
362 return FNM_NOMATCH;
c627d613 363
9dce9b45
DD
364 if (__iswctype (__btowc ((unsigned char) *n), wt))
365 goto matched;
366# else
367 if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
368 || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
369 || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
370 || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
371 || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
372 || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
373 || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
374 || (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
375 || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
376 || (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
377 || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
378 || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
379 goto matched;
380# endif
381 }
382 else if (c == '\0')
c627d613
AT
383 /* [ (unterminated) loses. */
384 return FNM_NOMATCH;
9dce9b45
DD
385 else
386 {
387 normal_bracket:
388 if (FOLD (c) == fn)
389 goto matched;
c627d613 390
9dce9b45
DD
391 cold = c;
392 c = *p++;
c627d613 393
9dce9b45
DD
394 if (c == '-' && *p != ']')
395 {
396 /* It is a range. */
397 unsigned char cend = *p++;
398 if (!(flags & FNM_NOESCAPE) && cend == '\\')
399 cend = *p++;
400 if (cend == '\0')
401 return FNM_NOMATCH;
c627d613 402
9dce9b45
DD
403 if (cold <= fn && fn <= FOLD (cend))
404 goto matched;
c627d613 405
9dce9b45
DD
406 c = *p++;
407 }
c627d613
AT
408 }
409
c627d613
AT
410 if (c == ']')
411 break;
412 }
9dce9b45 413
c627d613
AT
414 if (!not)
415 return FNM_NOMATCH;
416 break;
417
9dce9b45 418 matched:
c627d613
AT
419 /* Skip the rest of the [...] that already matched. */
420 while (c != ']')
421 {
422 if (c == '\0')
423 /* [... (unterminated) loses. */
424 return FNM_NOMATCH;
425
426 c = *p++;
427 if (!(flags & FNM_NOESCAPE) && c == '\\')
9dce9b45
DD
428 {
429 if (*p == '\0')
430 return FNM_NOMATCH;
431 /* XXX 1003.2d11 is unclear if this is right. */
432 ++p;
433 }
434 else if (c == '[' && *p == ':')
435 {
436 do
437 if (*++p == '\0')
438 return FNM_NOMATCH;
439 while (*p != ':' || p[1] == ']');
440 p += 2;
441 c = *p;
442 }
c627d613
AT
443 }
444 if (not)
445 return FNM_NOMATCH;
446 }
447 break;
448
449 default:
9dce9b45 450 if (c != FOLD ((unsigned char) *n))
c627d613
AT
451 return FNM_NOMATCH;
452 }
453
454 ++n;
455 }
456
457 if (*n == '\0')
458 return 0;
459
460 if ((flags & FNM_LEADING_DIR) && *n == '/')
461 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
462 return 0;
463
464 return FNM_NOMATCH;
9dce9b45
DD
465
466# undef FOLD
c627d613
AT
467}
468
9dce9b45
DD
469
470int
471fnmatch (pattern, string, flags)
472 const char *pattern;
473 const char *string;
474 int flags;
475{
476 return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
477}
478
479#endif /* _LIBC or not __GNU_LIBRARY__. */
480/* ----- END glibc-2.1.2 posix/fnmatch.c */
481
c627d613
AT
482#else /* HAVE_FNMATCH */
483void fnmatch_dummy(void) {}
484#endif