Mercurial > octave
comparison glob/fnmatch.c @ 1313:f0dcdcc9a780
[project @ 1995-06-25 18:42:38 by jwe]
Initial revision
author | jwe |
---|---|
date | Sun, 25 Jun 1995 18:42:38 +0000 |
parents | |
children | 611d403c7f3d |
comparison
equal
deleted
inserted
replaced
1312:3a02b029b618 | 1313:f0dcdcc9a780 |
---|---|
1 /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. | |
2 | |
3 This library is free software; you can redistribute it and/or | |
4 modify it under the terms of the GNU Library General Public License as | |
5 published by the Free Software Foundation; either version 2 of the | |
6 License, or (at your option) any later version. | |
7 | |
8 This library 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 GNU | |
11 Library General Public License for more details. | |
12 | |
13 You should have received a copy of the GNU Library General Public | |
14 License along with this library; see the file COPYING.LIB. If | |
15 not, write to the Free Software Foundation, Inc., 675 Mass Ave, | |
16 Cambridge, MA 02139, USA. */ | |
17 | |
18 #ifdef HAVE_CONFIG_H | |
19 #include <config.h> | |
20 #endif | |
21 | |
22 #include <errno.h> | |
23 #include <fnmatch.h> | |
24 #include <ctype.h> | |
25 | |
26 | |
27 /* Comment out all this code if we are using the GNU C Library, and are not | |
28 actually compiling the library itself. This code is part of the GNU C | |
29 Library, but also included in many other GNU distributions. Compiling | |
30 and linking in this code is a waste when using the GNU C library | |
31 (especially if it is a shared library). Rather than having every GNU | |
32 program understand `configure --with-gnu-libc' and omit the object files, | |
33 it is simpler to just do this in the source for each such file. */ | |
34 | |
35 #if defined (_LIBC) || !defined (__GNU_LIBRARY__) | |
36 | |
37 | |
38 #ifndef errno | |
39 extern int errno; | |
40 #endif | |
41 | |
42 /* Match STRING against the filename pattern PATTERN, returning zero if | |
43 it matches, nonzero if not. */ | |
44 int | |
45 fnmatch (pattern, string, flags) | |
46 const char *pattern; | |
47 const char *string; | |
48 int flags; | |
49 { | |
50 register const char *p = pattern, *n = string; | |
51 register char c; | |
52 | |
53 /* Note that this evalutes C many times. */ | |
54 #define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c)) | |
55 | |
56 while ((c = *p++) != '\0') | |
57 { | |
58 c = FOLD (c); | |
59 | |
60 switch (c) | |
61 { | |
62 case '?': | |
63 if (*n == '\0') | |
64 return FNM_NOMATCH; | |
65 else if ((flags & FNM_FILE_NAME) && *n == '/') | |
66 return FNM_NOMATCH; | |
67 else if ((flags & FNM_PERIOD) && *n == '.' && | |
68 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) | |
69 return FNM_NOMATCH; | |
70 break; | |
71 | |
72 case '\\': | |
73 if (!(flags & FNM_NOESCAPE)) | |
74 { | |
75 c = *p++; | |
76 c = FOLD (c); | |
77 } | |
78 if (FOLD (*n) != c) | |
79 return FNM_NOMATCH; | |
80 break; | |
81 | |
82 case '*': | |
83 if ((flags & FNM_PERIOD) && *n == '.' && | |
84 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) | |
85 return FNM_NOMATCH; | |
86 | |
87 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) | |
88 if (((flags & FNM_FILE_NAME) && *n == '/') || | |
89 (c == '?' && *n == '\0')) | |
90 return FNM_NOMATCH; | |
91 | |
92 if (c == '\0') | |
93 return 0; | |
94 | |
95 { | |
96 char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; | |
97 c1 = FOLD (c1); | |
98 for (--p; *n != '\0'; ++n) | |
99 if ((c == '[' || FOLD (*n) == c1) && | |
100 fnmatch (p, n, flags & ~FNM_PERIOD) == 0) | |
101 return 0; | |
102 return FNM_NOMATCH; | |
103 } | |
104 | |
105 case '[': | |
106 { | |
107 /* Nonzero if the sense of the character class is inverted. */ | |
108 register int not; | |
109 | |
110 if (*n == '\0') | |
111 return FNM_NOMATCH; | |
112 | |
113 if ((flags & FNM_PERIOD) && *n == '.' && | |
114 (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) | |
115 return FNM_NOMATCH; | |
116 | |
117 not = (*p == '!' || *p == '^'); | |
118 if (not) | |
119 ++p; | |
120 | |
121 c = *p++; | |
122 for (;;) | |
123 { | |
124 register char cstart = c, cend = c; | |
125 | |
126 if (!(flags & FNM_NOESCAPE) && c == '\\') | |
127 cstart = cend = *p++; | |
128 | |
129 cstart = cend = FOLD (cstart); | |
130 | |
131 if (c == '\0') | |
132 /* [ (unterminated) loses. */ | |
133 return FNM_NOMATCH; | |
134 | |
135 c = *p++; | |
136 c = FOLD (c); | |
137 | |
138 if ((flags & FNM_FILE_NAME) && c == '/') | |
139 /* [/] can never match. */ | |
140 return FNM_NOMATCH; | |
141 | |
142 if (c == '-' && *p != ']') | |
143 { | |
144 cend = *p++; | |
145 if (!(flags & FNM_NOESCAPE) && cend == '\\') | |
146 cend = *p++; | |
147 if (cend == '\0') | |
148 return FNM_NOMATCH; | |
149 cend = FOLD (cend); | |
150 | |
151 c = *p++; | |
152 } | |
153 | |
154 if (FOLD (*n) >= cstart && FOLD (*n) <= cend) | |
155 goto matched; | |
156 | |
157 if (c == ']') | |
158 break; | |
159 } | |
160 if (!not) | |
161 return FNM_NOMATCH; | |
162 break; | |
163 | |
164 matched:; | |
165 /* Skip the rest of the [...] that already matched. */ | |
166 while (c != ']') | |
167 { | |
168 if (c == '\0') | |
169 /* [... (unterminated) loses. */ | |
170 return FNM_NOMATCH; | |
171 | |
172 c = *p++; | |
173 if (!(flags & FNM_NOESCAPE) && c == '\\') | |
174 /* XXX 1003.2d11 is unclear if this is right. */ | |
175 ++p; | |
176 } | |
177 if (not) | |
178 return FNM_NOMATCH; | |
179 } | |
180 break; | |
181 | |
182 default: | |
183 if (c != FOLD (*n)) | |
184 return FNM_NOMATCH; | |
185 } | |
186 | |
187 ++n; | |
188 } | |
189 | |
190 if (*n == '\0') | |
191 return 0; | |
192 | |
193 if ((flags & FNM_LEADING_DIR) && *n == '/') | |
194 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ | |
195 return 0; | |
196 | |
197 return FNM_NOMATCH; | |
198 } | |
199 | |
200 #endif /* _LIBC or not __GNU_LIBRARY__. */ |