1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Copyright (C) 1991-1993, 1996-2006, 2009-2013 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, see <http://www.gnu.org/licenses/>. */
19 /* Match STRING against the file name pattern PATTERN, returning zero if
20 it matches, nonzero if not. */
21 static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
22 const CHAR *string_end, bool no_leading_period, int flags)
24 static const CHAR *END (const CHAR *patternp) internal_function;
28 FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,
29 bool no_leading_period, int flags)
31 register const CHAR *p = pattern, *n = string;
34 # if WIDE_CHAR_VERSION
35 const char *collseq = (const char *)
36 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
38 const UCHAR *collseq = (const UCHAR *)
39 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
43 while ((c = *p++) != L_('\0'))
45 bool new_no_leading_period = false;
51 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
55 res = EXT (c, p, n, string_end, no_leading_period,
63 else if (*n == L_('/') && (flags & FNM_FILE_NAME))
65 else if (*n == L_('.') && no_leading_period)
70 if (!(flags & FNM_NOESCAPE))
74 /* Trailing \ loses. */
78 if (n == string_end || FOLD ((UCHAR) *n) != c)
83 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
87 res = EXT (c, p, n, string_end, no_leading_period,
93 if (n != string_end && *n == L_('.') && no_leading_period)
96 for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)
98 if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)
100 const CHAR *endp = END (p);
103 /* This is a pattern. Skip over it. */
111 /* A ? needs to match one character. */
113 /* There isn't another character; no match. */
115 else if (*n == L_('/')
116 && __builtin_expect (flags & FNM_FILE_NAME, 0))
117 /* A slash does not match a wildcard under
121 /* One character of the string is consumed in matching
122 this ? wildcard, so *??? won't match if there are
123 less than three characters. */
129 /* The wildcard(s) is/are the last element of the pattern.
130 If the name is a file name and contains another slash
131 this means it cannot match, unless the FNM_LEADING_DIR
134 int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
136 if (flags & FNM_FILE_NAME)
138 if (flags & FNM_LEADING_DIR)
142 if (MEMCHR (n, L_('/'), string_end - n) == NULL)
153 endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'),
159 || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
160 && (c == L_('@') || c == L_('+') || c == L_('!'))
163 int flags2 = ((flags & FNM_FILE_NAME)
164 ? flags : (flags & ~FNM_PERIOD));
165 bool no_leading_period2 = no_leading_period;
167 for (--p; n < endp; ++n, no_leading_period2 = false)
168 if (FCT (p, n, string_end, no_leading_period2, flags2)
172 else if (c == L_('/') && (flags & FNM_FILE_NAME))
174 while (n < string_end && *n != L_('/'))
176 if (n < string_end && *n == L_('/')
177 && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
183 int flags2 = ((flags & FNM_FILE_NAME)
184 ? flags : (flags & ~FNM_PERIOD));
185 int no_leading_period2 = no_leading_period;
187 if (c == L_('\\') && !(flags & FNM_NOESCAPE))
190 for (--p; n < endp; ++n, no_leading_period2 = false)
191 if (FOLD ((UCHAR) *n) == c
192 && (FCT (p, n, string_end, no_leading_period2, flags2)
198 /* If we come here no match is possible with the wildcard. */
203 /* Nonzero if the sense of the character class is inverted. */
204 const CHAR *p_init = p;
205 const CHAR *n_init = n;
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 equivalence class value. */
387 int len = weights[idx & 0xffffff];
389 const UCHAR *np = (const UCHAR *) n;
391 idx2 = findidx (&np);
393 && (idx >> 24) == (idx2 >> 24)
394 && len == weights[idx2 & 0xffffff])
402 && (weights[idx + 1 + cnt]
403 == weights[idx2 + 1 + cnt]))
415 else if (c == L_('\0'))
417 /* [ unterminated, treat as normal character. */
425 bool is_range = false;
428 bool is_seqval = false;
430 if (c == L_('[') && *p == L_('.'))
433 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
434 const CHAR *startp = p;
440 if (c == L_('.') && p[1] == L_(']'))
450 /* We have to handling the symbols differently in
451 ranges since then the collation sequence is
453 is_range = *p == L_('-') && p[1] != L_('\0');
457 /* There are no names defined in the collation
458 data. Therefore we only accept the trivial
459 names consisting of the character itself. */
463 if (!is_range && *n == startp[1])
472 const int32_t *symb_table;
473 # ifdef WIDE_CHAR_VERSION
477 # define str (startp + 1)
479 const unsigned char *extra;
485 # ifdef WIDE_CHAR_VERSION
486 /* We have to convert the name to a single-byte
487 string. This is possible since the names
488 consist of ASCII characters and the internal
489 representation is UCS4. */
490 for (strcnt = 0; strcnt < c1; ++strcnt)
491 str[strcnt] = startp[1 + strcnt];
495 _NL_CURRENT_WORD (LC_COLLATE,
496 _NL_COLLATE_SYMB_HASH_SIZEMB);
497 symb_table = (const int32_t *)
498 _NL_CURRENT (LC_COLLATE,
499 _NL_COLLATE_SYMB_TABLEMB);
500 extra = (const unsigned char *)
501 _NL_CURRENT (LC_COLLATE,
502 _NL_COLLATE_SYMB_EXTRAMB);
504 /* Locate the character in the hashing table. */
505 hash = elem_hash (str, c1);
508 elem = hash % table_size;
509 if (symb_table[2 * elem] != 0)
511 second = hash % (table_size - 2) + 1;
515 /* First compare the hashing value. */
516 if (symb_table[2 * elem] == hash
518 == extra[symb_table[2 * elem + 1]])
520 &extra[symb_table[2 * elem
524 /* Yep, this is the entry. */
525 idx = symb_table[2 * elem + 1];
526 idx += 1 + extra[idx];
533 while (symb_table[2 * elem] != 0);
536 if (symb_table[2 * elem] != 0)
538 /* Compare the byte sequence but only if
539 this is not part of a range. */
540 # ifdef WIDE_CHAR_VERSION
543 idx += 1 + extra[idx];
544 /* Adjust for the alignment. */
545 idx = (idx + 3) & ~3;
547 wextra = (int32_t *) &extra[idx + 4];
552 # ifdef WIDE_CHAR_VERSION
554 (int32_t) c1 < wextra[idx];
556 if (n[c1] != wextra[1 + c1])
559 if ((int32_t) c1 == wextra[idx])
562 for (c1 = 0; c1 < extra[idx]; ++c1)
563 if (n[c1] != extra[1 + c1])
566 if (c1 == extra[idx])
571 /* Get the collation sequence value. */
573 # ifdef WIDE_CHAR_VERSION
574 cold = wextra[1 + wextra[idx]];
576 /* Adjust for the alignment. */
577 idx += 1 + extra[idx];
578 idx = (idx + 3) & ~4;
579 cold = *((int32_t *) &extra[idx]);
586 /* No valid character. Match it as a
588 if (!is_range && *n == str[0])
605 /* We have to handling the symbols differently in
606 ranges since then the collation sequence is
608 is_range = (*p == L_('-') && p[1] != L_('\0')
611 if (!is_range && c == fn)
615 /* This is needed if we goto normal_bracket; from
616 outside of is_seqval's scope. */
624 if (c == L_('-') && *p != L_(']'))
627 /* We have to find the collation sequence
628 value for C. Collation sequence is nothing
629 we can regularly access. The sequence
630 value is defined by the order in which the
631 definitions of the collation values for the
632 various characters appear in the source
633 file. A strange concept, nowhere
639 # ifdef WIDE_CHAR_VERSION
640 /* Search in the 'names' array for the characters. */
641 fcollseq = __collseq_table_lookup (collseq, fn);
642 if (fcollseq == ~((uint32_t) 0))
643 /* XXX We don't know anything about the character
644 we are supposed to match. This means we are
646 goto range_not_matched;
651 lcollseq = __collseq_table_lookup (collseq, cold);
653 fcollseq = collseq[fn];
654 lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
658 if (cend == L_('[') && *p == L_('.'))
661 _NL_CURRENT_WORD (LC_COLLATE,
663 const CHAR *startp = p;
669 if (c == L_('.') && p[1] == L_(']'))
681 /* There are no names defined in the
682 collation data. Therefore we only
683 accept the trivial names consisting
684 of the character itself. */
693 const int32_t *symb_table;
694 # ifdef WIDE_CHAR_VERSION
698 # define str (startp + 1)
700 const unsigned char *extra;
706 # ifdef WIDE_CHAR_VERSION
707 /* We have to convert the name to a single-byte
708 string. This is possible since the names
709 consist of ASCII characters and the internal
710 representation is UCS4. */
711 for (strcnt = 0; strcnt < c1; ++strcnt)
712 str[strcnt] = startp[1 + strcnt];
716 _NL_CURRENT_WORD (LC_COLLATE,
717 _NL_COLLATE_SYMB_HASH_SIZEMB);
718 symb_table = (const int32_t *)
719 _NL_CURRENT (LC_COLLATE,
720 _NL_COLLATE_SYMB_TABLEMB);
721 extra = (const unsigned char *)
722 _NL_CURRENT (LC_COLLATE,
723 _NL_COLLATE_SYMB_EXTRAMB);
725 /* Locate the character in the hashing
727 hash = elem_hash (str, c1);
730 elem = hash % table_size;
731 if (symb_table[2 * elem] != 0)
733 second = hash % (table_size - 2) + 1;
737 /* First compare the hashing value. */
738 if (symb_table[2 * elem] == hash
740 == extra[symb_table[2 * elem + 1]])
742 &extra[symb_table[2 * elem + 1]
745 /* Yep, this is the entry. */
746 idx = symb_table[2 * elem + 1];
747 idx += 1 + extra[idx];
754 while (symb_table[2 * elem] != 0);
757 if (symb_table[2 * elem] != 0)
759 /* Compare the byte sequence but only if
760 this is not part of a range. */
761 # ifdef WIDE_CHAR_VERSION
764 idx += 1 + extra[idx];
765 /* Adjust for the alignment. */
766 idx = (idx + 3) & ~4;
768 wextra = (int32_t *) &extra[idx + 4];
770 /* Get the collation sequence value. */
772 # ifdef WIDE_CHAR_VERSION
773 cend = wextra[1 + wextra[idx]];
775 /* Adjust for the alignment. */
776 idx += 1 + extra[idx];
777 idx = (idx + 3) & ~4;
778 cend = *((int32_t *) &extra[idx]);
781 else if (symb_table[2 * elem] != 0 && c1 == 1)
793 if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
795 if (cend == L_('\0'))
800 /* XXX It is not entirely clear to me how to handle
801 characters which are not mentioned in the
802 collation specification. */
804 # ifdef WIDE_CHAR_VERSION
805 lcollseq == 0xffffffff ||
807 lcollseq <= fcollseq)
809 /* We have to look at the upper bound. */
816 # ifdef WIDE_CHAR_VERSION
818 __collseq_table_lookup (collseq, cend);
819 if (hcollseq == ~((uint32_t) 0))
821 /* Hum, no information about the upper
822 bound. The matching succeeds if the
823 lower bound is matched exactly. */
824 if (lcollseq != fcollseq)
825 goto range_not_matched;
830 hcollseq = collseq[cend];
834 if (lcollseq <= hcollseq && fcollseq <= hcollseq)
837 # ifdef WIDE_CHAR_VERSION
841 /* We use a boring value comparison of the character
842 values. This is better than comparing using
843 'strcoll' since the latter would have surprising
844 and sometimes fatal consequences. */
847 if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
849 if (cend == L_('\0'))
853 if (cold <= fn && fn <= cend)
870 /* Skip the rest of the [...] that already matched. */
877 /* [... (unterminated) loses. */
880 if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
884 /* XXX 1003.2d11 is unclear if this is right. */
887 else if (c == L_('[') && *p == L_(':'))
890 const CHAR *startp = p;
895 if (++c1 == CHAR_CLASS_MAX_LENGTH)
898 if (*p == L_(':') && p[1] == L_(']'))
901 if (c < L_('a') || c >= L_('z'))
910 else if (c == L_('[') && *p == L_('='))
916 if (c != L_('=') || p[1] != L_(']'))
921 else if (c == L_('[') && *p == L_('.'))
930 if (*p == L_('.') && p[1] == L_(']'))
937 while (c != L_(']'));
946 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
950 res = EXT (c, p, n, string_end, no_leading_period, flags);
957 if (NO_LEADING_PERIOD (flags))
959 if (n == string_end || c != (UCHAR) *n)
962 new_no_leading_period = true;
968 if (n == string_end || c != FOLD ((UCHAR) *n))
972 no_leading_period = new_no_leading_period;
979 if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/'))
980 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
989 END (const CHAR *pattern)
991 const CHAR *p = pattern;
994 if (*++p == L_('\0'))
995 /* This is an invalid pattern. */
997 else if (*p == L_('['))
999 /* Handle brackets special. */
1000 if (posixly_correct == 0)
1001 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
1003 /* Skip the not sign. We have to recognize it because of a possibly
1005 if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
1007 /* A leading ']' is recognized as such. */
1010 /* Skip over all characters of the list. */
1011 while (*p != L_(']'))
1012 if (*p++ == L_('\0'))
1013 /* This is no valid pattern. */
1016 else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
1017 || *p == L_('!')) && p[1] == L_('('))
1019 else if (*p == L_(')'))
1028 EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
1029 bool no_leading_period, int flags)
1035 struct patternlist *next;
1038 struct patternlist **lastp = &list;
1039 size_t pattern_len = STRLEN (pattern);
1042 enum { ALLOCA_LIMIT = 8000 };
1044 /* Parse the pattern. Store the individual parts in the list. */
1046 for (startp = p = pattern + 1; ; ++p)
1048 /* This is an invalid pattern. */
1050 else if (*p == L_('['))
1052 /* Handle brackets special. */
1053 if (posixly_correct == 0)
1054 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
1056 /* Skip the not sign. We have to recognize it because of a possibly
1058 if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
1060 /* A leading ']' is recognized as such. */
1063 /* Skip over all characters of the list. */
1064 while (*p != L_(']'))
1065 if (*p++ == L_('\0'))
1066 /* This is no valid pattern. */
1069 else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
1070 || *p == L_('!')) && p[1] == L_('('))
1071 /* Remember the nesting level. */
1073 else if (*p == L_(')'))
1077 /* This means we found the end of the pattern. */
1078 #define NEW_PATTERN \
1079 struct patternlist *newp; \
1084 plen = (opt == L_('?') || opt == L_('@') \
1086 : p - startp + 1UL); \
1087 plensize = plen * sizeof (CHAR); \
1088 newpsize = offsetof (struct patternlist, str) + plensize; \
1089 if ((size_t) -1 / sizeof (CHAR) < plen \
1090 || newpsize < offsetof (struct patternlist, str) \
1091 || ALLOCA_LIMIT <= newpsize) \
1093 newp = (struct patternlist *) alloca (newpsize); \
1094 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \
1095 newp->next = NULL; \
1102 else if (*p == L_('|'))
1110 assert (list != NULL);
1111 assert (p[-1] == L_(')'));
1117 if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1124 for (rs = string; rs <= string_end; ++rs)
1125 /* First match the prefix with the current pattern with the
1127 if (FCT (list->str, string, rs, no_leading_period,
1128 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
1129 /* This was successful. Now match the rest with the rest
1131 && (FCT (p, rs, string_end,
1134 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1135 flags & FNM_FILE_NAME
1136 ? flags : flags & ~FNM_PERIOD) == 0
1137 /* This didn't work. Try the whole pattern. */
1139 && FCT (pattern - 1, rs, string_end,
1142 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1143 flags & FNM_FILE_NAME
1144 ? flags : flags & ~FNM_PERIOD) == 0)))
1145 /* It worked. Signal success. */
1148 while ((list = list->next) != NULL);
1150 /* None of the patterns lead to a match. */
1154 if (FCT (p, string, string_end, no_leading_period, flags) == 0)
1160 /* I cannot believe it but 'strcat' is actually acceptable
1161 here. Match the entire string with the prefix from the
1162 pattern list and the rest of the pattern following the
1164 if (FCT (STRCAT (list->str, p), string, string_end,
1166 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1167 /* It worked. Signal success. */
1169 while ((list = list->next) != NULL);
1171 /* None of the patterns lead to a match. */
1175 for (rs = string; rs <= string_end; ++rs)
1177 struct patternlist *runp;
1179 for (runp = list; runp != NULL; runp = runp->next)
1180 if (FCT (runp->str, string, rs, no_leading_period,
1181 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1184 /* If none of the patterns matched see whether the rest does. */
1186 && (FCT (p, rs, string_end,
1189 : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
1190 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
1192 /* This is successful. */
1196 /* None of the patterns together with the rest of the pattern
1201 assert (! "Invalid extended matching operator");