1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Copyright (C) 1991-1993, 1996-2006, 2009-2011 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20 /* Match STRING against the file name pattern PATTERN, returning zero if
21 it matches, nonzero if not. */
22 static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
23 const CHAR *string_end, bool no_leading_period, int flags)
25 static const CHAR *END (const CHAR *patternp) internal_function;
29 FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
30 bool no_leading_period, int flags)
32 register const CHAR *p = pattern, *n = string;
35 # if WIDE_CHAR_VERSION
36 const char *collseq = (const char *)
37 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
39 const UCHAR *collseq = (const UCHAR *)
40 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
44 while ((c = *p++) != L_('\0'))
46 bool new_no_leading_period = false;
52 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
56 res = EXT (c, p, n, string_end, no_leading_period,
64 else if (*n == L_('/') && (flags & FNM_FILE_NAME))
66 else if (*n == L_('.') && no_leading_period)
71 if (!(flags & FNM_NOESCAPE))
75 /* Trailing \ loses. */
79 if (n == string_end || FOLD ((UCHAR) *n) != c)
84 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
88 res = EXT (c, p, n, string_end, no_leading_period,
94 if (n != string_end && *n == L_('.') && no_leading_period)
97 for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)
99 if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)
101 const CHAR *endp = END (p);
104 /* This is a pattern. Skip over it. */
112 /* A ? needs to match one character. */
114 /* There isn't another character; no match. */
116 else if (*n == L_('/')
117 && __builtin_expect (flags & FNM_FILE_NAME, 0))
118 /* A slash does not match a wildcard under
122 /* One character of the string is consumed in matching
123 this ? wildcard, so *??? won't match if there are
124 less than three characters. */
130 /* The wildcard(s) is/are the last element of the pattern.
131 If the name is a file name and contains another slash
132 this means it cannot match, unless the FNM_LEADING_DIR
135 int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
137 if (flags & FNM_FILE_NAME)
139 if (flags & FNM_LEADING_DIR)
143 if (MEMCHR (n, L_('/'), string_end - n) == NULL)
154 endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'),
160 || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
161 && (c == L_('@') || c == L_('+') || c == L_('!'))
164 int flags2 = ((flags & FNM_FILE_NAME)
165 ? flags : (flags & ~FNM_PERIOD));
166 bool no_leading_period2 = no_leading_period;
168 for (--p; n < endp; ++n, no_leading_period2 = false)
169 if (FCT (p, n, string_end, no_leading_period2, flags2)
173 else if (c == L_('/') && (flags & FNM_FILE_NAME))
175 while (n < string_end && *n != L_('/'))
177 if (n < string_end && *n == L_('/')
178 && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
184 int flags2 = ((flags & FNM_FILE_NAME)
185 ? flags : (flags & ~FNM_PERIOD));
186 int no_leading_period2 = no_leading_period;
188 if (c == L_('\\') && !(flags & FNM_NOESCAPE))
191 for (--p; n < endp; ++n, no_leading_period2 = false)
192 if (FOLD ((UCHAR) *n) == c
193 && (FCT (p, n, string_end, no_leading_period2, flags2)
199 /* If we come here no match is possible with the wildcard. */
204 /* Nonzero if the sense of the character class is inverted. */
209 if (posixly_correct == 0)
210 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
215 if (*n == L_('.') && no_leading_period)
218 if (*n == L_('/') && (flags & FNM_FILE_NAME))
219 /* `/' cannot be matched. */
222 not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^')));
226 fn = FOLD ((UCHAR) *n);
231 if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
235 c = FOLD ((UCHAR) *p);
240 else if (c == L_('[') && *p == L_(':'))
242 /* Leave room for the null. */
243 CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
245 #if defined _LIBC || WIDE_CHAR_SUPPORT
248 const CHAR *startp = p;
252 if (c1 == CHAR_CLASS_MAX_LENGTH)
253 /* The name is too long and therefore the pattern
258 if (c == L_(':') && p[1] == L_(']'))
263 if (c < L_('a') || c >= L_('z'))
265 /* This cannot possibly be a character class name.
266 Match it as a normal range. */
275 #if defined _LIBC || WIDE_CHAR_SUPPORT
276 wt = IS_CHAR_CLASS (str);
278 /* Invalid character class name. */
281 # if defined _LIBC && ! WIDE_CHAR_VERSION
282 /* The following code is glibc specific but does
283 there a good job in speeding up the code since
284 we can avoid the btowc() call. */
285 if (_ISCTYPE ((UCHAR) *n, wt))
288 if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
292 if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n))
293 || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n))
294 || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n))
295 || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n))
296 || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n))
297 || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n))
298 || (STREQ (str, L_("lower")) && islower ((UCHAR) *n))
299 || (STREQ (str, L_("print")) && isprint ((UCHAR) *n))
300 || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n))
301 || (STREQ (str, L_("space")) && isspace ((UCHAR) *n))
302 || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n))
303 || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n)))
309 else if (c == L_('[') && *p == L_('='))
313 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
314 const CHAR *startp = p;
326 if (c != L_('=') || p[1] != L_(']'))
336 if ((UCHAR) *n == str[0])
341 const int32_t *table;
342 # if WIDE_CHAR_VERSION
343 const int32_t *weights;
344 const int32_t *extra;
346 const unsigned char *weights;
347 const unsigned char *extra;
349 const int32_t *indirect;
351 const UCHAR *cp = (const UCHAR *) str;
353 /* This #include defines a local function! */
354 # if WIDE_CHAR_VERSION
355 # include <locale/weightwc.h>
357 # include <locale/weight.h>
360 # if WIDE_CHAR_VERSION
361 table = (const int32_t *)
362 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
363 weights = (const int32_t *)
364 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
365 extra = (const int32_t *)
366 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
367 indirect = (const int32_t *)
368 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
370 table = (const int32_t *)
371 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
372 weights = (const unsigned char *)
373 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
374 extra = (const unsigned char *)
375 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
376 indirect = (const int32_t *)
377 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
383 /* We found a table entry. Now see whether the
384 character we are currently at has the same
385 equivalance class value. */
386 int len = weights[idx & 0xffffff];
388 const UCHAR *np = (const UCHAR *) n;
390 idx2 = findidx (&np);
392 && (idx >> 24) == (idx2 >> 24)
393 && len == weights[idx2 & 0xffffff])
401 && (weights[idx + 1 + cnt]
402 == weights[idx2 + 1 + cnt]))
414 else if (c == L_('\0'))
415 /* [ (unterminated) loses. */
419 bool is_range = false;
422 bool is_seqval = false;
424 if (c == L_('[') && *p == L_('.'))
427 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
428 const CHAR *startp = p;
434 if (c == L_('.') && p[1] == L_(']'))
444 /* We have to handling the symbols differently in
445 ranges since then the collation sequence is
447 is_range = *p == L_('-') && p[1] != L_('\0');
451 /* There are no names defined in the collation
452 data. Therefore we only accept the trivial
453 names consisting of the character itself. */
457 if (!is_range && *n == startp[1])
466 const int32_t *symb_table;
467 # ifdef WIDE_CHAR_VERSION
471 # define str (startp + 1)
473 const unsigned char *extra;
479 # ifdef WIDE_CHAR_VERSION
480 /* We have to convert the name to a single-byte
481 string. This is possible since the names
482 consist of ASCII characters and the internal
483 representation is UCS4. */
484 for (strcnt = 0; strcnt < c1; ++strcnt)
485 str[strcnt] = startp[1 + strcnt];
489 _NL_CURRENT_WORD (LC_COLLATE,
490 _NL_COLLATE_SYMB_HASH_SIZEMB);
491 symb_table = (const int32_t *)
492 _NL_CURRENT (LC_COLLATE,
493 _NL_COLLATE_SYMB_TABLEMB);
494 extra = (const unsigned char *)
495 _NL_CURRENT (LC_COLLATE,
496 _NL_COLLATE_SYMB_EXTRAMB);
498 /* Locate the character in the hashing table. */
499 hash = elem_hash (str, c1);
502 elem = hash % table_size;
503 if (symb_table[2 * elem] != 0)
505 second = hash % (table_size - 2) + 1;
509 /* First compare the hashing value. */
510 if (symb_table[2 * elem] == hash
512 == extra[symb_table[2 * elem + 1]])
514 &extra[symb_table[2 * elem
518 /* Yep, this is the entry. */
519 idx = symb_table[2 * elem + 1];
520 idx += 1 + extra[idx];
527 while (symb_table[2 * elem] != 0);
530 if (symb_table[2 * elem] != 0)
532 /* Compare the byte sequence but only if
533 this is not part of a range. */
534 # ifdef WIDE_CHAR_VERSION
537 idx += 1 + extra[idx];
538 /* Adjust for the alignment. */
539 idx = (idx + 3) & ~3;
541 wextra = (int32_t *) &extra[idx + 4];
546 # ifdef WIDE_CHAR_VERSION
548 (int32_t) c1 < wextra[idx];
550 if (n[c1] != wextra[1 + c1])
553 if ((int32_t) c1 == wextra[idx])
556 for (c1 = 0; c1 < extra[idx]; ++c1)
557 if (n[c1] != extra[1 + c1])
560 if (c1 == extra[idx])
565 /* Get the collation sequence value. */
567 # ifdef WIDE_CHAR_VERSION
568 cold = wextra[1 + wextra[idx]];
570 /* Adjust for the alignment. */
571 idx += 1 + extra[idx];
572 idx = (idx + 3) & ~4;
573 cold = *((int32_t *) &extra[idx]);
580 /* No valid character. Match it as a
582 if (!is_range && *n == str[0])
599 /* We have to handling the symbols differently in
600 ranges since then the collation sequence is
602 is_range = (*p == L_('-') && p[1] != L_('\0')
605 if (!is_range && c == fn)
609 /* This is needed if we goto normal_bracket; from
610 outside of is_seqval's scope. */
618 if (c == L_('-') && *p != L_(']'))
621 /* We have to find the collation sequence
622 value for C. Collation sequence is nothing
623 we can regularly access. The sequence
624 value is defined by the order in which the
625 definitions of the collation values for the
626 various characters appear in the source
627 file. A strange concept, nowhere
633 # ifdef WIDE_CHAR_VERSION
634 /* Search in the `names' array for the characters. */
635 fcollseq = __collseq_table_lookup (collseq, fn);
636 if (fcollseq == ~((uint32_t) 0))
637 /* XXX We don't know anything about the character
638 we are supposed to match. This means we are
640 goto range_not_matched;
645 lcollseq = __collseq_table_lookup (collseq, cold);
647 fcollseq = collseq[fn];
648 lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
652 if (cend == L_('[') && *p == L_('.'))
655 _NL_CURRENT_WORD (LC_COLLATE,
657 const CHAR *startp = p;
663 if (c == L_('.') && p[1] == L_(']'))
675 /* There are no names defined in the
676 collation data. Therefore we only
677 accept the trivial names consisting
678 of the character itself. */
687 const int32_t *symb_table;
688 # ifdef WIDE_CHAR_VERSION
692 # define str (startp + 1)
694 const unsigned char *extra;
700 # ifdef WIDE_CHAR_VERSION
701 /* We have to convert the name to a single-byte
702 string. This is possible since the names
703 consist of ASCII characters and the internal
704 representation is UCS4. */
705 for (strcnt = 0; strcnt < c1; ++strcnt)
706 str[strcnt] = startp[1 + strcnt];
710 _NL_CURRENT_WORD (LC_COLLATE,
711 _NL_COLLATE_SYMB_HASH_SIZEMB);
712 symb_table = (const int32_t *)
713 _NL_CURRENT (LC_COLLATE,
714 _NL_COLLATE_SYMB_TABLEMB);
715 extra = (const unsigned char *)
716 _NL_CURRENT (LC_COLLATE,
717 _NL_COLLATE_SYMB_EXTRAMB);
719 /* Locate the character in the hashing
721 hash = elem_hash (str, c1);
724 elem = hash % table_size;
725 if (symb_table[2 * elem] != 0)
727 second = hash % (table_size - 2) + 1;
731 /* First compare the hashing value. */
732 if (symb_table[2 * elem] == hash
734 == extra[symb_table[2 * elem + 1]])
736 &extra[symb_table[2 * elem + 1]
739 /* Yep, this is the entry. */
740 idx = symb_table[2 * elem + 1];
741 idx += 1 + extra[idx];
748 while (symb_table[2 * elem] != 0);
751 if (symb_table[2 * elem] != 0)
753 /* Compare the byte sequence but only if
754 this is not part of a range. */
755 # ifdef WIDE_CHAR_VERSION
758 idx += 1 + extra[idx];
759 /* Adjust for the alignment. */
760 idx = (idx + 3) & ~4;
762 wextra = (int32_t *) &extra[idx + 4];
764 /* Get the collation sequence value. */
766 # ifdef WIDE_CHAR_VERSION
767 cend = wextra[1 + wextra[idx]];
769 /* Adjust for the alignment. */
770 idx += 1 + extra[idx];
771 idx = (idx + 3) & ~4;
772 cend = *((int32_t *) &extra[idx]);
775 else if (symb_table[2 * elem] != 0 && c1 == 1)
787 if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
789 if (cend == L_('\0'))
794 /* XXX It is not entirely clear to me how to handle
795 characters which are not mentioned in the
796 collation specification. */
798 # ifdef WIDE_CHAR_VERSION
799 lcollseq == 0xffffffff ||
801 lcollseq <= fcollseq)
803 /* We have to look at the upper bound. */
810 # ifdef WIDE_CHAR_VERSION
812 __collseq_table_lookup (collseq, cend);
813 if (hcollseq == ~((uint32_t) 0))
815 /* Hum, no information about the upper
816 bound. The matching succeeds if the
817 lower bound is matched exactly. */
818 if (lcollseq != fcollseq)
819 goto range_not_matched;
824 hcollseq = collseq[cend];
828 if (lcollseq <= hcollseq && fcollseq <= hcollseq)
831 # ifdef WIDE_CHAR_VERSION
835 /* We use a boring value comparison of the character
836 values. This is better than comparing using
837 `strcoll' since the latter would have surprising
838 and sometimes fatal consequences. */
841 if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
843 if (cend == L_('\0'))
847 if (cold <= fn && fn <= cend)
864 /* Skip the rest of the [...] that already matched. */
871 /* [... (unterminated) loses. */
874 if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
878 /* XXX 1003.2d11 is unclear if this is right. */
881 else if (c == L_('[') && *p == L_(':'))
884 const CHAR *startp = p;
889 if (++c1 == CHAR_CLASS_MAX_LENGTH)
892 if (*p == L_(':') && p[1] == L_(']'))
895 if (c < L_('a') || c >= L_('z'))
904 else if (c == L_('[') && *p == L_('='))
910 if (c != L_('=') || p[1] != L_(']'))
915 else if (c == L_('[') && *p == L_('.'))
924 if (*p == L_('.') && p[1] == L_(']'))
931 while (c != L_(']'));
940 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
944 res = EXT (c, p, n, string_end, no_leading_period, flags);
951 if (NO_LEADING_PERIOD (flags))
953 if (n == string_end || c != (UCHAR) *n)
956 new_no_leading_period = true;
962 if (n == string_end || c != FOLD ((UCHAR) *n))
966 no_leading_period = new_no_leading_period;
973 if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/'))
974 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
983 END (const CHAR *pattern)
985 const CHAR *p = pattern;
988 if (*++p == L_('\0'))
989 /* This is an invalid pattern. */
991 else if (*p == L_('['))
993 /* Handle brackets special. */
994 if (posixly_correct == 0)
995 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
997 /* Skip the not sign. We have to recognize it because of a possibly
999 if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
1001 /* A leading ']' is recognized as such. */
1004 /* Skip over all characters of the list. */
1005 while (*p != L_(']'))
1006 if (*p++ == L_('\0'))
1007 /* This is no valid pattern. */
1010 else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
1011 || *p == L_('!')) && p[1] == L_('('))
1013 else if (*p == L_(')'))
1022 EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
1023 bool no_leading_period, int flags)
1029 struct patternlist *next;
1032 struct patternlist **lastp = &list;
1033 size_t pattern_len = STRLEN (pattern);
1036 enum { ALLOCA_LIMIT = 8000 };
1038 /* Parse the pattern. Store the individual parts in the list. */
1040 for (startp = p = pattern + 1; ; ++p)
1042 /* This is an invalid pattern. */
1044 else if (*p == L_('['))
1046 /* Handle brackets special. */
1047 if (posixly_correct == 0)
1048 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
1050 /* Skip the not sign. We have to recognize it because of a possibly
1052 if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
1054 /* A leading ']' is recognized as such. */
1057 /* Skip over all characters of the list. */
1058 while (*p != L_(']'))
1059 if (*p++ == L_('\0'))
1060 /* This is no valid pattern. */
1063 else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
1064 || *p == L_('!')) && p[1] == L_('('))
1065 /* Remember the nesting level. */
1067 else if (*p == L_(')'))
1071 /* This means we found the end of the pattern. */
1072 #define NEW_PATTERN \
1073 struct patternlist *newp; \
1078 plen = (opt == L_('?') || opt == L_('@') \
1080 : p - startp + 1UL); \
1081 plensize = plen * sizeof (CHAR); \
1082 newpsize = offsetof (struct patternlist, str) + plensize; \
1083 if ((size_t) -1 / sizeof (CHAR) < plen \
1084 || newpsize < offsetof (struct patternlist, str) \
1085 || ALLOCA_LIMIT <= newpsize) \
1087 newp = (struct patternlist *) alloca (newpsize); \
1088 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \
1089 newp->next = NULL; \
1096 else if (*p == L_('|'))
1104 assert (list != NULL);
1105 assert (p[-1] == L_(')'));
1111 if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1118 for (rs = string; rs <= string_end; ++rs)
1119 /* First match the prefix with the current pattern with the
1121 if (FCT (list->str, string, rs, no_leading_period,
1122 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
1123 /* This was successful. Now match the rest with the rest
1125 && (FCT (p, rs, string_end,
1128 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1129 flags & FNM_FILE_NAME
1130 ? flags : flags & ~FNM_PERIOD) == 0
1131 /* This didn't work. Try the whole pattern. */
1133 && FCT (pattern - 1, rs, string_end,
1136 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1137 flags & FNM_FILE_NAME
1138 ? flags : flags & ~FNM_PERIOD) == 0)))
1139 /* It worked. Signal success. */
1142 while ((list = list->next) != NULL);
1144 /* None of the patterns lead to a match. */
1148 if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1154 /* I cannot believe it but `strcat' is actually acceptable
1155 here. Match the entire string with the prefix from the
1156 pattern list and the rest of the pattern following the
1158 if (FCT (STRCAT (list->str, p), string, string_end,
1160 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1161 /* It worked. Signal success. */
1163 while ((list = list->next) != NULL);
1165 /* None of the patterns lead to a match. */
1169 for (rs = string; rs <= string_end; ++rs)
1171 struct patternlist *runp;
1173 for (runp = list; runp != NULL; runp = runp->next)
1174 if (FCT (runp->str, string, rs, no_leading_period,
1175 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1178 /* If none of the patterns matched see whether the rest does. */
1180 && (FCT (p, rs, string_end,
1183 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1184 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
1186 /* This is successful. */
1190 /* None of the patterns together with the rest of the pattern
1195 assert (! "Invalid extended matching operator");