1 /* Copyright (C) 1992 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details. */
14 /* Modified slightly by Brian Berliner <berliner@sun.com> and
15 Jim Blandy <jimb@cyclic.com> for CVS use */
21 /* Some file systems are case-insensitive. If FOLD_FN_CHAR is
22 #defined, it maps the character C onto its "canonical" form. In a
23 case-insensitive system, it would map all alphanumeric characters
24 to lower case. Under Windows NT, / and \ are both path component
25 separators, so FOLD_FN_CHAR would map them both to /. */
27 #define FOLD_FN_CHAR(c) (c)
31 /* #include <ansidecl.h> */
36 #if !defined(__GNU_LIBRARY__) \
37 && !defined(STDC_HEADERS) \
38 && !defined(_CRT_ERRNO_DEFINED)
42 /* Match STRING against the filename pattern PATTERN, returning zero if
43 it matches, nonzero if not. */
46 fnmatch (const char *pattern
, const char *string
, int flags
)
48 fnmatch (pattern
, string
, flags
)
54 register const char *p
= pattern
, *n
= string
;
57 if ((flags
& ~__FNM_FLAGS
) != 0)
63 while ((c
= *p
++) != '\0')
70 else if ((flags
& FNM_PATHNAME
) && *n
== '/')
72 else if ((flags
& FNM_PERIOD
) && *n
== '.' &&
73 (n
== string
|| ((flags
& FNM_PATHNAME
) && n
[-1] == '/')))
78 if (!(flags
& FNM_NOESCAPE
))
85 if ((flags
& FNM_PERIOD
) && *n
== '.' &&
86 (n
== string
|| ((flags
& FNM_PATHNAME
) && n
[-1] == '/')))
89 for (c
= *p
++; c
== '?' || c
== '*'; c
= *p
++, ++n
)
90 if (((flags
& FNM_PATHNAME
) && *n
== '/') ||
91 (c
== '?' && *n
== '\0'))
98 char c1
= (!(flags
& FNM_NOESCAPE
) && c
== '\\') ? *p
: c
;
99 for (--p
; *n
!= '\0'; ++n
)
100 if ((c
== '[' || *n
== c1
) &&
101 fnmatch(p
, n
, flags
& ~FNM_PERIOD
) == 0)
108 /* Nonzero if the sense of the character class is inverted. */
114 if ((flags
& FNM_PERIOD
) && *n
== '.' &&
115 (n
== string
|| ((flags
& FNM_PATHNAME
) && n
[-1] == '/')))
118 not = (*p
== '!' || *p
== '^');
125 register char cstart
= c
, cend
= c
;
127 if (!(flags
& FNM_NOESCAPE
) && c
== '\\')
128 cstart
= cend
= *p
++;
131 /* [ (unterminated) loses. */
136 if ((flags
& FNM_PATHNAME
) && c
== '/')
137 /* [/] can never match. */
140 if (c
== '-' && *p
!= ']')
143 if (!(flags
& FNM_NOESCAPE
) && cend
== '\\')
150 if (*n
>= cstart
&& *n
<= cend
)
161 /* Skip the rest of the [...] that already matched. */
165 /* [... (unterminated) loses. */
169 if (!(flags
& FNM_NOESCAPE
) && c
== '\\')
170 /* 1003.2d11 is unclear if this is right. %%% */
179 if (FOLD_FN_CHAR (c
) != FOLD_FN_CHAR (*n
))