2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)fnmatch.c 1.4 02/02/10 eric */
14 /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
16 NOTE: The canonical source of this file is maintained with the GNU C Library.
17 Bugs can be reported to bug-glibc@prep.ai.mit.edu.
19 This program is free software; you can redistribute it and/or modify it
20 under the terms of the GNU General Public License as published by the
21 Free Software Foundation; either version 2, or (at your option) any
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License for more details.
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
46 #define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
49 #ifndef FNM_LEADING_DIR
50 #define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
54 #define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
60 #if defined (STDC_HEADERS) || !defined (isascii)
63 #define ISASCII(c) isascii(c)
66 #define ISUPPER(c) (ISASCII (c) && isupper (c))
69 /* Comment out all this code if we are using the GNU C Library, and are not
70 actually compiling the library itself. This code is part of the GNU C
71 Library, but also included in many other GNU distributions. Compiling
72 and linking in this code is a waste when using the GNU C library
73 (especially if it is a shared library). Rather than having every GNU
74 program understand `configure --with-gnu-libc' and omit the object files,
75 it is simpler to just do this in the source for each such file. */
77 #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
80 #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
84 /* Match STRING against the filename pattern PATTERN, returning zero if
85 it matches, nonzero if not. */
87 fnmatch (const char *pattern, const char *string, int flags)
89 register const char *p = pattern, *n = string;
92 /* Note that this evalutes C many times. */
93 #define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
95 while ((c = *p++) != '\0')
104 else if ((flags & FNM_FILE_NAME) && *n == '/')
106 else if ((flags & FNM_PERIOD) && *n == '.' &&
107 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
112 if (!(flags & FNM_NOESCAPE))
115 c = FOLD ((Uchar )c);
117 if (FOLD ((Uchar )*n) != c)
122 if ((flags & FNM_PERIOD) && *n == '.' &&
123 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
126 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
127 if (((flags & FNM_FILE_NAME) && *n == '/') ||
128 (c == '?' && *n == '\0'))
135 char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
136 c1 = FOLD ((Uchar )c1);
137 for (--p; *n != '\0'; ++n)
138 if ((c == '[' || FOLD ((Uchar )*n) == c1) &&
139 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
146 /* Nonzero if the sense of the character class is inverted. */
152 if ((flags & FNM_PERIOD) && *n == '.' &&
153 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
156 not = (*p == '!' || *p == '^');
163 register char cstart = c, cend = c;
165 if (!(flags & FNM_NOESCAPE) && c == '\\')
166 cstart = cend = *p++;
168 cstart = cend = FOLD ((Uchar)cstart);
171 /* [ (unterminated) loses. */
177 if ((flags & FNM_FILE_NAME) && c == '/')
178 /* [/] can never match. */
181 if (c == '-' && *p != ']')
184 if (!(flags & FNM_NOESCAPE) && cend == '\\')
188 cend = FOLD ((Uchar)cend);
193 if ((Uchar)FOLD((Uchar)*n) >= (Uchar)cstart && (Uchar)FOLD((Uchar)*n) <= (Uchar)cend)
204 /* Skip the rest of the [...] that already matched. */
208 /* [... (unterminated) loses. */
212 if (!(flags & FNM_NOESCAPE) && c == '\\')
213 /* XXX 1003.2d11 is unclear if this is right. */
222 if (c != FOLD ((Uchar)*n))
232 if ((flags & FNM_LEADING_DIR) && *n == '/')
233 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
239 #endif /* _LIBC or not __GNU_LIBRARY__. */