Mercurial > hg > octave-kai > gnulib-hg
annotate lib/fnmatch.c @ 2953:a58bda8b783d
Do not comment out all the code if we are using
the GNU C library, because in some cases we are replacing buggy
code in the GNU C library itself.
author | Jim Meyering <jim@meyering.net> |
---|---|
date | Fri, 03 Nov 2000 08:43:20 +0000 |
parents | a48403c1d85a |
children | d28482de9e26 |
rev | line source |
---|---|
2948
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
1 /* Copyright 1991, 1992, 1993, 1996, 1997, 2000 Free Software Foundation, Inc. |
5 | 2 |
1249 | 3 This program is free software; you can redistribute it and/or modify |
4 it under the terms of the GNU General Public License as published by | |
5 the Free Software Foundation; either version 2, or (at your option) | |
6 any later version. | |
335 | 7 |
763 | 8 This program is distributed in the hope that it will be useful, |
9 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 GNU General Public License for more details. | |
5 | 12 |
1249 | 13 You should have received a copy of the GNU General Public License |
14 along with this program; if not, write to the Free Software Foundation, | |
15 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
5 | 16 |
763 | 17 #if HAVE_CONFIG_H |
18 # include <config.h> | |
77 | 19 #endif |
20 | |
1249 | 21 /* Enable GNU extensions in fnmatch.h. */ |
22 #ifndef _GNU_SOURCE | |
23 # define _GNU_SOURCE 1 | |
24 #endif | |
25 | |
5 | 26 #include <errno.h> |
42 | 27 #include <fnmatch.h> |
28 #include <ctype.h> | |
5 | 29 |
1249 | 30 # if defined STDC_HEADERS || !defined isascii |
2856
21b199ffea14
Rename ISASCII to IN_CTYPE_DOMAIN.
Jim Meyering <jim@meyering.net>
parents:
2807
diff
changeset
|
31 # define IN_CTYPE_DOMAIN(c) 1 |
1249 | 32 # else |
2953
a58bda8b783d
Do not comment out all the code if we are using
Jim Meyering <jim@meyering.net>
parents:
2948
diff
changeset
|
33 # define IN_CTYPE_DOMAIN(c) isascii (c) |
1249 | 34 # endif |
35 | |
2856
21b199ffea14
Rename ISASCII to IN_CTYPE_DOMAIN.
Jim Meyering <jim@meyering.net>
parents:
2807
diff
changeset
|
36 # define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c)) |
1249 | 37 |
763 | 38 |
39 # ifndef errno | |
5 | 40 extern int errno; |
763 | 41 # endif |
5 | 42 |
43 /* Match STRING against the filename pattern PATTERN, returning zero if | |
44 it matches, nonzero if not. */ | |
45 int | |
1557 | 46 fnmatch (const char *pattern, const char *string, int flags) |
5 | 47 { |
48 register const char *p = pattern, *n = string; | |
49 register char c; | |
50 | |
884 | 51 /* Note that this evaluates C many times. */ |
2948
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
52 # define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER ((unsigned char) (c)) \ |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
53 ? tolower ((unsigned char) (c)) \ |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
54 : (c)) |
5 | 55 |
56 while ((c = *p++) != '\0') | |
57 { | |
42 | 58 c = FOLD (c); |
59 | |
5 | 60 switch (c) |
61 { | |
62 case '?': | |
63 if (*n == '\0') | |
64 return FNM_NOMATCH; | |
42 | 65 else if ((flags & FNM_FILE_NAME) && *n == '/') |
5 | 66 return FNM_NOMATCH; |
67 else if ((flags & FNM_PERIOD) && *n == '.' && | |
42 | 68 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) |
5 | 69 return FNM_NOMATCH; |
70 break; | |
71 | |
72 case '\\': | |
73 if (!(flags & FNM_NOESCAPE)) | |
42 | 74 { |
75 c = *p++; | |
1249 | 76 if (c == '\0') |
77 /* Trailing \ loses. */ | |
78 return FNM_NOMATCH; | |
42 | 79 c = FOLD (c); |
80 } | |
81 if (FOLD (*n) != c) | |
5 | 82 return FNM_NOMATCH; |
83 break; | |
84 | |
85 case '*': | |
86 if ((flags & FNM_PERIOD) && *n == '.' && | |
42 | 87 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) |
5 | 88 return FNM_NOMATCH; |
89 | |
1249 | 90 for (c = *p++; c == '?' || c == '*'; c = *p++) |
91 { | |
2948
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
92 if (c == '?') |
1249 | 93 { |
94 /* A ? needs to match one character. */ | |
2948
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
95 if (*n == '\0' || (*n == '/' && (flags & FNM_FILE_NAME))) |
1249 | 96 /* There isn't another character; no match. */ |
97 return FNM_NOMATCH; | |
98 else | |
99 /* One character of the string is consumed in matching | |
100 this ? wildcard, so *??? won't match if there are | |
101 less than three characters. */ | |
102 ++n; | |
103 } | |
104 } | |
5 | 105 |
106 if (c == '\0') | |
2948
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
107 { |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
108 if ((flags & (FNM_FILE_NAME | FNM_LEADING_DIR)) == FNM_FILE_NAME) |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
109 for (; *n != '\0'; n++) |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
110 if (*n == '/') |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
111 return FNM_NOMATCH; |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
112 return 0; |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
113 } |
5 | 114 |
115 { | |
116 char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; | |
42 | 117 c1 = FOLD (c1); |
5 | 118 for (--p; *n != '\0'; ++n) |
42 | 119 if ((c == '[' || FOLD (*n) == c1) && |
5 | 120 fnmatch (p, n, flags & ~FNM_PERIOD) == 0) |
121 return 0; | |
2948
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
122 else if (*n == '/' && (flags & FNM_FILE_NAME)) |
a48403c1d85a
(FOLD): Do not assume that characters are unsigned.
Jim Meyering <jim@meyering.net>
parents:
2856
diff
changeset
|
123 break; |
5 | 124 return FNM_NOMATCH; |
125 } | |
126 | |
127 case '[': | |
128 { | |
129 /* Nonzero if the sense of the character class is inverted. */ | |
130 register int not; | |
131 | |
132 if (*n == '\0') | |
133 return FNM_NOMATCH; | |
134 | |
135 if ((flags & FNM_PERIOD) && *n == '.' && | |
42 | 136 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) |
5 | 137 return FNM_NOMATCH; |
138 | |
139 not = (*p == '!' || *p == '^'); | |
140 if (not) | |
141 ++p; | |
142 | |
143 c = *p++; | |
144 for (;;) | |
145 { | |
146 register char cstart = c, cend = c; | |
147 | |
148 if (!(flags & FNM_NOESCAPE) && c == '\\') | |
1249 | 149 { |
150 if (*p == '\0') | |
151 return FNM_NOMATCH; | |
152 cstart = cend = *p++; | |
153 } | |
5 | 154 |
42 | 155 cstart = cend = FOLD (cstart); |
156 | |
5 | 157 if (c == '\0') |
158 /* [ (unterminated) loses. */ | |
159 return FNM_NOMATCH; | |
160 | |
161 c = *p++; | |
42 | 162 c = FOLD (c); |
5 | 163 |
42 | 164 if ((flags & FNM_FILE_NAME) && c == '/') |
5 | 165 /* [/] can never match. */ |
166 return FNM_NOMATCH; | |
167 | |
168 if (c == '-' && *p != ']') | |
169 { | |
170 cend = *p++; | |
171 if (!(flags & FNM_NOESCAPE) && cend == '\\') | |
172 cend = *p++; | |
173 if (cend == '\0') | |
174 return FNM_NOMATCH; | |
42 | 175 cend = FOLD (cend); |
176 | |
5 | 177 c = *p++; |
178 } | |
179 | |
42 | 180 if (FOLD (*n) >= cstart && FOLD (*n) <= cend) |
5 | 181 goto matched; |
182 | |
183 if (c == ']') | |
184 break; | |
185 } | |
186 if (!not) | |
187 return FNM_NOMATCH; | |
188 break; | |
189 | |
190 matched:; | |
191 /* Skip the rest of the [...] that already matched. */ | |
192 while (c != ']') | |
193 { | |
194 if (c == '\0') | |
195 /* [... (unterminated) loses. */ | |
196 return FNM_NOMATCH; | |
197 | |
198 c = *p++; | |
199 if (!(flags & FNM_NOESCAPE) && c == '\\') | |
1249 | 200 { |
201 if (*p == '\0') | |
202 return FNM_NOMATCH; | |
203 /* XXX 1003.2d11 is unclear if this is right. */ | |
204 ++p; | |
205 } | |
5 | 206 } |
207 if (not) | |
208 return FNM_NOMATCH; | |
209 } | |
210 break; | |
211 | |
212 default: | |
42 | 213 if (c != FOLD (*n)) |
5 | 214 return FNM_NOMATCH; |
215 } | |
216 | |
217 ++n; | |
218 } | |
219 | |
42 | 220 if (*n == '\0') |
221 return 0; | |
222 | |
223 if ((flags & FNM_LEADING_DIR) && *n == '/') | |
224 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ | |
5 | 225 return 0; |
226 | |
227 return FNM_NOMATCH; | |
763 | 228 |
229 # undef FOLD | |
5 | 230 } |