3
* This file is included as part of the Grid Engine source
4
* to provide the fnmatch C library function for the NEC SX
5
* platform which does not have this function.
8
/* $OpenBSD: fnmatch.c,v 1.7 2000/03/23 19:13:51 millert Exp $ */
11
* Copyright (c) 1989, 1993, 1994
12
* The Regents of the University of California. All rights reserved.
14
* This code is derived from software contributed to Berkeley by
17
* Redistribution and use in source and binary forms, with or without
18
* modification, are permitted provided that the following conditions
20
* 1. Redistributions of source code must retain the above copyright
21
* notice, this list of conditions and the following disclaimer.
22
* 2. Redistributions in binary form must reproduce the above copyright
23
* notice, this list of conditions and the following disclaimer in the
24
* documentation and/or other materials provided with the distribution.
25
* 3. All advertising materials mentioning features or use of this software
26
* must display the following acknowledgement:
27
* This product includes software developed by the University of
28
* California, Berkeley and its contributors.
29
* 4. Neither the name of the University nor the names of its contributors
30
* may be used to endorse or promote products derived from this software
31
* without specific prior written permission.
33
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46
#if defined(LIBC_SCCS) && !defined(lint)
48
(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
50
static char rcsid[] = "$OpenBSD: fnmatch.c,v 1.7 2000/03/23 19:13:51 millert Exp $";
52
#endif /* LIBC_SCCS and not lint */
55
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
56
* Compares a filename or pathname to a pattern.
67
#define RANGE_NOMATCH 0
68
#define RANGE_ERROR (-1)
70
static int rangematch (const char *, char, int, char **);
73
fnmatch(pattern, string, flags)
74
const char *pattern, *string;
77
const char *stringstart;
81
for (stringstart = string;;)
82
switch (c = *pattern++) {
84
if ((flags & FNM_LEADING_DIR) && *string == '/')
86
return (*string == EOS ? 0 : FNM_NOMATCH);
90
if (*string == '/' && (flags & FNM_PATHNAME))
92
if (*string == '.' && (flags & FNM_PERIOD) &&
93
(string == stringstart ||
94
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
100
/* Collapse multiple stars. */
104
if (*string == '.' && (flags & FNM_PERIOD) &&
105
(string == stringstart ||
106
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
107
return (FNM_NOMATCH);
109
/* Optimize for pattern with * at end or before /. */
111
if (flags & FNM_PATHNAME)
112
return ((flags & FNM_LEADING_DIR) ||
113
strchr(string, '/') == NULL ?
117
} else if (c == '/' && (flags & FNM_PATHNAME)) {
118
if ((string = strchr(string, '/')) == NULL)
119
return (FNM_NOMATCH);
123
/* General case, use recursion. */
124
while ((test = *string) != EOS) {
125
if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
127
if (test == '/' && (flags & FNM_PATHNAME))
131
return (FNM_NOMATCH);
134
return (FNM_NOMATCH);
135
if (*string == '/' && (flags & FNM_PATHNAME))
136
return (FNM_NOMATCH);
137
if (*string == '.' && (flags & FNM_PERIOD) &&
138
(string == stringstart ||
139
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
140
return (FNM_NOMATCH);
142
switch (rangematch(pattern, *string, flags, &newp)) {
144
/* not a good range, treat as normal text */
150
return (FNM_NOMATCH);
155
if (!(flags & FNM_NOESCAPE)) {
156
if ((c = *pattern++) == EOS) {
164
if (c != *string && !((flags & FNM_CASEFOLD) &&
165
(tolower((unsigned char)c) ==
166
tolower((unsigned char)*string))))
167
return (FNM_NOMATCH);
176
rangematch(const char *pattern, char test, int flags, char **newp)
178
rangematch(pattern, test, flags, newp)
189
* A bracket expression starting with an unquoted circumflex
190
* character produces unspecified results (IEEE 1003.2-1992,
191
* 3.13.2). This implementation treats it like '!', for
192
* consistency with the regular expression syntax.
195
if ((negate = (*pattern == '!' || *pattern == '^')))
198
if (flags & FNM_CASEFOLD)
199
test = tolower((unsigned char)test);
202
* A right bracket shall lose its special meaning and represent
203
* itself in a bracket expression if it occurs first in the list.
209
if (c == '\\' && !(flags & FNM_NOESCAPE))
212
return (RANGE_ERROR);
213
if (c == '/' && (flags & FNM_PATHNAME))
214
return (RANGE_NOMATCH);
215
if ((flags & FNM_CASEFOLD))
216
c = tolower((unsigned char)c);
218
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
220
if (c2 == '\\' && !(flags & FNM_NOESCAPE))
223
return (RANGE_ERROR);
224
if (flags & FNM_CASEFOLD)
225
c2 = tolower((unsigned char)c2);
226
if (c <= test && test <= c2)
228
} else if (c == test)
230
} while ((c = *pattern++) != ']');
232
*newp = (char *)pattern;
233
return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);