1 /* Copyright (C) 1991-2018 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
);
32 static int EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
,
33 const CHAR
*string_end
, int no_leading_period
, int flags
,
35 static const CHAR
*END (const CHAR
*patternp
);
38 FCT (const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
39 int no_leading_period
, int flags
, struct STRUCT
*ends
, size_t alloca_used
)
41 const CHAR
*p
= pattern
, *n
= string
;
44 # if WIDE_CHAR_VERSION
45 const char *collseq
= (const char *)
46 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQWC
);
48 const UCHAR
*collseq
= (const UCHAR
*)
49 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQMB
);
53 while ((c
= *p
++) != L('\0'))
55 int new_no_leading_period
= 0;
61 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
63 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
71 else if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
73 else if (*n
== L('.') && no_leading_period
)
78 if (!(flags
& FNM_NOESCAPE
))
82 /* Trailing \ loses. */
86 if (n
== string_end
|| FOLD ((UCHAR
) *n
) != c
)
91 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
93 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
98 else if (ends
!= NULL
)
100 ends
->pattern
= p
- 1;
102 ends
->no_leading_period
= no_leading_period
;
106 if (n
!= string_end
&& *n
== L('.') && no_leading_period
)
109 for (c
= *p
++; c
== L('?') || c
== L('*'); c
= *p
++)
111 if (*p
== L('(') && (flags
& FNM_EXTMATCH
) != 0)
113 const CHAR
*endp
= END (p
);
116 /* This is a pattern. Skip over it. */
124 /* A ? needs to match one character. */
126 /* There isn't another character; no match. */
128 else if (*n
== L('/')
129 && __builtin_expect (flags
& FNM_FILE_NAME
, 0))
130 /* A slash does not match a wildcard under
134 /* One character of the string is consumed in matching
135 this ? wildcard, so *??? won't match if there are
136 less than three characters. */
142 /* The wildcard(s) is/are the last element of the pattern.
143 If the name is a file name and contains another slash
144 this means it cannot match, unless the FNM_LEADING_DIR
147 int result
= (flags
& FNM_FILE_NAME
) == 0 ? 0 : FNM_NOMATCH
;
149 if (flags
& FNM_FILE_NAME
)
151 if (flags
& FNM_LEADING_DIR
)
155 if (MEMCHR (n
, L('/'), string_end
- n
) == NULL
)
168 endp
= MEMCHR (n
, (flags
& FNM_FILE_NAME
) ? L('/') : L('\0'),
174 || (__builtin_expect (flags
& FNM_EXTMATCH
, 0) != 0
175 && (c
== L('@') || c
== L('+') || c
== L('!'))
178 int flags2
= ((flags
& FNM_FILE_NAME
)
179 ? flags
: (flags
& ~FNM_PERIOD
));
181 for (--p
; n
< endp
; ++n
, no_leading_period
= 0)
182 if (FCT (p
, n
, string_end
, no_leading_period
, flags2
,
183 &end
, alloca_used
) == 0)
186 else if (c
== L('/') && (flags
& FNM_FILE_NAME
))
188 while (n
< string_end
&& *n
!= L('/'))
190 if (n
< string_end
&& *n
== L('/')
191 && (FCT (p
, n
+ 1, string_end
, flags
& FNM_PERIOD
, flags
,
192 NULL
, alloca_used
) == 0))
197 int flags2
= ((flags
& FNM_FILE_NAME
)
198 ? flags
: (flags
& ~FNM_PERIOD
));
200 if (c
== L('\\') && !(flags
& FNM_NOESCAPE
))
203 for (--p
; n
< endp
; ++n
, no_leading_period
= 0)
204 if (FOLD ((UCHAR
) *n
) == c
205 && (FCT (p
, n
, string_end
, no_leading_period
, flags2
,
206 &end
, alloca_used
) == 0))
209 if (end
.pattern
== NULL
)
213 if (end
.pattern
!= NULL
)
217 no_leading_period
= end
.no_leading_period
;
223 /* If we come here no match is possible with the wildcard. */
228 /* Nonzero if the sense of the character class is inverted. */
229 const CHAR
*p_init
= p
;
230 const CHAR
*n_init
= n
;
235 if (posixly_correct
== 0)
236 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
241 if (*n
== L('.') && no_leading_period
)
244 if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
245 /* `/' cannot be matched. */
248 not = (*p
== L('!') || (posixly_correct
< 0 && *p
== L('^')));
252 fn
= FOLD ((UCHAR
) *n
);
257 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
261 c
= FOLD ((UCHAR
) *p
);
266 else if (c
== L('[') && *p
== L(':'))
268 /* Leave room for the null. */
269 CHAR str
[CHAR_CLASS_MAX_LENGTH
+ 1];
271 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
274 const CHAR
*startp
= p
;
278 if (c1
== CHAR_CLASS_MAX_LENGTH
)
279 /* The name is too long and therefore the pattern
284 if (c
== L(':') && p
[1] == L(']'))
289 if (c
< L('a') || c
>= L('z'))
291 /* This cannot possibly be a character class name.
292 Match it as a normal range. */
301 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
302 wt
= IS_CHAR_CLASS (str
);
304 /* Invalid character class name. */
307 # if defined _LIBC && ! WIDE_CHAR_VERSION
308 /* The following code is glibc specific but does
309 there a good job in speeding up the code since
310 we can avoid the btowc() call. */
311 if (_ISCTYPE ((UCHAR
) *n
, wt
))
314 if (ISWCTYPE (BTOWC ((UCHAR
) *n
), wt
))
318 if ((STREQ (str
, L("alnum")) && ISALNUM ((UCHAR
) *n
))
319 || (STREQ (str
, L("alpha")) && ISALPHA ((UCHAR
) *n
))
320 || (STREQ (str
, L("blank")) && ISBLANK ((UCHAR
) *n
))
321 || (STREQ (str
, L("cntrl")) && ISCNTRL ((UCHAR
) *n
))
322 || (STREQ (str
, L("digit")) && ISDIGIT ((UCHAR
) *n
))
323 || (STREQ (str
, L("graph")) && ISGRAPH ((UCHAR
) *n
))
324 || (STREQ (str
, L("lower")) && ISLOWER ((UCHAR
) *n
))
325 || (STREQ (str
, L("print")) && ISPRINT ((UCHAR
) *n
))
326 || (STREQ (str
, L("punct")) && ISPUNCT ((UCHAR
) *n
))
327 || (STREQ (str
, L("space")) && ISSPACE ((UCHAR
) *n
))
328 || (STREQ (str
, L("upper")) && ISUPPER ((UCHAR
) *n
))
329 || (STREQ (str
, L("xdigit")) && ISXDIGIT ((UCHAR
) *n
)))
335 else if (c
== L('[') && *p
== L('='))
337 /* It's important that STR be a scalar variable rather
338 than a one-element array, because GCC (at least 4.9.2
339 -O2 on x86-64) can be confused by the array and
340 diagnose a "used initialized" in a dead branch in the
344 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
345 const CHAR
*startp
= p
;
357 if (c
!= L('=') || p
[1] != L(']'))
367 if ((UCHAR
) *n
== str
)
372 const int32_t *table
;
373 # if WIDE_CHAR_VERSION
374 const int32_t *weights
;
377 const unsigned char *weights
;
378 const unsigned char *extra
;
380 const int32_t *indirect
;
382 const UCHAR
*cp
= (const UCHAR
*) &str
;
384 # if WIDE_CHAR_VERSION
385 table
= (const int32_t *)
386 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEWC
);
387 weights
= (const int32_t *)
388 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTWC
);
389 extra
= (const wint_t *)
390 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAWC
);
391 indirect
= (const int32_t *)
392 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTWC
);
394 table
= (const int32_t *)
395 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEMB
);
396 weights
= (const unsigned char *)
397 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTMB
);
398 extra
= (const unsigned char *)
399 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAMB
);
400 indirect
= (const int32_t *)
401 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTMB
);
404 idx
= FINDIDX (table
, indirect
, extra
, &cp
, 1);
407 /* We found a table entry. Now see whether the
408 character we are currently at has the same
409 equivalance class value. */
410 int len
= weights
[idx
& 0xffffff];
412 const UCHAR
*np
= (const UCHAR
*) n
;
414 idx2
= FINDIDX (table
, indirect
, extra
,
415 &np
, string_end
- n
);
417 && (idx
>> 24) == (idx2
>> 24)
418 && len
== weights
[idx2
& 0xffffff])
426 && (weights
[idx
+ 1 + cnt
]
427 == weights
[idx2
+ 1 + cnt
]))
439 else if (c
== L('\0'))
441 /* [ unterminated, treat as normal character. */
454 if (c
== L('[') && *p
== L('.'))
457 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
458 const CHAR
*startp
= p
;
464 if (c
== L('.') && p
[1] == L(']'))
474 /* We have to handling the symbols differently in
475 ranges since then the collation sequence is
477 is_range
= *p
== L('-') && p
[1] != L('\0');
481 /* There are no names defined in the collation
482 data. Therefore we only accept the trivial
483 names consisting of the character itself. */
487 if (!is_range
&& *n
== startp
[1])
496 const int32_t *symb_table
;
497 # if WIDE_CHAR_VERSION
501 # define str (startp + 1)
503 const unsigned char *extra
;
509 # if WIDE_CHAR_VERSION
510 /* We have to convert the name to a single-byte
511 string. This is possible since the names
512 consist of ASCII characters and the internal
513 representation is UCS4. */
514 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
515 str
[strcnt
] = startp
[1 + strcnt
];
519 _NL_CURRENT_WORD (LC_COLLATE
,
520 _NL_COLLATE_SYMB_HASH_SIZEMB
);
521 symb_table
= (const int32_t *)
522 _NL_CURRENT (LC_COLLATE
,
523 _NL_COLLATE_SYMB_TABLEMB
);
524 extra
= (const unsigned char *)
525 _NL_CURRENT (LC_COLLATE
,
526 _NL_COLLATE_SYMB_EXTRAMB
);
528 /* Locate the character in the hashing table. */
529 hash
= elem_hash (str
, c1
);
532 elem
= hash
% table_size
;
533 if (symb_table
[2 * elem
] != 0)
535 second
= hash
% (table_size
- 2) + 1;
539 /* First compare the hashing value. */
540 if (symb_table
[2 * elem
] == hash
542 == extra
[symb_table
[2 * elem
+ 1]])
544 &extra
[symb_table
[2 * elem
548 /* Yep, this is the entry. */
549 idx
= symb_table
[2 * elem
+ 1];
550 idx
+= 1 + extra
[idx
];
557 while (symb_table
[2 * elem
] != 0);
560 if (symb_table
[2 * elem
] != 0)
562 /* Compare the byte sequence but only if
563 this is not part of a range. */
564 # if WIDE_CHAR_VERSION
567 idx
+= 1 + extra
[idx
];
568 /* Adjust for the alignment. */
569 idx
= (idx
+ 3) & ~3;
571 wextra
= (int32_t *) &extra
[idx
+ 4];
576 # if WIDE_CHAR_VERSION
578 (int32_t) c1
< wextra
[idx
];
580 if (n
[c1
] != wextra
[1 + c1
])
583 if ((int32_t) c1
== wextra
[idx
])
586 for (c1
= 0; c1
< extra
[idx
]; ++c1
)
587 if (n
[c1
] != extra
[1 + c1
])
590 if (c1
== extra
[idx
])
595 /* Get the collation sequence value. */
597 # if WIDE_CHAR_VERSION
598 cold
= wextra
[1 + wextra
[idx
]];
600 /* Adjust for the alignment. */
601 idx
+= 1 + extra
[idx
];
602 idx
= (idx
+ 3) & ~4;
603 cold
= *((int32_t *) &extra
[idx
]);
610 /* No valid character. Match it as a
612 if (!is_range
&& *n
== str
[0])
629 /* We have to handling the symbols differently in
630 ranges since then the collation sequence is
632 is_range
= (*p
== L('-') && p
[1] != L('\0')
635 if (!is_range
&& c
== fn
)
638 /* This is needed if we goto normal_bracket; from
639 outside of is_seqval's scope. */
645 if (c
== L('-') && *p
!= L(']'))
648 /* We have to find the collation sequence
649 value for C. Collation sequence is nothing
650 we can regularly access. The sequence
651 value is defined by the order in which the
652 definitions of the collation values for the
653 various characters appear in the source
654 file. A strange concept, nowhere
660 # if WIDE_CHAR_VERSION
661 /* Search in the `names' array for the characters. */
662 fcollseq
= __collseq_table_lookup (collseq
, fn
);
663 if (fcollseq
== ~((uint32_t) 0))
664 /* XXX We don't know anything about the character
665 we are supposed to match. This means we are
667 goto range_not_matched
;
672 lcollseq
= __collseq_table_lookup (collseq
, cold
);
674 fcollseq
= collseq
[fn
];
675 lcollseq
= is_seqval
? cold
: collseq
[(UCHAR
) cold
];
679 if (cend
== L('[') && *p
== L('.'))
682 _NL_CURRENT_WORD (LC_COLLATE
,
684 const CHAR
*startp
= p
;
690 if (c
== L('.') && p
[1] == L(']'))
702 /* There are no names defined in the
703 collation data. Therefore we only
704 accept the trivial names consisting
705 of the character itself. */
714 const int32_t *symb_table
;
715 # if WIDE_CHAR_VERSION
719 # define str (startp + 1)
721 const unsigned char *extra
;
727 # if WIDE_CHAR_VERSION
728 /* We have to convert the name to a single-byte
729 string. This is possible since the names
730 consist of ASCII characters and the internal
731 representation is UCS4. */
732 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
733 str
[strcnt
] = startp
[1 + strcnt
];
737 _NL_CURRENT_WORD (LC_COLLATE
,
738 _NL_COLLATE_SYMB_HASH_SIZEMB
);
739 symb_table
= (const int32_t *)
740 _NL_CURRENT (LC_COLLATE
,
741 _NL_COLLATE_SYMB_TABLEMB
);
742 extra
= (const unsigned char *)
743 _NL_CURRENT (LC_COLLATE
,
744 _NL_COLLATE_SYMB_EXTRAMB
);
746 /* Locate the character in the hashing
748 hash
= elem_hash (str
, c1
);
751 elem
= hash
% table_size
;
752 if (symb_table
[2 * elem
] != 0)
754 second
= hash
% (table_size
- 2) + 1;
758 /* First compare the hashing value. */
759 if (symb_table
[2 * elem
] == hash
761 == extra
[symb_table
[2 * elem
+ 1]])
763 &extra
[symb_table
[2 * elem
+ 1]
766 /* Yep, this is the entry. */
767 idx
= symb_table
[2 * elem
+ 1];
768 idx
+= 1 + extra
[idx
];
775 while (symb_table
[2 * elem
] != 0);
778 if (symb_table
[2 * elem
] != 0)
780 /* Compare the byte sequence but only if
781 this is not part of a range. */
782 # if WIDE_CHAR_VERSION
785 idx
+= 1 + extra
[idx
];
786 /* Adjust for the alignment. */
787 idx
= (idx
+ 3) & ~4;
789 wextra
= (int32_t *) &extra
[idx
+ 4];
791 /* Get the collation sequence value. */
793 # if WIDE_CHAR_VERSION
794 cend
= wextra
[1 + wextra
[idx
]];
796 /* Adjust for the alignment. */
797 idx
+= 1 + extra
[idx
];
798 idx
= (idx
+ 3) & ~4;
799 cend
= *((int32_t *) &extra
[idx
]);
802 else if (symb_table
[2 * elem
] != 0 && c1
== 1)
814 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
821 /* XXX It is not entirely clear to me how to handle
822 characters which are not mentioned in the
823 collation specification. */
825 # if WIDE_CHAR_VERSION
826 lcollseq
== 0xffffffff ||
828 lcollseq
<= fcollseq
)
830 /* We have to look at the upper bound. */
837 # if WIDE_CHAR_VERSION
839 __collseq_table_lookup (collseq
, cend
);
840 if (hcollseq
== ~((uint32_t) 0))
842 /* Hum, no information about the upper
843 bound. The matching succeeds if the
844 lower bound is matched exactly. */
845 if (lcollseq
!= fcollseq
)
846 goto range_not_matched
;
851 hcollseq
= collseq
[cend
];
855 if (lcollseq
<= hcollseq
&& fcollseq
<= hcollseq
)
858 # if WIDE_CHAR_VERSION
862 /* We use a boring value comparison of the character
863 values. This is better than comparing using
864 `strcoll' since the latter would have surprising
865 and sometimes fatal consequences. */
868 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
874 if (cold
<= fn
&& fn
<= cend
)
891 /* Skip the rest of the [...] that already matched. */
892 while ((c
= *p
++) != L (']'))
895 /* [... (unterminated) loses. */
898 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
902 /* XXX 1003.2d11 is unclear if this is right. */
905 else if (c
== L('[') && *p
== L(':'))
908 const CHAR
*startp
= p
;
913 if (++c1
== CHAR_CLASS_MAX_LENGTH
)
916 if (*p
== L(':') && p
[1] == L(']'))
919 if (c
< L('a') || c
>= L('z'))
927 else if (c
== L('[') && *p
== L('='))
933 if (c
!= L('=') || p
[1] != L(']'))
937 else if (c
== L('[') && *p
== L('.'))
945 if (c
== L('.') && p
[1] == L(']'))
959 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
961 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
, flags
,
969 if (NO_LEADING_PERIOD (flags
))
971 if (n
== string_end
|| c
!= (UCHAR
) *n
)
974 new_no_leading_period
= 1;
980 if (n
== string_end
|| c
!= FOLD ((UCHAR
) *n
))
984 no_leading_period
= new_no_leading_period
;
991 if ((flags
& FNM_LEADING_DIR
) && n
!= string_end
&& *n
== L('/'))
992 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
1000 END (const CHAR
*pattern
)
1002 const CHAR
*p
= pattern
;
1005 if (*++p
== L('\0'))
1006 /* This is an invalid pattern. */
1008 else if (*p
== L('['))
1010 /* Handle brackets special. */
1011 if (posixly_correct
== 0)
1012 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1014 /* Skip the not sign. We have to recognize it because of a possibly
1016 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1018 /* A leading ']' is recognized as such. */
1021 /* Skip over all characters of the list. */
1022 while (*p
!= L(']'))
1023 if (*p
++ == L('\0'))
1024 /* This is no valid pattern. */
1027 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1028 || *p
== L('!')) && p
[1] == L('('))
1032 /* This is an invalid pattern. */
1035 else if (*p
== L(')'))
1043 EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
1044 int no_leading_period
, int flags
, size_t alloca_used
)
1050 struct patternlist
*next
;
1054 struct patternlist
**lastp
= &list
;
1055 size_t pattern_len
= STRLEN (pattern
);
1056 int any_malloced
= 0;
1061 /* Parse the pattern. Store the individual parts in the list. */
1063 for (startp
= p
= pattern
+ 1; level
>= 0; ++p
)
1066 /* This is an invalid pattern. */
1070 else if (*p
== L('['))
1072 /* Handle brackets special. */
1073 if (posixly_correct
== 0)
1074 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1076 /* Skip the not sign. We have to recognize it because of a possibly
1078 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1080 /* A leading ']' is recognized as such. */
1083 /* Skip over all characters of the list. */
1084 while (*p
!= L(']'))
1085 if (*p
++ == L('\0'))
1087 /* This is no valid pattern. */
1092 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1093 || *p
== L('!')) && p
[1] == L('('))
1094 /* Remember the nesting level. */
1096 else if (*p
== L(')'))
1100 /* This means we found the end of the pattern. */
1101 #define NEW_PATTERN \
1102 struct patternlist *newp; \
1103 size_t slen = (opt == L('?') || opt == L('@') \
1104 ? pattern_len : (p - startp + 1)); \
1105 slen = sizeof (struct patternlist) + (slen * sizeof (CHAR)); \
1106 int malloced = ! __libc_use_alloca (alloca_used + slen); \
1107 if (__builtin_expect (malloced, 0)) \
1109 newp = malloc (slen); \
1118 newp = alloca_account (slen, alloca_used); \
1119 newp->next = NULL; \
1120 newp->malloced = malloced; \
1121 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1127 else if (*p
== L('|'))
1135 assert (list
!= NULL
);
1136 assert (p
[-1] == L(')'));
1142 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1150 for (rs
= string
; rs
<= string_end
; ++rs
)
1151 /* First match the prefix with the current pattern with the
1153 if (FCT (list
->str
, string
, rs
, no_leading_period
,
1154 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1155 NULL
, alloca_used
) == 0
1156 /* This was successful. Now match the rest with the rest
1158 && (FCT (p
, rs
, string_end
,
1161 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1162 flags
& FNM_FILE_NAME
1163 ? flags
: flags
& ~FNM_PERIOD
, NULL
, alloca_used
) == 0
1164 /* This didn't work. Try the whole pattern. */
1166 && FCT (pattern
- 1, rs
, string_end
,
1169 : (rs
[-1] == '/' && NO_LEADING_PERIOD (flags
)
1171 flags
& FNM_FILE_NAME
1172 ? flags
: flags
& ~FNM_PERIOD
, NULL
,
1173 alloca_used
) == 0)))
1174 /* It worked. Signal success. */
1177 while ((list
= list
->next
) != NULL
);
1179 /* None of the patterns lead to a match. */
1180 retval
= FNM_NOMATCH
;
1184 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1191 /* I cannot believe it but `strcat' is actually acceptable
1192 here. Match the entire string with the prefix from the
1193 pattern list and the rest of the pattern following the
1195 if (FCT (STRCAT (list
->str
, p
), string
, string_end
,
1197 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1198 NULL
, alloca_used
) == 0)
1199 /* It worked. Signal success. */
1201 while ((list
= list
->next
) != NULL
);
1203 /* None of the patterns lead to a match. */
1204 retval
= FNM_NOMATCH
;
1208 for (rs
= string
; rs
<= string_end
; ++rs
)
1210 struct patternlist
*runp
;
1212 for (runp
= list
; runp
!= NULL
; runp
= runp
->next
)
1213 if (FCT (runp
->str
, string
, rs
, no_leading_period
,
1214 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1215 NULL
, alloca_used
) == 0)
1218 /* If none of the patterns matched see whether the rest does. */
1220 && (FCT (p
, rs
, string_end
,
1223 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1224 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1225 NULL
, alloca_used
) == 0))
1226 /* This is successful. */
1230 /* None of the patterns together with the rest of the pattern
1232 retval
= FNM_NOMATCH
;
1236 assert (! "Invalid extended matching operator");
1244 while (list
!= NULL
)
1246 struct patternlist
*old
= list
;
1271 #undef WIDE_CHAR_VERSION