1 /* Copyright (C) 1991-2017 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C 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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
24 int no_leading_period
;
27 /* Match STRING against the filename pattern PATTERN, returning zero if
28 it matches, nonzero if not. */
29 static int FCT (const CHAR
*pattern
, const CHAR
*string
,
30 const CHAR
*string_end
, int no_leading_period
, int flags
,
31 struct STRUCT
*ends
, size_t alloca_used
)
33 static int EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
,
34 const CHAR
*string_end
, int no_leading_period
, int flags
,
37 static const CHAR
*END (const CHAR
*patternp
) internal_function
;
41 FCT (const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
42 int no_leading_period
, int flags
, struct STRUCT
*ends
, size_t alloca_used
)
44 const CHAR
*p
= pattern
, *n
= string
;
47 # if WIDE_CHAR_VERSION
48 const char *collseq
= (const char *)
49 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQWC
);
51 const UCHAR
*collseq
= (const UCHAR
*)
52 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQMB
);
56 while ((c
= *p
++) != L('\0'))
58 int new_no_leading_period
= 0;
64 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
66 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
74 else if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
76 else if (*n
== L('.') && no_leading_period
)
81 if (!(flags
& FNM_NOESCAPE
))
85 /* Trailing \ loses. */
89 if (n
== string_end
|| FOLD ((UCHAR
) *n
) != c
)
94 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
96 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
101 else if (ends
!= NULL
)
103 ends
->pattern
= p
- 1;
105 ends
->no_leading_period
= no_leading_period
;
109 if (n
!= string_end
&& *n
== L('.') && no_leading_period
)
112 for (c
= *p
++; c
== L('?') || c
== L('*'); c
= *p
++)
114 if (*p
== L('(') && (flags
& FNM_EXTMATCH
) != 0)
116 const CHAR
*endp
= END (p
);
119 /* This is a pattern. Skip over it. */
127 /* A ? needs to match one character. */
129 /* There isn't another character; no match. */
131 else if (*n
== L('/')
132 && __builtin_expect (flags
& FNM_FILE_NAME
, 0))
133 /* A slash does not match a wildcard under
137 /* One character of the string is consumed in matching
138 this ? wildcard, so *??? won't match if there are
139 less than three characters. */
145 /* The wildcard(s) is/are the last element of the pattern.
146 If the name is a file name and contains another slash
147 this means it cannot match, unless the FNM_LEADING_DIR
150 int result
= (flags
& FNM_FILE_NAME
) == 0 ? 0 : FNM_NOMATCH
;
152 if (flags
& FNM_FILE_NAME
)
154 if (flags
& FNM_LEADING_DIR
)
158 if (MEMCHR (n
, L('/'), string_end
- n
) == NULL
)
171 endp
= MEMCHR (n
, (flags
& FNM_FILE_NAME
) ? L('/') : L('\0'),
177 || (__builtin_expect (flags
& FNM_EXTMATCH
, 0) != 0
178 && (c
== L('@') || c
== L('+') || c
== L('!'))
181 int flags2
= ((flags
& FNM_FILE_NAME
)
182 ? flags
: (flags
& ~FNM_PERIOD
));
184 for (--p
; n
< endp
; ++n
, no_leading_period
= 0)
185 if (FCT (p
, n
, string_end
, no_leading_period
, flags2
,
186 &end
, alloca_used
) == 0)
189 else if (c
== L('/') && (flags
& FNM_FILE_NAME
))
191 while (n
< string_end
&& *n
!= L('/'))
193 if (n
< string_end
&& *n
== L('/')
194 && (FCT (p
, n
+ 1, string_end
, flags
& FNM_PERIOD
, flags
,
195 NULL
, alloca_used
) == 0))
200 int flags2
= ((flags
& FNM_FILE_NAME
)
201 ? flags
: (flags
& ~FNM_PERIOD
));
203 if (c
== L('\\') && !(flags
& FNM_NOESCAPE
))
206 for (--p
; n
< endp
; ++n
, no_leading_period
= 0)
207 if (FOLD ((UCHAR
) *n
) == c
208 && (FCT (p
, n
, string_end
, no_leading_period
, flags2
,
209 &end
, alloca_used
) == 0))
212 if (end
.pattern
== NULL
)
216 if (end
.pattern
!= NULL
)
220 no_leading_period
= end
.no_leading_period
;
226 /* If we come here no match is possible with the wildcard. */
231 /* Nonzero if the sense of the character class is inverted. */
232 const CHAR
*p_init
= p
;
233 const CHAR
*n_init
= n
;
238 if (posixly_correct
== 0)
239 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
244 if (*n
== L('.') && no_leading_period
)
247 if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
248 /* `/' cannot be matched. */
251 not = (*p
== L('!') || (posixly_correct
< 0 && *p
== L('^')));
255 fn
= FOLD ((UCHAR
) *n
);
260 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
264 c
= FOLD ((UCHAR
) *p
);
269 else if (c
== L('[') && *p
== L(':'))
271 /* Leave room for the null. */
272 CHAR str
[CHAR_CLASS_MAX_LENGTH
+ 1];
274 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
277 const CHAR
*startp
= p
;
281 if (c1
== CHAR_CLASS_MAX_LENGTH
)
282 /* The name is too long and therefore the pattern
287 if (c
== L(':') && p
[1] == L(']'))
292 if (c
< L('a') || c
>= L('z'))
294 /* This cannot possibly be a character class name.
295 Match it as a normal range. */
304 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
305 wt
= IS_CHAR_CLASS (str
);
307 /* Invalid character class name. */
310 # if defined _LIBC && ! WIDE_CHAR_VERSION
311 /* The following code is glibc specific but does
312 there a good job in speeding up the code since
313 we can avoid the btowc() call. */
314 if (_ISCTYPE ((UCHAR
) *n
, wt
))
317 if (ISWCTYPE (BTOWC ((UCHAR
) *n
), wt
))
321 if ((STREQ (str
, L("alnum")) && ISALNUM ((UCHAR
) *n
))
322 || (STREQ (str
, L("alpha")) && ISALPHA ((UCHAR
) *n
))
323 || (STREQ (str
, L("blank")) && ISBLANK ((UCHAR
) *n
))
324 || (STREQ (str
, L("cntrl")) && ISCNTRL ((UCHAR
) *n
))
325 || (STREQ (str
, L("digit")) && ISDIGIT ((UCHAR
) *n
))
326 || (STREQ (str
, L("graph")) && ISGRAPH ((UCHAR
) *n
))
327 || (STREQ (str
, L("lower")) && ISLOWER ((UCHAR
) *n
))
328 || (STREQ (str
, L("print")) && ISPRINT ((UCHAR
) *n
))
329 || (STREQ (str
, L("punct")) && ISPUNCT ((UCHAR
) *n
))
330 || (STREQ (str
, L("space")) && ISSPACE ((UCHAR
) *n
))
331 || (STREQ (str
, L("upper")) && ISUPPER ((UCHAR
) *n
))
332 || (STREQ (str
, L("xdigit")) && ISXDIGIT ((UCHAR
) *n
)))
338 else if (c
== L('[') && *p
== L('='))
340 /* It's important that STR be a scalar variable rather
341 than a one-element array, because GCC (at least 4.9.2
342 -O2 on x86-64) can be confused by the array and
343 diagnose a "used initialized" in a dead branch in the
347 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
348 const CHAR
*startp
= p
;
360 if (c
!= L('=') || p
[1] != L(']'))
370 if ((UCHAR
) *n
== str
)
375 const int32_t *table
;
376 # if WIDE_CHAR_VERSION
377 const int32_t *weights
;
380 const unsigned char *weights
;
381 const unsigned char *extra
;
383 const int32_t *indirect
;
385 const UCHAR
*cp
= (const UCHAR
*) &str
;
387 # if WIDE_CHAR_VERSION
388 table
= (const int32_t *)
389 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEWC
);
390 weights
= (const int32_t *)
391 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTWC
);
392 extra
= (const wint_t *)
393 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAWC
);
394 indirect
= (const int32_t *)
395 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTWC
);
397 table
= (const int32_t *)
398 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEMB
);
399 weights
= (const unsigned char *)
400 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTMB
);
401 extra
= (const unsigned char *)
402 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAMB
);
403 indirect
= (const int32_t *)
404 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTMB
);
407 idx
= FINDIDX (table
, indirect
, extra
, &cp
, 1);
410 /* We found a table entry. Now see whether the
411 character we are currently at has the same
412 equivalance class value. */
413 int len
= weights
[idx
& 0xffffff];
415 const UCHAR
*np
= (const UCHAR
*) n
;
417 idx2
= FINDIDX (table
, indirect
, extra
,
418 &np
, string_end
- n
);
420 && (idx
>> 24) == (idx2
>> 24)
421 && len
== weights
[idx2
& 0xffffff])
429 && (weights
[idx
+ 1 + cnt
]
430 == weights
[idx2
+ 1 + cnt
]))
442 else if (c
== L('\0'))
444 /* [ unterminated, treat as normal character. */
457 if (c
== L('[') && *p
== L('.'))
460 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
461 const CHAR
*startp
= p
;
467 if (c
== L('.') && p
[1] == L(']'))
477 /* We have to handling the symbols differently in
478 ranges since then the collation sequence is
480 is_range
= *p
== L('-') && p
[1] != L('\0');
484 /* There are no names defined in the collation
485 data. Therefore we only accept the trivial
486 names consisting of the character itself. */
490 if (!is_range
&& *n
== startp
[1])
499 const int32_t *symb_table
;
500 # if WIDE_CHAR_VERSION
504 # define str (startp + 1)
506 const unsigned char *extra
;
512 # if WIDE_CHAR_VERSION
513 /* We have to convert the name to a single-byte
514 string. This is possible since the names
515 consist of ASCII characters and the internal
516 representation is UCS4. */
517 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
518 str
[strcnt
] = startp
[1 + strcnt
];
522 _NL_CURRENT_WORD (LC_COLLATE
,
523 _NL_COLLATE_SYMB_HASH_SIZEMB
);
524 symb_table
= (const int32_t *)
525 _NL_CURRENT (LC_COLLATE
,
526 _NL_COLLATE_SYMB_TABLEMB
);
527 extra
= (const unsigned char *)
528 _NL_CURRENT (LC_COLLATE
,
529 _NL_COLLATE_SYMB_EXTRAMB
);
531 /* Locate the character in the hashing table. */
532 hash
= elem_hash (str
, c1
);
535 elem
= hash
% table_size
;
536 if (symb_table
[2 * elem
] != 0)
538 second
= hash
% (table_size
- 2) + 1;
542 /* First compare the hashing value. */
543 if (symb_table
[2 * elem
] == hash
545 == extra
[symb_table
[2 * elem
+ 1]])
547 &extra
[symb_table
[2 * elem
551 /* Yep, this is the entry. */
552 idx
= symb_table
[2 * elem
+ 1];
553 idx
+= 1 + extra
[idx
];
560 while (symb_table
[2 * elem
] != 0);
563 if (symb_table
[2 * elem
] != 0)
565 /* Compare the byte sequence but only if
566 this is not part of a range. */
567 # if WIDE_CHAR_VERSION
570 idx
+= 1 + extra
[idx
];
571 /* Adjust for the alignment. */
572 idx
= (idx
+ 3) & ~3;
574 wextra
= (int32_t *) &extra
[idx
+ 4];
579 # if WIDE_CHAR_VERSION
581 (int32_t) c1
< wextra
[idx
];
583 if (n
[c1
] != wextra
[1 + c1
])
586 if ((int32_t) c1
== wextra
[idx
])
589 for (c1
= 0; c1
< extra
[idx
]; ++c1
)
590 if (n
[c1
] != extra
[1 + c1
])
593 if (c1
== extra
[idx
])
598 /* Get the collation sequence value. */
600 # if WIDE_CHAR_VERSION
601 cold
= wextra
[1 + wextra
[idx
]];
603 /* Adjust for the alignment. */
604 idx
+= 1 + extra
[idx
];
605 idx
= (idx
+ 3) & ~4;
606 cold
= *((int32_t *) &extra
[idx
]);
613 /* No valid character. Match it as a
615 if (!is_range
&& *n
== str
[0])
632 /* We have to handling the symbols differently in
633 ranges since then the collation sequence is
635 is_range
= (*p
== L('-') && p
[1] != L('\0')
638 if (!is_range
&& c
== fn
)
641 /* This is needed if we goto normal_bracket; from
642 outside of is_seqval's scope. */
648 if (c
== L('-') && *p
!= L(']'))
651 /* We have to find the collation sequence
652 value for C. Collation sequence is nothing
653 we can regularly access. The sequence
654 value is defined by the order in which the
655 definitions of the collation values for the
656 various characters appear in the source
657 file. A strange concept, nowhere
663 # if WIDE_CHAR_VERSION
664 /* Search in the `names' array for the characters. */
665 fcollseq
= __collseq_table_lookup (collseq
, fn
);
666 if (fcollseq
== ~((uint32_t) 0))
667 /* XXX We don't know anything about the character
668 we are supposed to match. This means we are
670 goto range_not_matched
;
675 lcollseq
= __collseq_table_lookup (collseq
, cold
);
677 fcollseq
= collseq
[fn
];
678 lcollseq
= is_seqval
? cold
: collseq
[(UCHAR
) cold
];
682 if (cend
== L('[') && *p
== L('.'))
685 _NL_CURRENT_WORD (LC_COLLATE
,
687 const CHAR
*startp
= p
;
693 if (c
== L('.') && p
[1] == L(']'))
705 /* There are no names defined in the
706 collation data. Therefore we only
707 accept the trivial names consisting
708 of the character itself. */
717 const int32_t *symb_table
;
718 # if WIDE_CHAR_VERSION
722 # define str (startp + 1)
724 const unsigned char *extra
;
730 # if WIDE_CHAR_VERSION
731 /* We have to convert the name to a single-byte
732 string. This is possible since the names
733 consist of ASCII characters and the internal
734 representation is UCS4. */
735 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
736 str
[strcnt
] = startp
[1 + strcnt
];
740 _NL_CURRENT_WORD (LC_COLLATE
,
741 _NL_COLLATE_SYMB_HASH_SIZEMB
);
742 symb_table
= (const int32_t *)
743 _NL_CURRENT (LC_COLLATE
,
744 _NL_COLLATE_SYMB_TABLEMB
);
745 extra
= (const unsigned char *)
746 _NL_CURRENT (LC_COLLATE
,
747 _NL_COLLATE_SYMB_EXTRAMB
);
749 /* Locate the character in the hashing
751 hash
= elem_hash (str
, c1
);
754 elem
= hash
% table_size
;
755 if (symb_table
[2 * elem
] != 0)
757 second
= hash
% (table_size
- 2) + 1;
761 /* First compare the hashing value. */
762 if (symb_table
[2 * elem
] == hash
764 == extra
[symb_table
[2 * elem
+ 1]])
766 &extra
[symb_table
[2 * elem
+ 1]
769 /* Yep, this is the entry. */
770 idx
= symb_table
[2 * elem
+ 1];
771 idx
+= 1 + extra
[idx
];
778 while (symb_table
[2 * elem
] != 0);
781 if (symb_table
[2 * elem
] != 0)
783 /* Compare the byte sequence but only if
784 this is not part of a range. */
785 # if WIDE_CHAR_VERSION
788 idx
+= 1 + extra
[idx
];
789 /* Adjust for the alignment. */
790 idx
= (idx
+ 3) & ~4;
792 wextra
= (int32_t *) &extra
[idx
+ 4];
794 /* Get the collation sequence value. */
796 # if WIDE_CHAR_VERSION
797 cend
= wextra
[1 + wextra
[idx
]];
799 /* Adjust for the alignment. */
800 idx
+= 1 + extra
[idx
];
801 idx
= (idx
+ 3) & ~4;
802 cend
= *((int32_t *) &extra
[idx
]);
805 else if (symb_table
[2 * elem
] != 0 && c1
== 1)
817 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
824 /* XXX It is not entirely clear to me how to handle
825 characters which are not mentioned in the
826 collation specification. */
828 # if WIDE_CHAR_VERSION
829 lcollseq
== 0xffffffff ||
831 lcollseq
<= fcollseq
)
833 /* We have to look at the upper bound. */
840 # if WIDE_CHAR_VERSION
842 __collseq_table_lookup (collseq
, cend
);
843 if (hcollseq
== ~((uint32_t) 0))
845 /* Hum, no information about the upper
846 bound. The matching succeeds if the
847 lower bound is matched exactly. */
848 if (lcollseq
!= fcollseq
)
849 goto range_not_matched
;
854 hcollseq
= collseq
[cend
];
858 if (lcollseq
<= hcollseq
&& fcollseq
<= hcollseq
)
861 # if WIDE_CHAR_VERSION
865 /* We use a boring value comparison of the character
866 values. This is better than comparing using
867 `strcoll' since the latter would have surprising
868 and sometimes fatal consequences. */
871 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
877 if (cold
<= fn
&& fn
<= cend
)
894 /* Skip the rest of the [...] that already matched. */
895 while ((c
= *p
++) != L (']'))
898 /* [... (unterminated) loses. */
901 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
905 /* XXX 1003.2d11 is unclear if this is right. */
908 else if (c
== L('[') && *p
== L(':'))
911 const CHAR
*startp
= p
;
916 if (++c1
== CHAR_CLASS_MAX_LENGTH
)
919 if (*p
== L(':') && p
[1] == L(']'))
922 if (c
< L('a') || c
>= L('z'))
930 else if (c
== L('[') && *p
== L('='))
936 if (c
!= L('=') || p
[1] != L(']'))
940 else if (c
== L('[') && *p
== L('.'))
948 if (c
== L('.') && p
[1] == L(']'))
962 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
964 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
, flags
,
972 if (NO_LEADING_PERIOD (flags
))
974 if (n
== string_end
|| c
!= (UCHAR
) *n
)
977 new_no_leading_period
= 1;
983 if (n
== string_end
|| c
!= FOLD ((UCHAR
) *n
))
987 no_leading_period
= new_no_leading_period
;
994 if ((flags
& FNM_LEADING_DIR
) && n
!= string_end
&& *n
== L('/'))
995 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
1004 END (const CHAR
*pattern
)
1006 const CHAR
*p
= pattern
;
1009 if (*++p
== L('\0'))
1010 /* This is an invalid pattern. */
1012 else if (*p
== L('['))
1014 /* Handle brackets special. */
1015 if (posixly_correct
== 0)
1016 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1018 /* Skip the not sign. We have to recognize it because of a possibly
1020 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1022 /* A leading ']' is recognized as such. */
1025 /* Skip over all characters of the list. */
1026 while (*p
!= L(']'))
1027 if (*p
++ == L('\0'))
1028 /* This is no valid pattern. */
1031 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1032 || *p
== L('!')) && p
[1] == L('('))
1036 /* This is an invalid pattern. */
1039 else if (*p
== L(')'))
1048 EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
1049 int no_leading_period
, int flags
, size_t alloca_used
)
1055 struct patternlist
*next
;
1059 struct patternlist
**lastp
= &list
;
1060 size_t pattern_len
= STRLEN (pattern
);
1061 int any_malloced
= 0;
1066 /* Parse the pattern. Store the individual parts in the list. */
1068 for (startp
= p
= pattern
+ 1; level
>= 0; ++p
)
1071 /* This is an invalid pattern. */
1075 else if (*p
== L('['))
1077 /* Handle brackets special. */
1078 if (posixly_correct
== 0)
1079 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1081 /* Skip the not sign. We have to recognize it because of a possibly
1083 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1085 /* A leading ']' is recognized as such. */
1088 /* Skip over all characters of the list. */
1089 while (*p
!= L(']'))
1090 if (*p
++ == L('\0'))
1092 /* This is no valid pattern. */
1097 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1098 || *p
== L('!')) && p
[1] == L('('))
1099 /* Remember the nesting level. */
1101 else if (*p
== L(')'))
1105 /* This means we found the end of the pattern. */
1106 #define NEW_PATTERN \
1107 struct patternlist *newp; \
1108 size_t slen = (opt == L('?') || opt == L('@') \
1109 ? pattern_len : (p - startp + 1)); \
1110 slen = sizeof (struct patternlist) + (slen * sizeof (CHAR)); \
1111 int malloced = ! __libc_use_alloca (alloca_used + slen); \
1112 if (__builtin_expect (malloced, 0)) \
1114 newp = malloc (slen); \
1123 newp = alloca_account (slen, alloca_used); \
1124 newp->next = NULL; \
1125 newp->malloced = malloced; \
1126 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1132 else if (*p
== L('|'))
1140 assert (list
!= NULL
);
1141 assert (p
[-1] == L(')'));
1147 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1155 for (rs
= string
; rs
<= string_end
; ++rs
)
1156 /* First match the prefix with the current pattern with the
1158 if (FCT (list
->str
, string
, rs
, no_leading_period
,
1159 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1160 NULL
, alloca_used
) == 0
1161 /* This was successful. Now match the rest with the rest
1163 && (FCT (p
, rs
, string_end
,
1166 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1167 flags
& FNM_FILE_NAME
1168 ? flags
: flags
& ~FNM_PERIOD
, NULL
, alloca_used
) == 0
1169 /* This didn't work. Try the whole pattern. */
1171 && FCT (pattern
- 1, rs
, string_end
,
1174 : (rs
[-1] == '/' && NO_LEADING_PERIOD (flags
)
1176 flags
& FNM_FILE_NAME
1177 ? flags
: flags
& ~FNM_PERIOD
, NULL
,
1178 alloca_used
) == 0)))
1179 /* It worked. Signal success. */
1182 while ((list
= list
->next
) != NULL
);
1184 /* None of the patterns lead to a match. */
1185 retval
= FNM_NOMATCH
;
1189 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1196 /* I cannot believe it but `strcat' is actually acceptable
1197 here. Match the entire string with the prefix from the
1198 pattern list and the rest of the pattern following the
1200 if (FCT (STRCAT (list
->str
, p
), string
, string_end
,
1202 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1203 NULL
, alloca_used
) == 0)
1204 /* It worked. Signal success. */
1206 while ((list
= list
->next
) != NULL
);
1208 /* None of the patterns lead to a match. */
1209 retval
= FNM_NOMATCH
;
1213 for (rs
= string
; rs
<= string_end
; ++rs
)
1215 struct patternlist
*runp
;
1217 for (runp
= list
; runp
!= NULL
; runp
= runp
->next
)
1218 if (FCT (runp
->str
, string
, rs
, no_leading_period
,
1219 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1220 NULL
, alloca_used
) == 0)
1223 /* If none of the patterns matched see whether the rest does. */
1225 && (FCT (p
, rs
, string_end
,
1228 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1229 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1230 NULL
, alloca_used
) == 0))
1231 /* This is successful. */
1235 /* None of the patterns together with the rest of the pattern
1237 retval
= FNM_NOMATCH
;
1241 assert (! "Invalid extended matching operator");
1249 while (list
!= NULL
)
1251 struct patternlist
*old
= list
;
1276 #undef WIDE_CHAR_VERSION