1 /* Copyright (C) 1991-2015 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('='))
346 /* It's important that STR be a scalar variable rather
347 than a one-element array, because GCC (at least 4.9.2
348 -O2 on x86-64) can be confused by the array and
349 diagnose a "used initialized" in a dead branch in the
353 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
354 const CHAR
*startp
= p
;
366 if (c
!= L('=') || p
[1] != L(']'))
376 if ((UCHAR
) *n
== str
)
381 const int32_t *table
;
382 # if WIDE_CHAR_VERSION
383 const int32_t *weights
;
386 const unsigned char *weights
;
387 const unsigned char *extra
;
389 const int32_t *indirect
;
391 const UCHAR
*cp
= (const UCHAR
*) &str
;
393 # if WIDE_CHAR_VERSION
394 table
= (const int32_t *)
395 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEWC
);
396 weights
= (const int32_t *)
397 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTWC
);
398 extra
= (const wint_t *)
399 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAWC
);
400 indirect
= (const int32_t *)
401 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTWC
);
403 table
= (const int32_t *)
404 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEMB
);
405 weights
= (const unsigned char *)
406 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTMB
);
407 extra
= (const unsigned char *)
408 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAMB
);
409 indirect
= (const int32_t *)
410 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTMB
);
413 idx
= FINDIDX (table
, indirect
, extra
, &cp
, 1);
416 /* We found a table entry. Now see whether the
417 character we are currently at has the same
418 equivalance class value. */
419 int len
= weights
[idx
& 0xffffff];
421 const UCHAR
*np
= (const UCHAR
*) n
;
423 idx2
= FINDIDX (table
, indirect
, extra
,
424 &np
, string_end
- n
);
426 && (idx
>> 24) == (idx2
>> 24)
427 && len
== weights
[idx2
& 0xffffff])
435 && (weights
[idx
+ 1 + cnt
]
436 == weights
[idx2
+ 1 + cnt
]))
448 else if (c
== L('\0'))
450 /* [ unterminated, treat as normal character. */
463 if (c
== L('[') && *p
== L('.'))
466 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
467 const CHAR
*startp
= p
;
473 if (c
== L('.') && p
[1] == L(']'))
483 /* We have to handling the symbols differently in
484 ranges since then the collation sequence is
486 is_range
= *p
== L('-') && p
[1] != L('\0');
490 /* There are no names defined in the collation
491 data. Therefore we only accept the trivial
492 names consisting of the character itself. */
496 if (!is_range
&& *n
== startp
[1])
505 const int32_t *symb_table
;
506 # if WIDE_CHAR_VERSION
510 # define str (startp + 1)
512 const unsigned char *extra
;
518 # if WIDE_CHAR_VERSION
519 /* We have to convert the name to a single-byte
520 string. This is possible since the names
521 consist of ASCII characters and the internal
522 representation is UCS4. */
523 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
524 str
[strcnt
] = startp
[1 + strcnt
];
528 _NL_CURRENT_WORD (LC_COLLATE
,
529 _NL_COLLATE_SYMB_HASH_SIZEMB
);
530 symb_table
= (const int32_t *)
531 _NL_CURRENT (LC_COLLATE
,
532 _NL_COLLATE_SYMB_TABLEMB
);
533 extra
= (const unsigned char *)
534 _NL_CURRENT (LC_COLLATE
,
535 _NL_COLLATE_SYMB_EXTRAMB
);
537 /* Locate the character in the hashing table. */
538 hash
= elem_hash (str
, c1
);
541 elem
= hash
% table_size
;
542 if (symb_table
[2 * elem
] != 0)
544 second
= hash
% (table_size
- 2) + 1;
548 /* First compare the hashing value. */
549 if (symb_table
[2 * elem
] == hash
551 == extra
[symb_table
[2 * elem
+ 1]])
553 &extra
[symb_table
[2 * elem
557 /* Yep, this is the entry. */
558 idx
= symb_table
[2 * elem
+ 1];
559 idx
+= 1 + extra
[idx
];
566 while (symb_table
[2 * elem
] != 0);
569 if (symb_table
[2 * elem
] != 0)
571 /* Compare the byte sequence but only if
572 this is not part of a range. */
573 # if WIDE_CHAR_VERSION
576 idx
+= 1 + extra
[idx
];
577 /* Adjust for the alignment. */
578 idx
= (idx
+ 3) & ~3;
580 wextra
= (int32_t *) &extra
[idx
+ 4];
585 # if WIDE_CHAR_VERSION
587 (int32_t) c1
< wextra
[idx
];
589 if (n
[c1
] != wextra
[1 + c1
])
592 if ((int32_t) c1
== wextra
[idx
])
595 for (c1
= 0; c1
< extra
[idx
]; ++c1
)
596 if (n
[c1
] != extra
[1 + c1
])
599 if (c1
== extra
[idx
])
604 /* Get the collation sequence value. */
606 # if WIDE_CHAR_VERSION
607 cold
= wextra
[1 + wextra
[idx
]];
609 /* Adjust for the alignment. */
610 idx
+= 1 + extra
[idx
];
611 idx
= (idx
+ 3) & ~4;
612 cold
= *((int32_t *) &extra
[idx
]);
619 /* No valid character. Match it as a
621 if (!is_range
&& *n
== str
[0])
638 /* We have to handling the symbols differently in
639 ranges since then the collation sequence is
641 is_range
= (*p
== L('-') && p
[1] != L('\0')
644 if (!is_range
&& c
== fn
)
647 /* This is needed if we goto normal_bracket; from
648 outside of is_seqval's scope. */
654 if (c
== L('-') && *p
!= L(']'))
657 /* We have to find the collation sequence
658 value for C. Collation sequence is nothing
659 we can regularly access. The sequence
660 value is defined by the order in which the
661 definitions of the collation values for the
662 various characters appear in the source
663 file. A strange concept, nowhere
669 # if WIDE_CHAR_VERSION
670 /* Search in the `names' array for the characters. */
671 fcollseq
= __collseq_table_lookup (collseq
, fn
);
672 if (fcollseq
== ~((uint32_t) 0))
673 /* XXX We don't know anything about the character
674 we are supposed to match. This means we are
676 goto range_not_matched
;
681 lcollseq
= __collseq_table_lookup (collseq
, cold
);
683 fcollseq
= collseq
[fn
];
684 lcollseq
= is_seqval
? cold
: collseq
[(UCHAR
) cold
];
688 if (cend
== L('[') && *p
== L('.'))
691 _NL_CURRENT_WORD (LC_COLLATE
,
693 const CHAR
*startp
= p
;
699 if (c
== L('.') && p
[1] == L(']'))
711 /* There are no names defined in the
712 collation data. Therefore we only
713 accept the trivial names consisting
714 of the character itself. */
723 const int32_t *symb_table
;
724 # if WIDE_CHAR_VERSION
728 # define str (startp + 1)
730 const unsigned char *extra
;
736 # if WIDE_CHAR_VERSION
737 /* We have to convert the name to a single-byte
738 string. This is possible since the names
739 consist of ASCII characters and the internal
740 representation is UCS4. */
741 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
742 str
[strcnt
] = startp
[1 + strcnt
];
746 _NL_CURRENT_WORD (LC_COLLATE
,
747 _NL_COLLATE_SYMB_HASH_SIZEMB
);
748 symb_table
= (const int32_t *)
749 _NL_CURRENT (LC_COLLATE
,
750 _NL_COLLATE_SYMB_TABLEMB
);
751 extra
= (const unsigned char *)
752 _NL_CURRENT (LC_COLLATE
,
753 _NL_COLLATE_SYMB_EXTRAMB
);
755 /* Locate the character in the hashing
757 hash
= elem_hash (str
, c1
);
760 elem
= hash
% table_size
;
761 if (symb_table
[2 * elem
] != 0)
763 second
= hash
% (table_size
- 2) + 1;
767 /* First compare the hashing value. */
768 if (symb_table
[2 * elem
] == hash
770 == extra
[symb_table
[2 * elem
+ 1]])
772 &extra
[symb_table
[2 * elem
+ 1]
775 /* Yep, this is the entry. */
776 idx
= symb_table
[2 * elem
+ 1];
777 idx
+= 1 + extra
[idx
];
784 while (symb_table
[2 * elem
] != 0);
787 if (symb_table
[2 * elem
] != 0)
789 /* Compare the byte sequence but only if
790 this is not part of a range. */
791 # if WIDE_CHAR_VERSION
794 idx
+= 1 + extra
[idx
];
795 /* Adjust for the alignment. */
796 idx
= (idx
+ 3) & ~4;
798 wextra
= (int32_t *) &extra
[idx
+ 4];
800 /* Get the collation sequence value. */
802 # if WIDE_CHAR_VERSION
803 cend
= wextra
[1 + wextra
[idx
]];
805 /* Adjust for the alignment. */
806 idx
+= 1 + extra
[idx
];
807 idx
= (idx
+ 3) & ~4;
808 cend
= *((int32_t *) &extra
[idx
]);
811 else if (symb_table
[2 * elem
] != 0 && c1
== 1)
823 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
830 /* XXX It is not entirely clear to me how to handle
831 characters which are not mentioned in the
832 collation specification. */
834 # if WIDE_CHAR_VERSION
835 lcollseq
== 0xffffffff ||
837 lcollseq
<= fcollseq
)
839 /* We have to look at the upper bound. */
846 # if WIDE_CHAR_VERSION
848 __collseq_table_lookup (collseq
, cend
);
849 if (hcollseq
== ~((uint32_t) 0))
851 /* Hum, no information about the upper
852 bound. The matching succeeds if the
853 lower bound is matched exactly. */
854 if (lcollseq
!= fcollseq
)
855 goto range_not_matched
;
860 hcollseq
= collseq
[cend
];
864 if (lcollseq
<= hcollseq
&& fcollseq
<= hcollseq
)
867 # if WIDE_CHAR_VERSION
871 /* We use a boring value comparison of the character
872 values. This is better than comparing using
873 `strcoll' since the latter would have surprising
874 and sometimes fatal consequences. */
877 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
883 if (cold
<= fn
&& fn
<= cend
)
900 /* Skip the rest of the [...] that already matched. */
901 while ((c
= *p
++) != L (']'))
904 /* [... (unterminated) loses. */
907 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
911 /* XXX 1003.2d11 is unclear if this is right. */
914 else if (c
== L('[') && *p
== L(':'))
917 const CHAR
*startp
= p
;
922 if (++c1
== CHAR_CLASS_MAX_LENGTH
)
925 if (*p
== L(':') && p
[1] == L(']'))
928 if (c
< L('a') || c
>= L('z'))
936 else if (c
== L('[') && *p
== L('='))
942 if (c
!= L('=') || p
[1] != L(']'))
946 else if (c
== L('[') && *p
== L('.'))
954 if (c
== L('.') && p
[1] == L(']'))
968 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
970 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
, flags
,
978 if (NO_LEADING_PERIOD (flags
))
980 if (n
== string_end
|| c
!= (UCHAR
) *n
)
983 new_no_leading_period
= 1;
989 if (n
== string_end
|| c
!= FOLD ((UCHAR
) *n
))
993 no_leading_period
= new_no_leading_period
;
1000 if ((flags
& FNM_LEADING_DIR
) && n
!= string_end
&& *n
== L('/'))
1001 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
1010 END (const CHAR
*pattern
)
1012 const CHAR
*p
= pattern
;
1015 if (*++p
== L('\0'))
1016 /* This is an invalid pattern. */
1018 else if (*p
== L('['))
1020 /* Handle brackets special. */
1021 if (posixly_correct
== 0)
1022 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1024 /* Skip the not sign. We have to recognize it because of a possibly
1026 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1028 /* A leading ']' is recognized as such. */
1031 /* Skip over all characters of the list. */
1032 while (*p
!= L(']'))
1033 if (*p
++ == L('\0'))
1034 /* This is no valid pattern. */
1037 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1038 || *p
== L('!')) && p
[1] == L('('))
1042 /* This is an invalid pattern. */
1045 else if (*p
== L(')'))
1054 EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
1055 int no_leading_period
, int flags
, size_t alloca_used
)
1061 struct patternlist
*next
;
1065 struct patternlist
**lastp
= &list
;
1066 size_t pattern_len
= STRLEN (pattern
);
1067 int any_malloced
= 0;
1072 /* Parse the pattern. Store the individual parts in the list. */
1074 for (startp
= p
= pattern
+ 1; level
>= 0; ++p
)
1077 /* This is an invalid pattern. */
1081 else if (*p
== L('['))
1083 /* Handle brackets special. */
1084 if (posixly_correct
== 0)
1085 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1087 /* Skip the not sign. We have to recognize it because of a possibly
1089 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1091 /* A leading ']' is recognized as such. */
1094 /* Skip over all characters of the list. */
1095 while (*p
!= L(']'))
1096 if (*p
++ == L('\0'))
1098 /* This is no valid pattern. */
1103 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1104 || *p
== L('!')) && p
[1] == L('('))
1105 /* Remember the nesting level. */
1107 else if (*p
== L(')'))
1111 /* This means we found the end of the pattern. */
1112 #define NEW_PATTERN \
1113 struct patternlist *newp; \
1114 size_t slen = (opt == L('?') || opt == L('@') \
1115 ? pattern_len : (p - startp + 1)); \
1116 slen = sizeof (struct patternlist) + (slen * sizeof (CHAR)); \
1117 int malloced = ! __libc_use_alloca (alloca_used + slen); \
1118 if (__builtin_expect (malloced, 0)) \
1120 newp = malloc (slen); \
1129 newp = alloca_account (slen, alloca_used); \
1130 newp->next = NULL; \
1131 newp->malloced = malloced; \
1132 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1138 else if (*p
== L('|'))
1146 assert (list
!= NULL
);
1147 assert (p
[-1] == L(')'));
1153 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1161 for (rs
= string
; rs
<= string_end
; ++rs
)
1162 /* First match the prefix with the current pattern with the
1164 if (FCT (list
->str
, string
, rs
, no_leading_period
,
1165 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1166 NULL
, alloca_used
) == 0
1167 /* This was successful. Now match the rest with the rest
1169 && (FCT (p
, rs
, string_end
,
1172 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1173 flags
& FNM_FILE_NAME
1174 ? flags
: flags
& ~FNM_PERIOD
, NULL
, alloca_used
) == 0
1175 /* This didn't work. Try the whole pattern. */
1177 && FCT (pattern
- 1, rs
, string_end
,
1180 : (rs
[-1] == '/' && NO_LEADING_PERIOD (flags
)
1182 flags
& FNM_FILE_NAME
1183 ? flags
: flags
& ~FNM_PERIOD
, NULL
,
1184 alloca_used
) == 0)))
1185 /* It worked. Signal success. */
1188 while ((list
= list
->next
) != NULL
);
1190 /* None of the patterns lead to a match. */
1191 retval
= FNM_NOMATCH
;
1195 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1202 /* I cannot believe it but `strcat' is actually acceptable
1203 here. Match the entire string with the prefix from the
1204 pattern list and the rest of the pattern following the
1206 if (FCT (STRCAT (list
->str
, p
), string
, string_end
,
1208 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1209 NULL
, alloca_used
) == 0)
1210 /* It worked. Signal success. */
1212 while ((list
= list
->next
) != NULL
);
1214 /* None of the patterns lead to a match. */
1215 retval
= FNM_NOMATCH
;
1219 for (rs
= string
; rs
<= string_end
; ++rs
)
1221 struct patternlist
*runp
;
1223 for (runp
= list
; runp
!= NULL
; runp
= runp
->next
)
1224 if (FCT (runp
->str
, string
, rs
, no_leading_period
,
1225 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1226 NULL
, alloca_used
) == 0)
1229 /* If none of the patterns matched see whether the rest does. */
1231 && (FCT (p
, rs
, string_end
,
1234 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1235 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1236 NULL
, alloca_used
) == 0))
1237 /* This is successful. */
1241 /* None of the patterns together with the rest of the pattern
1243 retval
= FNM_NOMATCH
;
1247 assert (! "Invalid extended matching operator");
1255 while (list
!= NULL
)
1257 struct patternlist
*old
= list
;
1282 #undef WIDE_CHAR_VERSION