1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
4 Free Software Foundation, Inc.
5 This file is part of the GNU C Library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21 /* Match STRING against the file name pattern PATTERN, returning zero if
22 it matches, nonzero if not. */
23 static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
24 const CHAR *string_end, bool no_leading_period, int flags)
26 static const CHAR *END (const CHAR *patternp) internal_function;
30 FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
31 bool no_leading_period, int flags)
33 register const CHAR *p = pattern, *n = string;
36 # if WIDE_CHAR_VERSION
37 const char *collseq = (const char *)
38 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
40 const UCHAR *collseq = (const UCHAR *)
41 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
45 while ((c = *p++) != L_('\0'))
47 bool new_no_leading_period = false;
53 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
57 res = EXT (c, p, n, string_end, no_leading_period,
65 else if (*n == L_('/') && (flags & FNM_FILE_NAME))
67 else if (*n == L_('.') && no_leading_period)
72 if (!(flags & FNM_NOESCAPE))
76 /* Trailing \ loses. */
80 if (n == string_end || FOLD ((UCHAR) *n) != c)
85 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
89 res = EXT (c, p, n, string_end, no_leading_period,
95 if (n != string_end && *n == L_('.') && no_leading_period)
98 for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)
100 if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)
102 const CHAR *endp = END (p);
105 /* This is a pattern. Skip over it. */
113 /* A ? needs to match one character. */
115 /* There isn't another character; no match. */
117 else if (*n == L_('/')
118 && __builtin_expect (flags & FNM_FILE_NAME, 0))
119 /* A slash does not match a wildcard under
123 /* One character of the string is consumed in matching
124 this ? wildcard, so *??? won't match if there are
125 less than three characters. */
131 /* The wildcard(s) is/are the last element of the pattern.
132 If the name is a file name and contains another slash
133 this means it cannot match, unless the FNM_LEADING_DIR
136 int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
138 if (flags & FNM_FILE_NAME)
140 if (flags & FNM_LEADING_DIR)
144 if (MEMCHR (n, L_('/'), string_end - n) == NULL)
155 endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'),
161 || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
162 && (c == L_('@') || c == L_('+') || c == L_('!'))
165 int flags2 = ((flags & FNM_FILE_NAME)
166 ? flags : (flags & ~FNM_PERIOD));
167 bool no_leading_period2 = no_leading_period;
169 for (--p; n < endp; ++n, no_leading_period2 = false)
170 if (FCT (p, n, string_end, no_leading_period2, flags2)
174 else if (c == L_('/') && (flags & FNM_FILE_NAME))
176 while (n < string_end && *n != L_('/'))
178 if (n < string_end && *n == L_('/')
179 && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
185 int flags2 = ((flags & FNM_FILE_NAME)
186 ? flags : (flags & ~FNM_PERIOD));
187 int no_leading_period2 = no_leading_period;
189 if (c == L_('\\') && !(flags & FNM_NOESCAPE))
192 for (--p; n < endp; ++n, no_leading_period2 = false)
193 if (FOLD ((UCHAR) *n) == c
194 && (FCT (p, n, string_end, no_leading_period2, flags2)
200 /* If we come here no match is possible with the wildcard. */
205 /* Nonzero if the sense of the character class is inverted. */
210 if (posixly_correct == 0)
211 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
216 if (*n == L_('.') && no_leading_period)
219 if (*n == L_('/') && (flags & FNM_FILE_NAME))
220 /* `/' cannot be matched. */
223 not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^')));
227 fn = FOLD ((UCHAR) *n);
232 if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
236 c = FOLD ((UCHAR) *p);
241 else if (c == L_('[') && *p == L_(':'))
243 /* Leave room for the null. */
244 CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
246 #if defined _LIBC || WIDE_CHAR_SUPPORT
249 const CHAR *startp = p;
253 if (c1 == CHAR_CLASS_MAX_LENGTH)
254 /* The name is too long and therefore the pattern
259 if (c == L_(':') && p[1] == L_(']'))
264 if (c < L_('a') || c >= L_('z'))
266 /* This cannot possibly be a character class name.
267 Match it as a normal range. */
276 #if defined _LIBC || WIDE_CHAR_SUPPORT
277 wt = IS_CHAR_CLASS (str);
279 /* Invalid character class name. */
282 # if defined _LIBC && ! WIDE_CHAR_VERSION
283 /* The following code is glibc specific but does
284 there a good job in speeding up the code since
285 we can avoid the btowc() call. */
286 if (_ISCTYPE ((UCHAR) *n, wt))
289 if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
293 if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n))
294 || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n))
295 || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n))
296 || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n))
297 || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n))
298 || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n))
299 || (STREQ (str, L_("lower")) && islower ((UCHAR) *n))
300 || (STREQ (str, L_("print")) && isprint ((UCHAR) *n))
301 || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n))
302 || (STREQ (str, L_("space")) && isspace ((UCHAR) *n))
303 || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n))
304 || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n)))
310 else if (c == L_('[') && *p == L_('='))
314 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
315 const CHAR *startp = p;
327 if (c != L_('=') || p[1] != L_(']'))
337 if ((UCHAR) *n == str[0])
342 const int32_t *table;
343 # if WIDE_CHAR_VERSION
344 const int32_t *weights;
345 const int32_t *extra;
347 const unsigned char *weights;
348 const unsigned char *extra;
350 const int32_t *indirect;
352 const UCHAR *cp = (const UCHAR *) str;
354 /* This #include defines a local function! */
355 # if WIDE_CHAR_VERSION
356 # include <locale/weightwc.h>
358 # include <locale/weight.h>
361 # if WIDE_CHAR_VERSION
362 table = (const int32_t *)
363 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
364 weights = (const int32_t *)
365 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
366 extra = (const int32_t *)
367 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
368 indirect = (const int32_t *)
369 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
371 table = (const int32_t *)
372 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
373 weights = (const unsigned char *)
374 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
375 extra = (const unsigned char *)
376 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
377 indirect = (const int32_t *)
378 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
384 /* We found a table entry. Now see whether the
385 character we are currently at has the same
386 equivalance class value. */
387 int len = weights[idx];
389 const UCHAR *np = (const UCHAR *) n;
391 idx2 = findidx (&np);
392 if (idx2 != 0 && len == weights[idx2])
397 && (weights[idx + 1 + cnt]
398 == weights[idx2 + 1 + cnt]))
410 else if (c == L_('\0'))
411 /* [ (unterminated) loses. */
415 bool is_range = false;
418 bool is_seqval = false;
420 if (c == L_('[') && *p == L_('.'))
423 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
424 const CHAR *startp = p;
430 if (c == L_('.') && p[1] == L_(']'))
440 /* We have to handling the symbols differently in
441 ranges since then the collation sequence is
443 is_range = *p == L_('-') && p[1] != L_('\0');
447 /* There are no names defined in the collation
448 data. Therefore we only accept the trivial
449 names consisting of the character itself. */
453 if (!is_range && *n == startp[1])
462 const int32_t *symb_table;
463 # ifdef WIDE_CHAR_VERSION
467 # define str (startp + 1)
469 const unsigned char *extra;
475 # ifdef WIDE_CHAR_VERSION
476 /* We have to convert the name to a single-byte
477 string. This is possible since the names
478 consist of ASCII characters and the internal
479 representation is UCS4. */
480 for (strcnt = 0; strcnt < c1; ++strcnt)
481 str[strcnt] = startp[1 + strcnt];
485 _NL_CURRENT_WORD (LC_COLLATE,
486 _NL_COLLATE_SYMB_HASH_SIZEMB);
487 symb_table = (const int32_t *)
488 _NL_CURRENT (LC_COLLATE,
489 _NL_COLLATE_SYMB_TABLEMB);
490 extra = (const unsigned char *)
491 _NL_CURRENT (LC_COLLATE,
492 _NL_COLLATE_SYMB_EXTRAMB);
494 /* Locate the character in the hashing table. */
495 hash = elem_hash (str, c1);
498 elem = hash % table_size;
499 if (symb_table[2 * elem] != 0)
501 second = hash % (table_size - 2) + 1;
505 /* First compare the hashing value. */
506 if (symb_table[2 * elem] == hash
508 == extra[symb_table[2 * elem + 1]])
510 &extra[symb_table[2 * elem
514 /* Yep, this is the entry. */
515 idx = symb_table[2 * elem + 1];
516 idx += 1 + extra[idx];
523 while (symb_table[2 * elem] != 0);
526 if (symb_table[2 * elem] != 0)
528 /* Compare the byte sequence but only if
529 this is not part of a range. */
530 # ifdef WIDE_CHAR_VERSION
533 idx += 1 + extra[idx];
534 /* Adjust for the alignment. */
535 idx = (idx + 3) & ~3;
537 wextra = (int32_t *) &extra[idx + 4];
542 # ifdef WIDE_CHAR_VERSION
544 (int32_t) c1 < wextra[idx];
546 if (n[c1] != wextra[1 + c1])
549 if ((int32_t) c1 == wextra[idx])
552 for (c1 = 0; c1 < extra[idx]; ++c1)
553 if (n[c1] != extra[1 + c1])
556 if (c1 == extra[idx])
561 /* Get the collation sequence value. */
563 # ifdef WIDE_CHAR_VERSION
564 cold = wextra[1 + wextra[idx]];
566 /* Adjust for the alignment. */
567 idx += 1 + extra[idx];
568 idx = (idx + 3) & ~4;
569 cold = *((int32_t *) &extra[idx]);
576 /* No valid character. Match it as a
578 if (!is_range && *n == str[0])
595 /* We have to handling the symbols differently in
596 ranges since then the collation sequence is
598 is_range = (*p == L_('-') && p[1] != L_('\0')
601 if (!is_range && c == fn)
605 /* This is needed if we goto normal_bracket; from
606 outside of is_seqval's scope. */
614 if (c == L_('-') && *p != L_(']'))
617 /* We have to find the collation sequence
618 value for C. Collation sequence is nothing
619 we can regularly access. The sequence
620 value is defined by the order in which the
621 definitions of the collation values for the
622 various characters appear in the source
623 file. A strange concept, nowhere
629 # ifdef WIDE_CHAR_VERSION
630 /* Search in the `names' array for the characters. */
631 fcollseq = __collseq_table_lookup (collseq, fn);
632 if (fcollseq == ~((uint32_t) 0))
633 /* XXX We don't know anything about the character
634 we are supposed to match. This means we are
636 goto range_not_matched;
641 lcollseq = __collseq_table_lookup (collseq, cold);
643 fcollseq = collseq[fn];
644 lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
648 if (cend == L_('[') && *p == L_('.'))
651 _NL_CURRENT_WORD (LC_COLLATE,
653 const CHAR *startp = p;
659 if (c == L_('.') && p[1] == L_(']'))
671 /* There are no names defined in the
672 collation data. Therefore we only
673 accept the trivial names consisting
674 of the character itself. */
683 const int32_t *symb_table;
684 # ifdef WIDE_CHAR_VERSION
688 # define str (startp + 1)
690 const unsigned char *extra;
696 # ifdef WIDE_CHAR_VERSION
697 /* We have to convert the name to a single-byte
698 string. This is possible since the names
699 consist of ASCII characters and the internal
700 representation is UCS4. */
701 for (strcnt = 0; strcnt < c1; ++strcnt)
702 str[strcnt] = startp[1 + strcnt];
706 _NL_CURRENT_WORD (LC_COLLATE,
707 _NL_COLLATE_SYMB_HASH_SIZEMB);
708 symb_table = (const int32_t *)
709 _NL_CURRENT (LC_COLLATE,
710 _NL_COLLATE_SYMB_TABLEMB);
711 extra = (const unsigned char *)
712 _NL_CURRENT (LC_COLLATE,
713 _NL_COLLATE_SYMB_EXTRAMB);
715 /* Locate the character in the hashing
717 hash = elem_hash (str, c1);
720 elem = hash % table_size;
721 if (symb_table[2 * elem] != 0)
723 second = hash % (table_size - 2) + 1;
727 /* First compare the hashing value. */
728 if (symb_table[2 * elem] == hash
730 == extra[symb_table[2 * elem + 1]])
732 &extra[symb_table[2 * elem + 1]
735 /* Yep, this is the entry. */
736 idx = symb_table[2 * elem + 1];
737 idx += 1 + extra[idx];
744 while (symb_table[2 * elem] != 0);
747 if (symb_table[2 * elem] != 0)
749 /* Compare the byte sequence but only if
750 this is not part of a range. */
751 # ifdef WIDE_CHAR_VERSION
754 idx += 1 + extra[idx];
755 /* Adjust for the alignment. */
756 idx = (idx + 3) & ~4;
758 wextra = (int32_t *) &extra[idx + 4];
760 /* Get the collation sequence value. */
762 # ifdef WIDE_CHAR_VERSION
763 cend = wextra[1 + wextra[idx]];
765 /* Adjust for the alignment. */
766 idx += 1 + extra[idx];
767 idx = (idx + 3) & ~4;
768 cend = *((int32_t *) &extra[idx]);
771 else if (symb_table[2 * elem] != 0 && c1 == 1)
783 if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
785 if (cend == L_('\0'))
790 /* XXX It is not entirely clear to me how to handle
791 characters which are not mentioned in the
792 collation specification. */
794 # ifdef WIDE_CHAR_VERSION
795 lcollseq == 0xffffffff ||
797 lcollseq <= fcollseq)
799 /* We have to look at the upper bound. */
806 # ifdef WIDE_CHAR_VERSION
808 __collseq_table_lookup (collseq, cend);
809 if (hcollseq == ~((uint32_t) 0))
811 /* Hum, no information about the upper
812 bound. The matching succeeds if the
813 lower bound is matched exactly. */
814 if (lcollseq != fcollseq)
815 goto range_not_matched;
820 hcollseq = collseq[cend];
824 if (lcollseq <= hcollseq && fcollseq <= hcollseq)
827 # ifdef WIDE_CHAR_VERSION
831 /* We use a boring value comparison of the character
832 values. This is better than comparing using
833 `strcoll' since the latter would have surprising
834 and sometimes fatal consequences. */
837 if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
839 if (cend == L_('\0'))
843 if (cold <= fn && fn <= cend)
860 /* Skip the rest of the [...] that already matched. */
867 /* [... (unterminated) loses. */
870 if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
874 /* XXX 1003.2d11 is unclear if this is right. */
877 else if (c == L_('[') && *p == L_(':'))
880 const CHAR *startp = p;
885 if (++c1 == CHAR_CLASS_MAX_LENGTH)
888 if (*p == L_(':') && p[1] == L_(']'))
891 if (c < L_('a') || c >= L_('z'))
900 else if (c == L_('[') && *p == L_('='))
906 if (c != L_('=') || p[1] != L_(']'))
911 else if (c == L_('[') && *p == L_('.'))
920 if (*p == L_('.') && p[1] == L_(']'))
927 while (c != L_(']'));
936 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
940 res = EXT (c, p, n, string_end, no_leading_period, flags);
947 if (NO_LEADING_PERIOD (flags))
949 if (n == string_end || c != (UCHAR) *n)
952 new_no_leading_period = true;
958 if (n == string_end || c != FOLD ((UCHAR) *n))
962 no_leading_period = new_no_leading_period;
969 if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/'))
970 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
979 END (const CHAR *pattern)
981 const CHAR *p = pattern;
984 if (*++p == L_('\0'))
985 /* This is an invalid pattern. */
987 else if (*p == L_('['))
989 /* Handle brackets special. */
990 if (posixly_correct == 0)
991 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
993 /* Skip the not sign. We have to recognize it because of a possibly
995 if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
997 /* A leading ']' is recognized as such. */
1000 /* Skip over all characters of the list. */
1001 while (*p != L_(']'))
1002 if (*p++ == L_('\0'))
1003 /* This is no valid pattern. */
1006 else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
1007 || *p == L_('!')) && p[1] == L_('('))
1009 else if (*p == L_(')'))
1018 EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
1019 bool no_leading_period, int flags)
1025 struct patternlist *next;
1028 struct patternlist **lastp = &list;
1029 size_t pattern_len = STRLEN (pattern);
1032 enum { ALLOCA_LIMIT = 8000 };
1034 /* Parse the pattern. Store the individual parts in the list. */
1036 for (startp = p = pattern + 1; ; ++p)
1038 /* This is an invalid pattern. */
1040 else if (*p == L_('['))
1042 /* Handle brackets special. */
1043 if (posixly_correct == 0)
1044 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
1046 /* Skip the not sign. We have to recognize it because of a possibly
1048 if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
1050 /* A leading ']' is recognized as such. */
1053 /* Skip over all characters of the list. */
1054 while (*p != L_(']'))
1055 if (*p++ == L_('\0'))
1056 /* This is no valid pattern. */
1059 else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
1060 || *p == L_('!')) && p[1] == L_('('))
1061 /* Remember the nesting level. */
1063 else if (*p == L_(')'))
1067 /* This means we found the end of the pattern. */
1068 #define NEW_PATTERN \
1069 struct patternlist *newp; \
1074 plen = (opt == L_('?') || opt == L_('@') \
1076 : p - startp + 1); \
1077 plensize = plen * sizeof (CHAR); \
1078 newpsize = offsetof (struct patternlist, str) + plensize; \
1079 if ((size_t) -1 / sizeof (CHAR) < plen \
1080 || newpsize < offsetof (struct patternlist, str) \
1081 || ALLOCA_LIMIT <= newpsize) \
1083 newp = (struct patternlist *) alloca (newpsize); \
1084 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \
1085 newp->next = NULL; \
1092 else if (*p == L_('|'))
1100 assert (list != NULL);
1101 assert (p[-1] == L_(')'));
1107 if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1114 for (rs = string; rs <= string_end; ++rs)
1115 /* First match the prefix with the current pattern with the
1117 if (FCT (list->str, string, rs, no_leading_period,
1118 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
1119 /* This was successful. Now match the rest with the rest
1121 && (FCT (p, rs, string_end,
1124 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1125 flags & FNM_FILE_NAME
1126 ? flags : flags & ~FNM_PERIOD) == 0
1127 /* This didn't work. Try the whole pattern. */
1129 && FCT (pattern - 1, rs, string_end,
1132 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1133 flags & FNM_FILE_NAME
1134 ? flags : flags & ~FNM_PERIOD) == 0)))
1135 /* It worked. Signal success. */
1138 while ((list = list->next) != NULL);
1140 /* None of the patterns lead to a match. */
1144 if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1150 /* I cannot believe it but `strcat' is actually acceptable
1151 here. Match the entire string with the prefix from the
1152 pattern list and the rest of the pattern following the
1154 if (FCT (STRCAT (list->str, p), string, string_end,
1156 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1157 /* It worked. Signal success. */
1159 while ((list = list->next) != NULL);
1161 /* None of the patterns lead to a match. */
1165 for (rs = string; rs <= string_end; ++rs)
1167 struct patternlist *runp;
1169 for (runp = list; runp != NULL; runp = runp->next)
1170 if (FCT (runp->str, string, rs, no_leading_period,
1171 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1174 /* If none of the patterns matched see whether the rest does. */
1176 && (FCT (p, rs, string_end,
1179 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1180 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
1182 /* This is successful. */
1186 /* None of the patterns together with the rest of the pattern
1191 assert (! "Invalid extended matching operator");