1 /* Copyright (C) 1991-2014 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 (pattern
, string
, string_end
, no_leading_period
, flags
, ends
, alloca_used
)
44 const CHAR
*string_end
;
45 int no_leading_period
;
50 const CHAR
*p
= pattern
, *n
= string
;
53 # if WIDE_CHAR_VERSION
54 const char *collseq
= (const char *)
55 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQWC
);
57 const UCHAR
*collseq
= (const UCHAR
*)
58 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQMB
);
62 while ((c
= *p
++) != L('\0'))
64 int new_no_leading_period
= 0;
70 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
72 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
80 else if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
82 else if (*n
== L('.') && no_leading_period
)
87 if (!(flags
& FNM_NOESCAPE
))
91 /* Trailing \ loses. */
95 if (n
== string_end
|| FOLD ((UCHAR
) *n
) != c
)
100 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
102 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
107 else if (ends
!= NULL
)
109 ends
->pattern
= p
- 1;
111 ends
->no_leading_period
= no_leading_period
;
115 if (n
!= string_end
&& *n
== L('.') && no_leading_period
)
118 for (c
= *p
++; c
== L('?') || c
== L('*'); c
= *p
++)
120 if (*p
== L('(') && (flags
& FNM_EXTMATCH
) != 0)
122 const CHAR
*endp
= END (p
);
125 /* This is a pattern. Skip over it. */
133 /* A ? needs to match one character. */
135 /* There isn't another character; no match. */
137 else if (*n
== L('/')
138 && __builtin_expect (flags
& FNM_FILE_NAME
, 0))
139 /* A slash does not match a wildcard under
143 /* One character of the string is consumed in matching
144 this ? wildcard, so *??? won't match if there are
145 less than three characters. */
151 /* The wildcard(s) is/are the last element of the pattern.
152 If the name is a file name and contains another slash
153 this means it cannot match, unless the FNM_LEADING_DIR
156 int result
= (flags
& FNM_FILE_NAME
) == 0 ? 0 : FNM_NOMATCH
;
158 if (flags
& FNM_FILE_NAME
)
160 if (flags
& FNM_LEADING_DIR
)
164 if (MEMCHR (n
, L('/'), string_end
- n
) == NULL
)
177 endp
= MEMCHR (n
, (flags
& FNM_FILE_NAME
) ? L('/') : L('\0'),
183 || (__builtin_expect (flags
& FNM_EXTMATCH
, 0) != 0
184 && (c
== L('@') || c
== L('+') || c
== L('!'))
187 int flags2
= ((flags
& FNM_FILE_NAME
)
188 ? flags
: (flags
& ~FNM_PERIOD
));
190 for (--p
; n
< endp
; ++n
, no_leading_period
= 0)
191 if (FCT (p
, n
, string_end
, no_leading_period
, flags2
,
192 &end
, alloca_used
) == 0)
195 else if (c
== L('/') && (flags
& FNM_FILE_NAME
))
197 while (n
< string_end
&& *n
!= L('/'))
199 if (n
< string_end
&& *n
== L('/')
200 && (FCT (p
, n
+ 1, string_end
, flags
& FNM_PERIOD
, flags
,
201 NULL
, alloca_used
) == 0))
206 int flags2
= ((flags
& FNM_FILE_NAME
)
207 ? flags
: (flags
& ~FNM_PERIOD
));
209 if (c
== L('\\') && !(flags
& FNM_NOESCAPE
))
212 for (--p
; n
< endp
; ++n
, no_leading_period
= 0)
213 if (FOLD ((UCHAR
) *n
) == c
214 && (FCT (p
, n
, string_end
, no_leading_period
, flags2
,
215 &end
, alloca_used
) == 0))
218 if (end
.pattern
== NULL
)
222 if (end
.pattern
!= NULL
)
226 no_leading_period
= end
.no_leading_period
;
232 /* If we come here no match is possible with the wildcard. */
237 /* Nonzero if the sense of the character class is inverted. */
238 const CHAR
*p_init
= p
;
239 const CHAR
*n_init
= n
;
244 if (posixly_correct
== 0)
245 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
250 if (*n
== L('.') && no_leading_period
)
253 if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
254 /* `/' cannot be matched. */
257 not = (*p
== L('!') || (posixly_correct
< 0 && *p
== L('^')));
261 fn
= FOLD ((UCHAR
) *n
);
266 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
270 c
= FOLD ((UCHAR
) *p
);
275 else if (c
== L('[') && *p
== L(':'))
277 /* Leave room for the null. */
278 CHAR str
[CHAR_CLASS_MAX_LENGTH
+ 1];
280 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
283 const CHAR
*startp
= p
;
287 if (c1
== CHAR_CLASS_MAX_LENGTH
)
288 /* The name is too long and therefore the pattern
293 if (c
== L(':') && p
[1] == L(']'))
298 if (c
< L('a') || c
>= L('z'))
300 /* This cannot possibly be a character class name.
301 Match it as a normal range. */
310 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
311 wt
= IS_CHAR_CLASS (str
);
313 /* Invalid character class name. */
316 # if defined _LIBC && ! WIDE_CHAR_VERSION
317 /* The following code is glibc specific but does
318 there a good job in speeding up the code since
319 we can avoid the btowc() call. */
320 if (_ISCTYPE ((UCHAR
) *n
, wt
))
323 if (ISWCTYPE (BTOWC ((UCHAR
) *n
), wt
))
327 if ((STREQ (str
, L("alnum")) && ISALNUM ((UCHAR
) *n
))
328 || (STREQ (str
, L("alpha")) && ISALPHA ((UCHAR
) *n
))
329 || (STREQ (str
, L("blank")) && ISBLANK ((UCHAR
) *n
))
330 || (STREQ (str
, L("cntrl")) && ISCNTRL ((UCHAR
) *n
))
331 || (STREQ (str
, L("digit")) && ISDIGIT ((UCHAR
) *n
))
332 || (STREQ (str
, L("graph")) && ISGRAPH ((UCHAR
) *n
))
333 || (STREQ (str
, L("lower")) && ISLOWER ((UCHAR
) *n
))
334 || (STREQ (str
, L("print")) && ISPRINT ((UCHAR
) *n
))
335 || (STREQ (str
, L("punct")) && ISPUNCT ((UCHAR
) *n
))
336 || (STREQ (str
, L("space")) && ISSPACE ((UCHAR
) *n
))
337 || (STREQ (str
, L("upper")) && ISUPPER ((UCHAR
) *n
))
338 || (STREQ (str
, L("xdigit")) && ISXDIGIT ((UCHAR
) *n
)))
344 else if (c
== L('[') && *p
== L('='))
348 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
349 const CHAR
*startp
= p
;
361 if (c
!= L('=') || p
[1] != L(']'))
371 if ((UCHAR
) *n
== str
[0])
376 const int32_t *table
;
377 # if WIDE_CHAR_VERSION
378 const int32_t *weights
;
381 const unsigned char *weights
;
382 const unsigned char *extra
;
384 const int32_t *indirect
;
386 const UCHAR
*cp
= (const UCHAR
*) str
;
388 # if WIDE_CHAR_VERSION
389 table
= (const int32_t *)
390 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEWC
);
391 weights
= (const int32_t *)
392 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTWC
);
393 extra
= (const wint_t *)
394 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAWC
);
395 indirect
= (const int32_t *)
396 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTWC
);
398 table
= (const int32_t *)
399 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEMB
);
400 weights
= (const unsigned char *)
401 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTMB
);
402 extra
= (const unsigned char *)
403 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAMB
);
404 indirect
= (const int32_t *)
405 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTMB
);
408 idx
= FINDIDX (table
, indirect
, extra
, &cp
, 1);
411 /* We found a table entry. Now see whether the
412 character we are currently at has the same
413 equivalance class value. */
414 int len
= weights
[idx
& 0xffffff];
416 const UCHAR
*np
= (const UCHAR
*) n
;
418 idx2
= FINDIDX (table
, indirect
, extra
,
419 &np
, string_end
- n
);
421 && (idx
>> 24) == (idx2
>> 24)
422 && len
== weights
[idx2
& 0xffffff])
430 && (weights
[idx
+ 1 + cnt
]
431 == weights
[idx2
+ 1 + cnt
]))
443 else if (c
== L('\0'))
445 /* [ unterminated, treat as normal character. */
458 if (c
== L('[') && *p
== L('.'))
461 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
462 const CHAR
*startp
= p
;
468 if (c
== L('.') && p
[1] == L(']'))
478 /* We have to handling the symbols differently in
479 ranges since then the collation sequence is
481 is_range
= *p
== L('-') && p
[1] != L('\0');
485 /* There are no names defined in the collation
486 data. Therefore we only accept the trivial
487 names consisting of the character itself. */
491 if (!is_range
&& *n
== startp
[1])
500 const int32_t *symb_table
;
501 # if WIDE_CHAR_VERSION
505 # define str (startp + 1)
507 const unsigned char *extra
;
513 # if WIDE_CHAR_VERSION
514 /* We have to convert the name to a single-byte
515 string. This is possible since the names
516 consist of ASCII characters and the internal
517 representation is UCS4. */
518 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
519 str
[strcnt
] = startp
[1 + strcnt
];
523 _NL_CURRENT_WORD (LC_COLLATE
,
524 _NL_COLLATE_SYMB_HASH_SIZEMB
);
525 symb_table
= (const int32_t *)
526 _NL_CURRENT (LC_COLLATE
,
527 _NL_COLLATE_SYMB_TABLEMB
);
528 extra
= (const unsigned char *)
529 _NL_CURRENT (LC_COLLATE
,
530 _NL_COLLATE_SYMB_EXTRAMB
);
532 /* Locate the character in the hashing table. */
533 hash
= elem_hash (str
, c1
);
536 elem
= hash
% table_size
;
537 if (symb_table
[2 * elem
] != 0)
539 second
= hash
% (table_size
- 2) + 1;
543 /* First compare the hashing value. */
544 if (symb_table
[2 * elem
] == hash
546 == extra
[symb_table
[2 * elem
+ 1]])
548 &extra
[symb_table
[2 * elem
552 /* Yep, this is the entry. */
553 idx
= symb_table
[2 * elem
+ 1];
554 idx
+= 1 + extra
[idx
];
561 while (symb_table
[2 * elem
] != 0);
564 if (symb_table
[2 * elem
] != 0)
566 /* Compare the byte sequence but only if
567 this is not part of a range. */
568 # if WIDE_CHAR_VERSION
571 idx
+= 1 + extra
[idx
];
572 /* Adjust for the alignment. */
573 idx
= (idx
+ 3) & ~3;
575 wextra
= (int32_t *) &extra
[idx
+ 4];
580 # if WIDE_CHAR_VERSION
582 (int32_t) c1
< wextra
[idx
];
584 if (n
[c1
] != wextra
[1 + c1
])
587 if ((int32_t) c1
== wextra
[idx
])
590 for (c1
= 0; c1
< extra
[idx
]; ++c1
)
591 if (n
[c1
] != extra
[1 + c1
])
594 if (c1
== extra
[idx
])
599 /* Get the collation sequence value. */
601 # if WIDE_CHAR_VERSION
602 cold
= wextra
[1 + wextra
[idx
]];
604 /* Adjust for the alignment. */
605 idx
+= 1 + extra
[idx
];
606 idx
= (idx
+ 3) & ~4;
607 cold
= *((int32_t *) &extra
[idx
]);
614 /* No valid character. Match it as a
616 if (!is_range
&& *n
== str
[0])
633 /* We have to handling the symbols differently in
634 ranges since then the collation sequence is
636 is_range
= (*p
== L('-') && p
[1] != L('\0')
639 if (!is_range
&& c
== fn
)
642 /* This is needed if we goto normal_bracket; from
643 outside of is_seqval's scope. */
649 if (c
== L('-') && *p
!= L(']'))
652 /* We have to find the collation sequence
653 value for C. Collation sequence is nothing
654 we can regularly access. The sequence
655 value is defined by the order in which the
656 definitions of the collation values for the
657 various characters appear in the source
658 file. A strange concept, nowhere
664 # if WIDE_CHAR_VERSION
665 /* Search in the `names' array for the characters. */
666 fcollseq
= __collseq_table_lookup (collseq
, fn
);
667 if (fcollseq
== ~((uint32_t) 0))
668 /* XXX We don't know anything about the character
669 we are supposed to match. This means we are
671 goto range_not_matched
;
676 lcollseq
= __collseq_table_lookup (collseq
, cold
);
678 fcollseq
= collseq
[fn
];
679 lcollseq
= is_seqval
? cold
: collseq
[(UCHAR
) cold
];
683 if (cend
== L('[') && *p
== L('.'))
686 _NL_CURRENT_WORD (LC_COLLATE
,
688 const CHAR
*startp
= p
;
694 if (c
== L('.') && p
[1] == L(']'))
706 /* There are no names defined in the
707 collation data. Therefore we only
708 accept the trivial names consisting
709 of the character itself. */
718 const int32_t *symb_table
;
719 # if WIDE_CHAR_VERSION
723 # define str (startp + 1)
725 const unsigned char *extra
;
731 # if WIDE_CHAR_VERSION
732 /* We have to convert the name to a single-byte
733 string. This is possible since the names
734 consist of ASCII characters and the internal
735 representation is UCS4. */
736 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
737 str
[strcnt
] = startp
[1 + strcnt
];
741 _NL_CURRENT_WORD (LC_COLLATE
,
742 _NL_COLLATE_SYMB_HASH_SIZEMB
);
743 symb_table
= (const int32_t *)
744 _NL_CURRENT (LC_COLLATE
,
745 _NL_COLLATE_SYMB_TABLEMB
);
746 extra
= (const unsigned char *)
747 _NL_CURRENT (LC_COLLATE
,
748 _NL_COLLATE_SYMB_EXTRAMB
);
750 /* Locate the character in the hashing
752 hash
= elem_hash (str
, c1
);
755 elem
= hash
% table_size
;
756 if (symb_table
[2 * elem
] != 0)
758 second
= hash
% (table_size
- 2) + 1;
762 /* First compare the hashing value. */
763 if (symb_table
[2 * elem
] == hash
765 == extra
[symb_table
[2 * elem
+ 1]])
767 &extra
[symb_table
[2 * elem
+ 1]
770 /* Yep, this is the entry. */
771 idx
= symb_table
[2 * elem
+ 1];
772 idx
+= 1 + extra
[idx
];
779 while (symb_table
[2 * elem
] != 0);
782 if (symb_table
[2 * elem
] != 0)
784 /* Compare the byte sequence but only if
785 this is not part of a range. */
786 # if WIDE_CHAR_VERSION
789 idx
+= 1 + extra
[idx
];
790 /* Adjust for the alignment. */
791 idx
= (idx
+ 3) & ~4;
793 wextra
= (int32_t *) &extra
[idx
+ 4];
795 /* Get the collation sequence value. */
797 # if WIDE_CHAR_VERSION
798 cend
= wextra
[1 + wextra
[idx
]];
800 /* Adjust for the alignment. */
801 idx
+= 1 + extra
[idx
];
802 idx
= (idx
+ 3) & ~4;
803 cend
= *((int32_t *) &extra
[idx
]);
806 else if (symb_table
[2 * elem
] != 0 && c1
== 1)
818 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
825 /* XXX It is not entirely clear to me how to handle
826 characters which are not mentioned in the
827 collation specification. */
829 # if WIDE_CHAR_VERSION
830 lcollseq
== 0xffffffff ||
832 lcollseq
<= fcollseq
)
834 /* We have to look at the upper bound. */
841 # if WIDE_CHAR_VERSION
843 __collseq_table_lookup (collseq
, cend
);
844 if (hcollseq
== ~((uint32_t) 0))
846 /* Hum, no information about the upper
847 bound. The matching succeeds if the
848 lower bound is matched exactly. */
849 if (lcollseq
!= fcollseq
)
850 goto range_not_matched
;
855 hcollseq
= collseq
[cend
];
859 if (lcollseq
<= hcollseq
&& fcollseq
<= hcollseq
)
862 # if WIDE_CHAR_VERSION
866 /* We use a boring value comparison of the character
867 values. This is better than comparing using
868 `strcoll' since the latter would have surprising
869 and sometimes fatal consequences. */
872 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
878 if (cold
<= fn
&& fn
<= cend
)
895 /* Skip the rest of the [...] that already matched. */
896 while ((c
= *p
++) != L (']'))
899 /* [... (unterminated) loses. */
902 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
906 /* XXX 1003.2d11 is unclear if this is right. */
909 else if (c
== L('[') && *p
== L(':'))
912 const CHAR
*startp
= p
;
917 if (++c1
== CHAR_CLASS_MAX_LENGTH
)
920 if (*p
== L(':') && p
[1] == L(']'))
923 if (c
< L('a') || c
>= L('z'))
931 else if (c
== L('[') && *p
== L('='))
937 if (c
!= L('=') || p
[1] != L(']'))
941 else if (c
== L('[') && *p
== L('.'))
950 if (*p
== L('.') && p
[1] == L(']'))
964 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
966 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
, flags
,
974 if (NO_LEADING_PERIOD (flags
))
976 if (n
== string_end
|| c
!= (UCHAR
) *n
)
979 new_no_leading_period
= 1;
985 if (n
== string_end
|| c
!= FOLD ((UCHAR
) *n
))
989 no_leading_period
= new_no_leading_period
;
996 if ((flags
& FNM_LEADING_DIR
) && n
!= string_end
&& *n
== L('/'))
997 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
1006 END (const CHAR
*pattern
)
1008 const CHAR
*p
= pattern
;
1011 if (*++p
== L('\0'))
1012 /* This is an invalid pattern. */
1014 else if (*p
== L('['))
1016 /* Handle brackets special. */
1017 if (posixly_correct
== 0)
1018 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1020 /* Skip the not sign. We have to recognize it because of a possibly
1022 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1024 /* A leading ']' is recognized as such. */
1027 /* Skip over all characters of the list. */
1028 while (*p
!= L(']'))
1029 if (*p
++ == L('\0'))
1030 /* This is no valid pattern. */
1033 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1034 || *p
== L('!')) && p
[1] == L('('))
1036 else if (*p
== L(')'))
1045 EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
1046 int no_leading_period
, int flags
, size_t alloca_used
)
1052 struct patternlist
*next
;
1056 struct patternlist
**lastp
= &list
;
1057 size_t pattern_len
= STRLEN (pattern
);
1058 int any_malloced
= 0;
1063 /* Parse the pattern. Store the individual parts in the list. */
1065 for (startp
= p
= pattern
+ 1; level
>= 0; ++p
)
1068 /* This is an invalid pattern. */
1072 else if (*p
== L('['))
1074 /* Handle brackets special. */
1075 if (posixly_correct
== 0)
1076 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1078 /* Skip the not sign. We have to recognize it because of a possibly
1080 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1082 /* A leading ']' is recognized as such. */
1085 /* Skip over all characters of the list. */
1086 while (*p
!= L(']'))
1087 if (*p
++ == L('\0'))
1089 /* This is no valid pattern. */
1094 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1095 || *p
== L('!')) && p
[1] == L('('))
1096 /* Remember the nesting level. */
1098 else if (*p
== L(')'))
1102 /* This means we found the end of the pattern. */
1103 #define NEW_PATTERN \
1104 struct patternlist *newp; \
1105 size_t slen = (opt == L('?') || opt == L('@') \
1106 ? pattern_len : (p - startp + 1)); \
1107 slen = sizeof (struct patternlist) + (slen * sizeof (CHAR)); \
1108 int malloced = ! __libc_use_alloca (alloca_used + slen); \
1109 if (__builtin_expect (malloced, 0)) \
1111 newp = malloc (slen); \
1120 newp = alloca_account (slen, alloca_used); \
1121 newp->next = NULL; \
1122 newp->malloced = malloced; \
1123 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1129 else if (*p
== L('|'))
1137 assert (list
!= NULL
);
1138 assert (p
[-1] == L(')'));
1144 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1152 for (rs
= string
; rs
<= string_end
; ++rs
)
1153 /* First match the prefix with the current pattern with the
1155 if (FCT (list
->str
, string
, rs
, no_leading_period
,
1156 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1157 NULL
, alloca_used
) == 0
1158 /* This was successful. Now match the rest with the rest
1160 && (FCT (p
, rs
, string_end
,
1163 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1164 flags
& FNM_FILE_NAME
1165 ? flags
: flags
& ~FNM_PERIOD
, NULL
, alloca_used
) == 0
1166 /* This didn't work. Try the whole pattern. */
1168 && FCT (pattern
- 1, rs
, string_end
,
1171 : (rs
[-1] == '/' && NO_LEADING_PERIOD (flags
)
1173 flags
& FNM_FILE_NAME
1174 ? flags
: flags
& ~FNM_PERIOD
, NULL
,
1175 alloca_used
) == 0)))
1176 /* It worked. Signal success. */
1179 while ((list
= list
->next
) != NULL
);
1181 /* None of the patterns lead to a match. */
1182 retval
= FNM_NOMATCH
;
1186 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1193 /* I cannot believe it but `strcat' is actually acceptable
1194 here. Match the entire string with the prefix from the
1195 pattern list and the rest of the pattern following the
1197 if (FCT (STRCAT (list
->str
, p
), string
, string_end
,
1199 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1200 NULL
, alloca_used
) == 0)
1201 /* It worked. Signal success. */
1203 while ((list
= list
->next
) != NULL
);
1205 /* None of the patterns lead to a match. */
1206 retval
= FNM_NOMATCH
;
1210 for (rs
= string
; rs
<= string_end
; ++rs
)
1212 struct patternlist
*runp
;
1214 for (runp
= list
; runp
!= NULL
; runp
= runp
->next
)
1215 if (FCT (runp
->str
, string
, rs
, no_leading_period
,
1216 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1217 NULL
, alloca_used
) == 0)
1220 /* If none of the patterns matched see whether the rest does. */
1222 && (FCT (p
, rs
, string_end
,
1225 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1226 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1227 NULL
, alloca_used
) == 0))
1228 /* This is successful. */
1232 /* None of the patterns together with the rest of the pattern
1234 retval
= FNM_NOMATCH
;
1238 assert (! "Invalid extended matching operator");
1246 while (list
!= NULL
)
1248 struct patternlist
*old
= list
;
1273 #undef WIDE_CHAR_VERSION