]>
Dogcows Code - chaz/tar/blob - lib/fnmatch_loop.c
1 /* Copyright (C) 1991-1993, 1996-1999, 2000 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 This 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 This 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 You should have received a copy of the GNU Library General Public
15 License along with this library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
19 /* Match STRING against the filename pattern PATTERN, returning zero if
20 it matches, nonzero if not. */
21 static int FCT (const CHAR
*pattern
, const CHAR
*string
,
22 int no_leading_period
, int flags
) internal_function
;
26 FCT (pattern
, string
, no_leading_period
, flags
)
29 int no_leading_period
;
32 register const CHAR
*p
= pattern
, *n
= string
;
35 const UCHAR
*collseq
= (const UCHAR
*)
36 _NL_CURRENT(LC_COLLATE
, CONCAT(_NL_COLLATE_COLLSEQ
,SUFFIX
));
37 # ifdef WIDE_CHAR_VERSION
38 const wint_t *names
= (const wint_t *)
39 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_NAMES
);
40 size_t size
= _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_HASH_SIZE
);
41 size_t layers
= _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_HASH_LAYERS
);
45 while ((c
= *p
++) != L('\0'))
54 else if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
56 else if (*n
== L('.') && no_leading_period
58 || (n
[-1] == L('/') && (flags
& FNM_FILE_NAME
))))
63 if (!(flags
& FNM_NOESCAPE
))
67 /* Trailing \ loses. */
71 if (FOLD ((UCHAR
) *n
) != c
)
76 if (*n
== L('.') && no_leading_period
78 || (n
[-1] == L('/') && (flags
& FNM_FILE_NAME
))))
81 for (c
= *p
++; c
== L('?') || c
== L('*'); c
= *p
++)
83 if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
84 /* A slash does not match a wildcard under FNM_FILE_NAME. */
88 /* A ? needs to match one character. */
90 /* There isn't another character; no match. */
93 /* One character of the string is consumed in matching
94 this ? wildcard, so *??? won't match if there are
95 less than three characters. */
101 /* The wildcard(s) is/are the last element of the pattern.
102 If the name is a file name and contains another slash
103 this does mean it cannot match. If the FNM_LEADING_DIR
104 flag is set and exactly one slash is following, we have
107 int result
= (flags
& FNM_FILE_NAME
) == 0 ? 0 : FNM_NOMATCH
;
109 if (flags
& FNM_FILE_NAME
)
111 const CHAR
*slashp
= STRCHR (n
, L('/'));
113 if (flags
& FNM_LEADING_DIR
)
116 && STRCHR (slashp
+ 1, L('/')) == NULL
)
132 endp
= STRCHRNUL (n
, (flags
& FNM_FILE_NAME
) ? L('/') : L('\0'));
136 int flags2
= ((flags
& FNM_FILE_NAME
)
137 ? flags
: (flags
& ~FNM_PERIOD
));
139 for (--p
; n
< endp
; ++n
)
140 if (FCT (p
, n
, (no_leading_period
143 && (flags
& FNM_FILE_NAME
)))),
147 else if (c
== L('/') && (flags
& FNM_FILE_NAME
))
149 while (*n
!= L('\0') && *n
!= L('/'))
152 && (FCT (p
, n
+ 1, flags
& FNM_PERIOD
, flags
) == 0))
157 int flags2
= ((flags
& FNM_FILE_NAME
)
158 ? flags
: (flags
& ~FNM_PERIOD
));
160 if (c
== L('\\') && !(flags
& FNM_NOESCAPE
))
163 for (--p
; n
< endp
; ++n
)
164 if (FOLD ((UCHAR
) *n
) == c
165 && (FCT (p
, n
, (no_leading_period
168 && (flags
& FNM_FILE_NAME
)))),
174 /* If we come here no match is possible with the wildcard. */
179 /* Nonzero if the sense of the character class is inverted. */
180 static int posixly_correct
;
184 if (posixly_correct
== 0)
185 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
190 if (*n
== L('.') && no_leading_period
192 || (n
[-1] == L('/') && (flags
& FNM_FILE_NAME
))))
195 if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
196 /* `/' cannot be matched. */
199 not = (*p
== L('!') || (posixly_correct
< 0 && *p
== L('^')));
206 UCHAR fn
= FOLD ((UCHAR
) *n
);
208 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
212 c
= FOLD ((UCHAR
) *p
);
218 else if (c
== L('[') && *p
== L(':'))
220 /* Leave room for the null. */
221 CHAR str
[CHAR_CLASS_MAX_LENGTH
+ 1];
223 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
226 const CHAR
*startp
= p
;
230 if (c1
== CHAR_CLASS_MAX_LENGTH
)
231 /* The name is too long and therefore the pattern
236 if (c
== L(':') && p
[1] == L(']'))
241 if (c
< L('a') || c
>= L('z'))
243 /* This cannot possibly be a character class name.
244 Match it as a normal range. */
253 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
254 wt
= IS_CHAR_CLASS (str
);
256 /* Invalid character class name. */
259 if (ISWCTYPE (BTOWC ((UCHAR
) *n
), wt
))
262 if ((STREQ (str
, L("alnum")) && ISALNUM ((UCHAR
) *n
))
263 || (STREQ (str
, L("alpha")) && ISALPHA ((UCHAR
) *n
))
264 || (STREQ (str
, L("blank")) && ISBLANK ((UCHAR
) *n
))
265 || (STREQ (str
, L("cntrl")) && ISCNTRL ((UCHAR
) *n
))
266 || (STREQ (str
, L("digit")) && ISDIGIT ((UCHAR
) *n
))
267 || (STREQ (str
, L("graph")) && ISGRAPH ((UCHAR
) *n
))
268 || (STREQ (str
, L("lower")) && ISLOWER ((UCHAR
) *n
))
269 || (STREQ (str
, L("print")) && ISPRINT ((UCHAR
) *n
))
270 || (STREQ (str
, L("punct")) && ISPUNCT ((UCHAR
) *n
))
271 || (STREQ (str
, L("space")) && ISSPACE ((UCHAR
) *n
))
272 || (STREQ (str
, L("upper")) && ISUPPER ((UCHAR
) *n
))
273 || (STREQ (str
, L("xdigit")) && ISXDIGIT ((UCHAR
) *n
)))
277 else if (c
== L('\0'))
278 /* [ (unterminated) loses. */
290 if (c
== L('-') && *p
!= L(']'))
293 /* We have to find the collation sequence
294 value for C. Collation sequence is nothing
295 we can regularly access. The sequence
296 value is defined by the order in which the
297 definitions of the collation values for the
298 various characters appear in the source
299 file. A strange concept, nowhere
304 # ifdef WIDE_CHAR_VERSION
308 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
313 # ifdef WIDE_CHAR_VERSION
314 /* Search in the `names' array for the characters. */
317 while (names
[fseqidx
] != fn
)
320 /* XXX We don't know anything about
321 the character we are supposed to
322 match. This means we are failing. */
323 goto range_not_matched
;
327 lseqidx
= cold
% size
;
329 while (names
[lseqidx
] != cold
)
343 /* XXX It is not entirely clear to me how to handle
344 characters which are not mentioned in the
345 collation specification. */
347 # ifdef WIDE_CHAR_VERSION
350 collseq
[lseqidx
] <= collseq
[fseqidx
])
352 /* We have to look at the upper bound. */
356 # ifdef WIDE_CHAR_VERSION
357 hseqidx
= cend
% size
;
359 while (names
[hseqidx
] != cend
)
363 /* Hum, no information about the upper
364 bound. The matching succeeds if the
365 lower bound is matched exactly. */
366 if (lseqidx
== -1 || cold
!= fn
)
367 goto range_not_matched
;
377 # ifdef WIDE_CHAR_VERSION
379 && collseq
[fseqidx
] == collseq
[hseqidx
]) ||
381 collseq
[fseqidx
] <= collseq
[hseqidx
])
384 # ifdef WIDE_CHAR_VERSION
388 /* We use a boring value comparison of the character
389 values. This is better than comparing using
390 `strcoll' since the latter would have surprising
391 and sometimes fatal consequences. */
394 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
400 if (cold
<= fc
&& fc
<= c
)
417 /* Skip the rest of the [...] that already matched. */
421 /* [... (unterminated) loses. */
425 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
429 /* XXX 1003.2d11 is unclear if this is right. */
432 else if (c
== L('[') && *p
== L(':'))
437 while (*p
!= L(':') || p
[1] == L(']'));
448 if (c
!= FOLD ((UCHAR
) *n
))
458 if ((flags
& FNM_LEADING_DIR
) && *n
== L('/'))
459 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
This page took 0.054804 seconds and 4 git commands to generate.