1 /* Copyright (C) 1991-1993, 1996-2006, 2009-2016 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 This program 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
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
17 /* Match STRING against the file name pattern PATTERN, returning zero if
18 it matches, nonzero if not. */
19 static int EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
,
20 const CHAR
*string_end
, bool no_leading_period
, int flags
)
22 static const CHAR
*END (const CHAR
*patternp
) internal_function
;
26 FCT (const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
27 bool no_leading_period
, int flags
)
29 register const CHAR
*p
= pattern
, *n
= string
;
32 # if WIDE_CHAR_VERSION
33 const char *collseq
= (const char *)
34 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQWC
);
36 const UCHAR
*collseq
= (const UCHAR
*)
37 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQMB
);
41 while ((c
= *p
++) != L_('\0'))
43 bool new_no_leading_period
= false;
49 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
53 res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
61 else if (*n
== L_('/') && (flags
& FNM_FILE_NAME
))
63 else if (*n
== L_('.') && no_leading_period
)
68 if (!(flags
& FNM_NOESCAPE
))
72 /* Trailing \ loses. */
76 if (n
== string_end
|| FOLD ((UCHAR
) *n
) != c
)
81 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
85 res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
91 if (n
!= string_end
&& *n
== L_('.') && no_leading_period
)
94 for (c
= *p
++; c
== L_('?') || c
== L_('*'); c
= *p
++)
96 if (*p
== L_('(') && (flags
& FNM_EXTMATCH
) != 0)
98 const CHAR
*endp
= END (p
);
101 /* This is a pattern. Skip over it. */
109 /* A ? needs to match one character. */
111 /* There isn't another character; no match. */
113 else if (*n
== L_('/')
114 && __builtin_expect (flags
& FNM_FILE_NAME
, 0))
115 /* A slash does not match a wildcard under
119 /* One character of the string is consumed in matching
120 this ? wildcard, so *??? won't match if there are
121 less than three characters. */
127 /* The wildcard(s) is/are the last element of the pattern.
128 If the name is a file name and contains another slash
129 this means it cannot match, unless the FNM_LEADING_DIR
132 int result
= (flags
& FNM_FILE_NAME
) == 0 ? 0 : FNM_NOMATCH
;
134 if (flags
& FNM_FILE_NAME
)
136 if (flags
& FNM_LEADING_DIR
)
140 if (MEMCHR (n
, L_('/'), string_end
- n
) == NULL
)
151 endp
= MEMCHR (n
, (flags
& FNM_FILE_NAME
) ? L_('/') : L_('\0'),
157 || (__builtin_expect (flags
& FNM_EXTMATCH
, 0) != 0
158 && (c
== L_('@') || c
== L_('+') || c
== L_('!'))
161 int flags2
= ((flags
& FNM_FILE_NAME
)
162 ? flags
: (flags
& ~FNM_PERIOD
));
163 bool no_leading_period2
= no_leading_period
;
165 for (--p
; n
< endp
; ++n
, no_leading_period2
= false)
166 if (FCT (p
, n
, string_end
, no_leading_period2
, flags2
)
170 else if (c
== L_('/') && (flags
& FNM_FILE_NAME
))
172 while (n
< string_end
&& *n
!= L_('/'))
174 if (n
< string_end
&& *n
== L_('/')
175 && (FCT (p
, n
+ 1, string_end
, flags
& FNM_PERIOD
, flags
)
181 int flags2
= ((flags
& FNM_FILE_NAME
)
182 ? flags
: (flags
& ~FNM_PERIOD
));
183 int no_leading_period2
= no_leading_period
;
185 if (c
== L_('\\') && !(flags
& FNM_NOESCAPE
))
188 for (--p
; n
< endp
; ++n
, no_leading_period2
= false)
189 if (FOLD ((UCHAR
) *n
) == c
190 && (FCT (p
, n
, string_end
, no_leading_period2
, flags2
)
196 /* If we come here no match is possible with the wildcard. */
201 /* Nonzero if the sense of the character class is inverted. */
202 const CHAR
*p_init
= p
;
203 const CHAR
*n_init
= n
;
208 if (posixly_correct
== 0)
209 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
214 if (*n
== L_('.') && no_leading_period
)
217 if (*n
== L_('/') && (flags
& FNM_FILE_NAME
))
218 /* '/' cannot be matched. */
221 not = (*p
== L_('!') || (posixly_correct
< 0 && *p
== L_('^')));
225 fn
= FOLD ((UCHAR
) *n
);
230 bool is_range
= false;
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. */
426 bool is_seqval
= false;
428 if (c
== L_('[') && *p
== L_('.'))
431 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
432 const CHAR
*startp
= p
;
438 if (c
== L_('.') && p
[1] == L_(']'))
448 /* We have to handling the symbols differently in
449 ranges since then the collation sequence is
451 is_range
= *p
== L_('-') && p
[1] != L_('\0');
455 /* There are no names defined in the collation
456 data. Therefore we only accept the trivial
457 names consisting of the character itself. */
461 if (!is_range
&& *n
== startp
[1])
470 const int32_t *symb_table
;
471 # ifdef WIDE_CHAR_VERSION
475 # define str (startp + 1)
477 const unsigned char *extra
;
483 # ifdef WIDE_CHAR_VERSION
484 /* We have to convert the name to a single-byte
485 string. This is possible since the names
486 consist of ASCII characters and the internal
487 representation is UCS4. */
488 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
489 str
[strcnt
] = startp
[1 + strcnt
];
493 _NL_CURRENT_WORD (LC_COLLATE
,
494 _NL_COLLATE_SYMB_HASH_SIZEMB
);
495 symb_table
= (const int32_t *)
496 _NL_CURRENT (LC_COLLATE
,
497 _NL_COLLATE_SYMB_TABLEMB
);
498 extra
= (const unsigned char *)
499 _NL_CURRENT (LC_COLLATE
,
500 _NL_COLLATE_SYMB_EXTRAMB
);
502 /* Locate the character in the hashing table. */
503 hash
= elem_hash (str
, c1
);
506 elem
= hash
% table_size
;
507 if (symb_table
[2 * elem
] != 0)
509 second
= hash
% (table_size
- 2) + 1;
513 /* First compare the hashing value. */
514 if (symb_table
[2 * elem
] == hash
516 == extra
[symb_table
[2 * elem
+ 1]])
518 &extra
[symb_table
[2 * elem
522 /* Yep, this is the entry. */
523 idx
= symb_table
[2 * elem
+ 1];
524 idx
+= 1 + extra
[idx
];
531 while (symb_table
[2 * elem
] != 0);
534 if (symb_table
[2 * elem
] != 0)
536 /* Compare the byte sequence but only if
537 this is not part of a range. */
538 # ifdef WIDE_CHAR_VERSION
541 idx
+= 1 + extra
[idx
];
542 /* Adjust for the alignment. */
543 idx
= (idx
+ 3) & ~3;
545 wextra
= (int32_t *) &extra
[idx
+ 4];
550 # ifdef WIDE_CHAR_VERSION
552 (int32_t) c1
< wextra
[idx
];
554 if (n
[c1
] != wextra
[1 + c1
])
557 if ((int32_t) c1
== wextra
[idx
])
560 for (c1
= 0; c1
< extra
[idx
]; ++c1
)
561 if (n
[c1
] != extra
[1 + c1
])
564 if (c1
== extra
[idx
])
569 /* Get the collation sequence value. */
571 # ifdef WIDE_CHAR_VERSION
572 cold
= wextra
[1 + wextra
[idx
]];
574 /* Adjust for the alignment. */
575 idx
+= 1 + extra
[idx
];
576 idx
= (idx
+ 3) & ~4;
577 cold
= *((int32_t *) &extra
[idx
]);
584 /* No valid character. Match it as a
586 if (!is_range
&& *n
== str
[0])
603 /* We have to handling the symbols differently in
604 ranges since then the collation sequence is
606 is_range
= (*p
== L_('-') && p
[1] != L_('\0')
609 if (!is_range
&& c
== fn
)
613 /* This is needed if we goto normal_bracket; from
614 outside of is_seqval's scope. */
622 if (c
== L_('-') && *p
!= L_(']'))
625 /* We have to find the collation sequence
626 value for C. Collation sequence is nothing
627 we can regularly access. The sequence
628 value is defined by the order in which the
629 definitions of the collation values for the
630 various characters appear in the source
631 file. A strange concept, nowhere
637 # ifdef WIDE_CHAR_VERSION
638 /* Search in the 'names' array for the characters. */
639 fcollseq
= __collseq_table_lookup (collseq
, fn
);
640 if (fcollseq
== ~((uint32_t) 0))
641 /* XXX We don't know anything about the character
642 we are supposed to match. This means we are
644 goto range_not_matched
;
649 lcollseq
= __collseq_table_lookup (collseq
, cold
);
651 fcollseq
= collseq
[fn
];
652 lcollseq
= is_seqval
? cold
: collseq
[(UCHAR
) cold
];
656 if (cend
== L_('[') && *p
== L_('.'))
659 _NL_CURRENT_WORD (LC_COLLATE
,
661 const CHAR
*startp
= p
;
667 if (c
== L_('.') && p
[1] == L_(']'))
679 /* There are no names defined in the
680 collation data. Therefore we only
681 accept the trivial names consisting
682 of the character itself. */
691 const int32_t *symb_table
;
692 # ifdef WIDE_CHAR_VERSION
696 # define str (startp + 1)
698 const unsigned char *extra
;
704 # ifdef WIDE_CHAR_VERSION
705 /* We have to convert the name to a single-byte
706 string. This is possible since the names
707 consist of ASCII characters and the internal
708 representation is UCS4. */
709 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
710 str
[strcnt
] = startp
[1 + strcnt
];
714 _NL_CURRENT_WORD (LC_COLLATE
,
715 _NL_COLLATE_SYMB_HASH_SIZEMB
);
716 symb_table
= (const int32_t *)
717 _NL_CURRENT (LC_COLLATE
,
718 _NL_COLLATE_SYMB_TABLEMB
);
719 extra
= (const unsigned char *)
720 _NL_CURRENT (LC_COLLATE
,
721 _NL_COLLATE_SYMB_EXTRAMB
);
723 /* Locate the character in the hashing
725 hash
= elem_hash (str
, c1
);
728 elem
= hash
% table_size
;
729 if (symb_table
[2 * elem
] != 0)
731 second
= hash
% (table_size
- 2) + 1;
735 /* First compare the hashing value. */
736 if (symb_table
[2 * elem
] == hash
738 == extra
[symb_table
[2 * elem
+ 1]])
740 &extra
[symb_table
[2 * elem
+ 1]
743 /* Yep, this is the entry. */
744 idx
= symb_table
[2 * elem
+ 1];
745 idx
+= 1 + extra
[idx
];
752 while (symb_table
[2 * elem
] != 0);
755 if (symb_table
[2 * elem
] != 0)
757 /* Compare the byte sequence but only if
758 this is not part of a range. */
759 # ifdef WIDE_CHAR_VERSION
762 idx
+= 1 + extra
[idx
];
763 /* Adjust for the alignment. */
764 idx
= (idx
+ 3) & ~4;
766 wextra
= (int32_t *) &extra
[idx
+ 4];
768 /* Get the collation sequence value. */
770 # ifdef WIDE_CHAR_VERSION
771 cend
= wextra
[1 + wextra
[idx
]];
773 /* Adjust for the alignment. */
774 idx
+= 1 + extra
[idx
];
775 idx
= (idx
+ 3) & ~4;
776 cend
= *((int32_t *) &extra
[idx
]);
779 else if (symb_table
[2 * elem
] != 0 && c1
== 1)
791 if (!(flags
& FNM_NOESCAPE
) && cend
== L_('\\'))
793 if (cend
== L_('\0'))
798 /* XXX It is not entirely clear to me how to handle
799 characters which are not mentioned in the
800 collation specification. */
802 # ifdef WIDE_CHAR_VERSION
803 lcollseq
== 0xffffffff ||
805 lcollseq
<= fcollseq
)
807 /* We have to look at the upper bound. */
814 # ifdef WIDE_CHAR_VERSION
816 __collseq_table_lookup (collseq
, cend
);
817 if (hcollseq
== ~((uint32_t) 0))
819 /* Hum, no information about the upper
820 bound. The matching succeeds if the
821 lower bound is matched exactly. */
822 if (lcollseq
!= fcollseq
)
823 goto range_not_matched
;
828 hcollseq
= collseq
[cend
];
832 if (lcollseq
<= hcollseq
&& fcollseq
<= hcollseq
)
835 # ifdef WIDE_CHAR_VERSION
839 /* We use a boring value comparison of the character
840 values. This is better than comparing using
841 'strcoll' since the latter would have surprising
842 and sometimes fatal consequences. */
845 if (!(flags
& FNM_NOESCAPE
) && cend
== L_('\\'))
847 if (cend
== L_('\0'))
851 if (cold
<= fn
&& fn
<= cend
)
868 /* Skip the rest of the [...] that already matched. */
875 /* [... (unterminated) loses. */
878 if (!(flags
& FNM_NOESCAPE
) && c
== L_('\\'))
882 /* XXX 1003.2d11 is unclear if this is right. */
885 else if (c
== L_('[') && *p
== L_(':'))
888 const CHAR
*startp
= p
;
893 if (++c1
== CHAR_CLASS_MAX_LENGTH
)
896 if (*p
== L_(':') && p
[1] == L_(']'))
899 if (c
< L_('a') || c
>= L_('z'))
908 else if (c
== L_('[') && *p
== L_('='))
914 if (c
!= L_('=') || p
[1] != L_(']'))
919 else if (c
== L_('[') && *p
== L_('.'))
928 if (*p
== L_('.') && p
[1] == L_(']'))
935 while (c
!= L_(']'));
944 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
948 res
= EXT (c
, p
, n
, string_end
, no_leading_period
, flags
);
955 if (NO_LEADING_PERIOD (flags
))
957 if (n
== string_end
|| c
!= (UCHAR
) *n
)
960 new_no_leading_period
= true;
966 if (n
== string_end
|| c
!= FOLD ((UCHAR
) *n
))
970 no_leading_period
= new_no_leading_period
;
977 if ((flags
& FNM_LEADING_DIR
) && n
!= string_end
&& *n
== L_('/'))
978 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
987 END (const CHAR
*pattern
)
989 const CHAR
*p
= pattern
;
992 if (*++p
== L_('\0'))
993 /* This is an invalid pattern. */
995 else if (*p
== L_('['))
997 /* Handle brackets special. */
998 if (posixly_correct
== 0)
999 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1001 /* Skip the not sign. We have to recognize it because of a possibly
1003 if (*++p
== L_('!') || (posixly_correct
< 0 && *p
== L_('^')))
1005 /* A leading ']' is recognized as such. */
1008 /* Skip over all characters of the list. */
1009 while (*p
!= L_(']'))
1010 if (*p
++ == L_('\0'))
1011 /* This is no valid pattern. */
1014 else if ((*p
== L_('?') || *p
== L_('*') || *p
== L_('+') || *p
== L_('@')
1015 || *p
== L_('!')) && p
[1] == L_('('))
1017 else if (*p
== L_(')'))
1026 EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
1027 bool no_leading_period
, int flags
)
1033 struct patternlist
*next
;
1034 CHAR str
[FLEXIBLE_ARRAY_MEMBER
];
1036 struct patternlist
**lastp
= &list
;
1037 size_t pattern_len
= STRLEN (pattern
);
1040 enum { ALLOCA_LIMIT
= 8000 };
1042 /* Parse the pattern. Store the individual parts in the list. */
1044 for (startp
= p
= pattern
+ 1; ; ++p
)
1046 /* This is an invalid pattern. */
1048 else if (*p
== L_('['))
1050 /* Handle brackets special. */
1051 if (posixly_correct
== 0)
1052 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1054 /* Skip the not sign. We have to recognize it because of a possibly
1056 if (*++p
== L_('!') || (posixly_correct
< 0 && *p
== L_('^')))
1058 /* A leading ']' is recognized as such. */
1061 /* Skip over all characters of the list. */
1062 while (*p
!= L_(']'))
1063 if (*p
++ == L_('\0'))
1064 /* This is no valid pattern. */
1067 else if ((*p
== L_('?') || *p
== L_('*') || *p
== L_('+') || *p
== L_('@')
1068 || *p
== L_('!')) && p
[1] == L_('('))
1069 /* Remember the nesting level. */
1071 else if (*p
== L_(')'))
1075 /* This means we found the end of the pattern. */
1076 #define NEW_PATTERN \
1077 struct patternlist *newp; \
1082 plen = (opt == L_('?') || opt == L_('@') \
1084 : p - startp + 1UL); \
1085 plensize = plen * sizeof (CHAR); \
1086 newpsize = FLEXSIZEOF (struct patternlist, str, plensize); \
1087 if ((size_t) -1 / sizeof (CHAR) < plen \
1088 || newpsize < offsetof (struct patternlist, str) \
1089 || ALLOCA_LIMIT <= newpsize) \
1091 newp = (struct patternlist *) alloca (newpsize); \
1092 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \
1093 newp->next = NULL; \
1100 else if (*p
== L_('|'))
1108 assert (list
!= NULL
);
1109 assert (p
[-1] == L_(')'));
1115 if (FCT (p
, string
, string_end
, no_leading_period
, flags
) == 0)
1122 for (rs
= string
; rs
<= string_end
; ++rs
)
1123 /* First match the prefix with the current pattern with the
1125 if (FCT (list
->str
, string
, rs
, no_leading_period
,
1126 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
) == 0
1127 /* This was successful. Now match the rest with the rest
1129 && (FCT (p
, rs
, string_end
,
1132 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
),
1133 flags
& FNM_FILE_NAME
1134 ? flags
: flags
& ~FNM_PERIOD
) == 0
1135 /* This didn't work. Try the whole pattern. */
1137 && FCT (pattern
- 1, rs
, string_end
,
1140 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
),
1141 flags
& FNM_FILE_NAME
1142 ? flags
: flags
& ~FNM_PERIOD
) == 0)))
1143 /* It worked. Signal success. */
1146 while ((list
= list
->next
) != NULL
);
1148 /* None of the patterns lead to a match. */
1152 if (FCT (p
, string
, string_end
, no_leading_period
, flags
) == 0)
1158 /* I cannot believe it but 'strcat' is actually acceptable
1159 here. Match the entire string with the prefix from the
1160 pattern list and the rest of the pattern following the
1162 if (FCT (STRCAT (list
->str
, p
), string
, string_end
,
1164 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
) == 0)
1165 /* It worked. Signal success. */
1167 while ((list
= list
->next
) != NULL
);
1169 /* None of the patterns lead to a match. */
1173 for (rs
= string
; rs
<= string_end
; ++rs
)
1175 struct patternlist
*runp
;
1177 for (runp
= list
; runp
!= NULL
; runp
= runp
->next
)
1178 if (FCT (runp
->str
, string
, rs
, no_leading_period
,
1179 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
) == 0)
1182 /* If none of the patterns matched see whether the rest does. */
1184 && (FCT (p
, rs
, string_end
,
1187 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
),
1188 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
)
1190 /* This is successful. */
1194 /* None of the patterns together with the rest of the pattern
1199 assert (! "Invalid extended matching operator");