1 /* Copyright (C) 1991-1993, 1996-2000, 2001 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, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 /* Match STRING against the filename pattern PATTERN, returning zero if
20 it matches, nonzero if not. */
21 static int FCT (const CHAR
*pattern
, const CHAR
*string
,
22 const CHAR
*string_end
, int no_leading_period
, int flags
)
24 static int EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
,
25 const CHAR
*string_end
, int no_leading_period
, int flags
)
27 static const CHAR
*END (const CHAR
*patternp
) internal_function
;
31 FCT (pattern
, string
, string_end
, no_leading_period
, flags
)
34 const CHAR
*string_end
;
35 int no_leading_period
;
38 register const CHAR
*p
= pattern
, *n
= string
;
41 # if WIDE_CHAR_VERSION
42 const char *collseq
= (const char *)
43 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQWC
);
45 const UCHAR
*collseq
= (const UCHAR
*)
46 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQMB
);
50 while ((c
= *p
++) != L('\0'))
52 int new_no_leading_period
= 0;
58 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
62 res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
70 else if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
72 else if (*n
== L('.') && no_leading_period
)
77 if (!(flags
& FNM_NOESCAPE
))
81 /* Trailing \ loses. */
85 if (n
== string_end
|| FOLD ((UCHAR
) *n
) != c
)
90 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
94 res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
100 if (n
!= string_end
&& *n
== L('.') && no_leading_period
)
103 for (c
= *p
++; c
== L('?') || c
== L('*'); c
= *p
++)
105 if (*p
== L('(') && (flags
& FNM_EXTMATCH
) != 0)
107 const CHAR
*endp
= END (p
);
110 /* This is a pattern. Skip over it. */
118 /* A ? needs to match one character. */
120 /* There isn't another character; no match. */
122 else if (*n
== L('/')
123 && __builtin_expect (flags
& FNM_FILE_NAME
, 0))
124 /* A slash does not match a wildcard under
128 /* One character of the string is consumed in matching
129 this ? wildcard, so *??? won't match if there are
130 less than three characters. */
136 /* The wildcard(s) is/are the last element of the pattern.
137 If the name is a file name and contains another slash
138 this means it cannot match, unless the FNM_LEADING_DIR
141 int result
= (flags
& FNM_FILE_NAME
) == 0 ? 0 : FNM_NOMATCH
;
143 if (flags
& FNM_FILE_NAME
)
145 if (flags
& FNM_LEADING_DIR
)
149 if (MEMCHR (n
, L('/'), string_end
- n
) == NULL
)
160 endp
= MEMCHR (n
, (flags
& FNM_FILE_NAME
) ? L('/') : L('\0'),
166 || (__builtin_expect (flags
& FNM_EXTMATCH
, 0) != 0
167 && (c
== L('@') || c
== L('+') || c
== L('!'))
170 int flags2
= ((flags
& FNM_FILE_NAME
)
171 ? flags
: (flags
& ~FNM_PERIOD
));
172 int no_leading_period2
= no_leading_period
;
174 for (--p
; n
< endp
; ++n
, no_leading_period2
= 0)
175 if (FCT (p
, n
, string_end
, no_leading_period2
, flags2
)
179 else if (c
== L('/') && (flags
& FNM_FILE_NAME
))
181 while (n
< string_end
&& *n
!= L('/'))
183 if (n
< string_end
&& *n
== L('/')
184 && (FCT (p
, n
+ 1, string_end
, flags
& FNM_PERIOD
, flags
)
190 int flags2
= ((flags
& FNM_FILE_NAME
)
191 ? flags
: (flags
& ~FNM_PERIOD
));
192 int no_leading_period2
= no_leading_period
;
194 if (c
== L('\\') && !(flags
& FNM_NOESCAPE
))
197 for (--p
; n
< endp
; ++n
, no_leading_period2
= 0)
198 if (FOLD ((UCHAR
) *n
) == c
199 && (FCT (p
, n
, string_end
, no_leading_period2
, flags2
)
205 /* If we come here no match is possible with the wildcard. */
210 /* Nonzero if the sense of the character class is inverted. */
215 if (posixly_correct
== 0)
216 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
221 if (*n
== L('.') && no_leading_period
)
224 if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
225 /* `/' cannot be matched. */
228 not = (*p
== L('!') || (posixly_correct
< 0 && *p
== L('^')));
232 fn
= FOLD ((UCHAR
) *n
);
237 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
241 c
= FOLD ((UCHAR
) *p
);
247 else if (c
== L('[') && *p
== L(':'))
249 /* Leave room for the null. */
250 CHAR str
[CHAR_CLASS_MAX_LENGTH
+ 1];
252 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
255 const CHAR
*startp
= p
;
259 if (c1
== CHAR_CLASS_MAX_LENGTH
)
260 /* The name is too long and therefore the pattern
265 if (c
== L(':') && p
[1] == L(']'))
270 if (c
< L('a') || c
>= L('z'))
272 /* This cannot possibly be a character class name.
273 Match it as a normal range. */
282 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
283 wt
= IS_CHAR_CLASS (str
);
285 /* Invalid character class name. */
288 # if defined _LIBC && ! WIDE_CHAR_VERSION
289 /* The following code is glibc specific but does
290 there a good job in speeding up the code since
291 we can avoid the btowc() call. */
292 if (_ISCTYPE ((UCHAR
) *n
, wt
))
295 if (ISWCTYPE (BTOWC ((UCHAR
) *n
), wt
))
299 if ((STREQ (str
, L("alnum")) && ISALNUM ((UCHAR
) *n
))
300 || (STREQ (str
, L("alpha")) && ISALPHA ((UCHAR
) *n
))
301 || (STREQ (str
, L("blank")) && ISBLANK ((UCHAR
) *n
))
302 || (STREQ (str
, L("cntrl")) && ISCNTRL ((UCHAR
) *n
))
303 || (STREQ (str
, L("digit")) && ISDIGIT ((UCHAR
) *n
))
304 || (STREQ (str
, L("graph")) && ISGRAPH ((UCHAR
) *n
))
305 || (STREQ (str
, L("lower")) && ISLOWER ((UCHAR
) *n
))
306 || (STREQ (str
, L("print")) && ISPRINT ((UCHAR
) *n
))
307 || (STREQ (str
, L("punct")) && ISPUNCT ((UCHAR
) *n
))
308 || (STREQ (str
, L("space")) && ISSPACE ((UCHAR
) *n
))
309 || (STREQ (str
, L("upper")) && ISUPPER ((UCHAR
) *n
))
310 || (STREQ (str
, L("xdigit")) && ISXDIGIT ((UCHAR
) *n
)))
316 else if (c
== L('[') && *p
== L('='))
320 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
321 const CHAR
*startp
= p
;
333 if (c
!= L('=') || p
[1] != L(']'))
343 if ((UCHAR
) *n
== str
[0])
348 const int32_t *table
;
349 # if WIDE_CHAR_VERSION
350 const int32_t *weights
;
351 const int32_t *extra
;
353 const unsigned char *weights
;
354 const unsigned char *extra
;
356 const int32_t *indirect
;
358 const UCHAR
*cp
= (const UCHAR
*) str
;
360 /* This #include defines a local function! */
361 # if WIDE_CHAR_VERSION
362 # include <locale/weightwc.h>
364 # include <locale/weight.h>
367 # if WIDE_CHAR_VERSION
368 table
= (const int32_t *)
369 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEWC
);
370 weights
= (const int32_t *)
371 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTWC
);
372 extra
= (const int32_t *)
373 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAWC
);
374 indirect
= (const int32_t *)
375 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTWC
);
377 table
= (const int32_t *)
378 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_TABLEMB
);
379 weights
= (const unsigned char *)
380 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_WEIGHTMB
);
381 extra
= (const unsigned char *)
382 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_EXTRAMB
);
383 indirect
= (const int32_t *)
384 _NL_CURRENT (LC_COLLATE
, _NL_COLLATE_INDIRECTMB
);
390 /* We found a table entry. Now see whether the
391 character we are currently at has the same
392 equivalance class value. */
393 int len
= weights
[idx
];
395 const UCHAR
*np
= (const UCHAR
*) n
;
397 idx2
= findidx (&np
);
398 if (idx2
!= 0 && len
== weights
[idx2
])
403 && (weights
[idx
+ 1 + cnt
]
404 == weights
[idx2
+ 1 + cnt
]))
416 else if (c
== L('\0'))
417 /* [ (unterminated) loses. */
426 if (c
== L('[') && *p
== L('.'))
429 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
430 const CHAR
*startp
= p
;
436 if (c
== L('.') && p
[1] == L(']'))
446 /* We have to handling the symbols differently in
447 ranges since then the collation sequence is
449 is_range
= *p
== L('-') && p
[1] != L('\0');
453 /* There are no names defined in the collation
454 data. Therefore we only accept the trivial
455 names consisting of the character itself. */
459 if (!is_range
&& *n
== startp
[1])
468 const int32_t *symb_table
;
469 # ifdef WIDE_CHAR_VERSION
473 # define str (startp + 1)
475 const unsigned char *extra
;
481 # ifdef WIDE_CHAR_VERSION
482 /* We have to convert the name to a single-byte
483 string. This is possible since the names
484 consist of ASCII characters and the internal
485 representation is UCS4. */
486 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
487 str
[strcnt
] = startp
[1 + strcnt
];
491 _NL_CURRENT_WORD (LC_COLLATE
,
492 _NL_COLLATE_SYMB_HASH_SIZEMB
);
493 symb_table
= (const int32_t *)
494 _NL_CURRENT (LC_COLLATE
,
495 _NL_COLLATE_SYMB_TABLEMB
);
496 extra
= (const unsigned char *)
497 _NL_CURRENT (LC_COLLATE
,
498 _NL_COLLATE_SYMB_EXTRAMB
);
500 /* Locate the character in the hashing table. */
501 hash
= elem_hash (str
, c1
);
504 elem
= hash
% table_size
;
505 second
= hash
% (table_size
- 2);
506 while (symb_table
[2 * elem
] != 0)
508 /* First compare the hashing value. */
509 if (symb_table
[2 * elem
] == hash
510 && c1
== extra
[symb_table
[2 * elem
+ 1]]
512 &extra
[symb_table
[2 * elem
+ 1]
515 /* Yep, this is the entry. */
516 idx
= symb_table
[2 * elem
+ 1];
517 idx
+= 1 + extra
[idx
];
525 if (symb_table
[2 * elem
] != 0)
527 /* Compare the byte sequence but only if
528 this is not part of a range. */
529 # ifdef WIDE_CHAR_VERSION
532 idx
+= 1 + extra
[idx
];
533 /* Adjust for the alignment. */
534 idx
= (idx
+ 3) & ~3;
536 wextra
= (int32_t *) &extra
[idx
+ 4];
541 # ifdef WIDE_CHAR_VERSION
542 for (c1
= 0; c1
< wextra
[idx
]; ++c1
)
543 if (n
[c1
] != wextra
[1 + c1
])
546 if (c1
== wextra
[idx
])
549 for (c1
= 0; c1
< extra
[idx
]; ++c1
)
550 if (n
[c1
] != extra
[1 + c1
])
553 if (c1
== extra
[idx
])
558 /* Get the collation sequence value. */
560 # ifdef WIDE_CHAR_VERSION
561 cold
= wextra
[1 + wextra
[idx
]];
563 /* Adjust for the alignment. */
564 idx
+= 1 + extra
[idx
];
565 idx
= (idx
+ 3) & ~4;
566 cold
= *((int32_t *) &extra
[idx
]);
573 /* No valid character. Match it as a
575 if (!is_range
&& *n
== str
[0])
592 /* We have to handling the symbols differently in
593 ranges since then the collation sequence is
595 is_range
= (*p
== L('-') && p
[1] != L('\0')
598 if (!is_range
&& c
== fn
)
605 if (c
== L('-') && *p
!= L(']'))
608 /* We have to find the collation sequence
609 value for C. Collation sequence is nothing
610 we can regularly access. The sequence
611 value is defined by the order in which the
612 definitions of the collation values for the
613 various characters appear in the source
614 file. A strange concept, nowhere
620 # ifdef WIDE_CHAR_VERSION
621 /* Search in the `names' array for the characters. */
622 fcollseq
= collseq_table_lookup (collseq
, fn
);
623 if (fcollseq
== ~((uint32_t) 0))
624 /* XXX We don't know anything about the character
625 we are supposed to match. This means we are
627 goto range_not_matched
;
632 lcollseq
= collseq_table_lookup (collseq
, cold
);
634 fcollseq
= collseq
[fn
];
635 lcollseq
= is_seqval
? cold
: collseq
[(UCHAR
) cold
];
639 if (cend
== L('[') && *p
== L('.'))
642 _NL_CURRENT_WORD (LC_COLLATE
,
644 const CHAR
*startp
= p
;
650 if (c
== L('.') && p
[1] == L(']'))
662 /* There are no names defined in the
663 collation data. Therefore we only
664 accept the trivial names consisting
665 of the character itself. */
674 const int32_t *symb_table
;
675 # ifdef WIDE_CHAR_VERSION
679 # define str (startp + 1)
681 const unsigned char *extra
;
687 # ifdef WIDE_CHAR_VERSION
688 /* We have to convert the name to a single-byte
689 string. This is possible since the names
690 consist of ASCII characters and the internal
691 representation is UCS4. */
692 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
693 str
[strcnt
] = startp
[1 + strcnt
];
697 _NL_CURRENT_WORD (LC_COLLATE
,
698 _NL_COLLATE_SYMB_HASH_SIZEMB
);
699 symb_table
= (const int32_t *)
700 _NL_CURRENT (LC_COLLATE
,
701 _NL_COLLATE_SYMB_TABLEMB
);
702 extra
= (const unsigned char *)
703 _NL_CURRENT (LC_COLLATE
,
704 _NL_COLLATE_SYMB_EXTRAMB
);
706 /* Locate the character in the hashing
708 hash
= elem_hash (str
, c1
);
711 elem
= hash
% table_size
;
712 second
= hash
% (table_size
- 2);
713 while (symb_table
[2 * elem
] != 0)
715 /* First compare the hashing value. */
716 if (symb_table
[2 * elem
] == hash
718 == extra
[symb_table
[2 * elem
+ 1]])
720 &extra
[symb_table
[2 * elem
+ 1]
723 /* Yep, this is the entry. */
724 idx
= symb_table
[2 * elem
+ 1];
725 idx
+= 1 + extra
[idx
];
733 if (symb_table
[2 * elem
] != 0)
735 /* Compare the byte sequence but only if
736 this is not part of a range. */
737 # ifdef WIDE_CHAR_VERSION
740 idx
+= 1 + extra
[idx
];
741 /* Adjust for the alignment. */
742 idx
= (idx
+ 3) & ~4;
744 wextra
= (int32_t *) &extra
[idx
+ 4];
746 /* Get the collation sequence value. */
748 # ifdef WIDE_CHAR_VERSION
749 cend
= wextra
[1 + wextra
[idx
]];
751 /* Adjust for the alignment. */
752 idx
+= 1 + extra
[idx
];
753 idx
= (idx
+ 3) & ~4;
754 cend
= *((int32_t *) &extra
[idx
]);
757 else if (symb_table
[2 * elem
] != 0 && c1
== 1)
769 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
776 /* XXX It is not entirely clear to me how to handle
777 characters which are not mentioned in the
778 collation specification. */
780 # ifdef WIDE_CHAR_VERSION
781 lcollseq
== 0xffffffff ||
783 lcollseq
<= fcollseq
)
785 /* We have to look at the upper bound. */
792 # ifdef WIDE_CHAR_VERSION
794 collseq_table_lookup (collseq
, cend
);
795 if (hcollseq
== ~((uint32_t) 0))
797 /* Hum, no information about the upper
798 bound. The matching succeeds if the
799 lower bound is matched exactly. */
800 if (lcollseq
!= fcollseq
)
801 goto range_not_matched
;
806 hcollseq
= collseq
[cend
];
810 if (lcollseq
<= hcollseq
&& fcollseq
<= hcollseq
)
813 # ifdef WIDE_CHAR_VERSION
817 /* We use a boring value comparison of the character
818 values. This is better than comparing using
819 `strcoll' since the latter would have surprising
820 and sometimes fatal consequences. */
823 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
829 if (cold
<= fn
&& fn
<= cend
)
846 /* Skip the rest of the [...] that already matched. */
853 /* [... (unterminated) loses. */
856 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
860 /* XXX 1003.2d11 is unclear if this is right. */
863 else if (c
== L('[') && *p
== L(':'))
866 const CHAR
*startp
= p
;
871 if (++c1
== CHAR_CLASS_MAX_LENGTH
)
874 if (*p
== L(':') && p
[1] == L(']'))
877 if (c
< L('a') || c
>= L('z'))
886 else if (c
== L('[') && *p
== L('='))
892 if (c
!= L('=') || p
[1] != L(']'))
897 else if (c
== L('[') && *p
== L('.'))
906 if (*p
== L('.') && p
[1] == L(']'))
922 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
926 res
= EXT (c
, p
, n
, string_end
, no_leading_period
, flags
);
933 if (NO_LEADING_PERIOD (flags
))
935 if (n
== string_end
|| c
!= *n
)
938 new_no_leading_period
= 1;
944 if (n
== string_end
|| c
!= FOLD ((UCHAR
) *n
))
948 no_leading_period
= new_no_leading_period
;
955 if ((flags
& FNM_LEADING_DIR
) && n
!= string_end
&& *n
== L('/'))
956 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
965 END (const CHAR
*pattern
)
967 const CHAR
*p
= pattern
;
971 /* This is an invalid pattern. */
973 else if (*p
== L('['))
975 /* Handle brackets special. */
976 if (posixly_correct
== 0)
977 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
979 /* Skip the not sign. We have to recognize it because of a possibly
981 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
983 /* A leading ']' is recognized as such. */
986 /* Skip over all characters of the list. */
989 /* This is no valid pattern. */
992 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
993 || *p
== L('!')) && p
[1] == L('('))
995 else if (*p
== L(')'))
1004 EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
1005 int no_leading_period
, int flags
)
1011 struct patternlist
*next
;
1014 struct patternlist
**lastp
= &list
;
1015 size_t pattern_len
= STRLEN (pattern
);
1019 /* Parse the pattern. Store the individual parts in the list. */
1021 for (startp
= p
= pattern
+ 1; level
>= 0; ++p
)
1023 /* This is an invalid pattern. */
1025 else if (*p
== L('['))
1027 /* Handle brackets special. */
1028 if (posixly_correct
== 0)
1029 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1031 /* Skip the not sign. We have to recognize it because of a possibly
1033 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1035 /* A leading ']' is recognized as such. */
1038 /* Skip over all characters of the list. */
1039 while (*p
!= L(']'))
1040 if (*p
++ == L('\0'))
1041 /* This is no valid pattern. */
1044 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1045 || *p
== L('!')) && p
[1] == L('('))
1046 /* Remember the nesting level. */
1048 else if (*p
== L(')'))
1052 /* This means we found the end of the pattern. */
1053 #define NEW_PATTERN \
1054 struct patternlist *newp; \
1056 if (opt == L('?') || opt == L('@')) \
1057 newp = alloca (sizeof (struct patternlist) \
1058 + (pattern_len * sizeof (CHAR))); \
1060 newp = alloca (sizeof (struct patternlist) \
1061 + ((p - startp + 1) * sizeof (CHAR))); \
1062 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1063 newp->next = NULL; \
1069 else if (*p
== L('|'))
1077 assert (list
!= NULL
);
1078 assert (p
[-1] == L(')'));
1084 if (FCT (p
, string
, string_end
, no_leading_period
, flags
) == 0)
1091 for (rs
= string
; rs
<= string_end
; ++rs
)
1092 /* First match the prefix with the current pattern with the
1094 if (FCT (list
->str
, string
, rs
, no_leading_period
,
1095 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
) == 0
1096 /* This was successful. Now match the rest with the rest
1098 && (FCT (p
, rs
, string_end
,
1101 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1102 flags
& FNM_FILE_NAME
1103 ? flags
: flags
& ~FNM_PERIOD
) == 0
1104 /* This didn't work. Try the whole pattern. */
1106 && FCT (pattern
- 1, rs
, string_end
,
1109 : (rs
[-1] == '/' && NO_LEADING_PERIOD (flags
)
1111 flags
& FNM_FILE_NAME
1112 ? flags
: flags
& ~FNM_PERIOD
) == 0)))
1113 /* It worked. Signal success. */
1116 while ((list
= list
->next
) != NULL
);
1118 /* None of the patterns lead to a match. */
1122 if (FCT (p
, string
, string_end
, no_leading_period
, flags
) == 0)
1128 /* I cannot believe it but `strcat' is actually acceptable
1129 here. Match the entire string with the prefix from the
1130 pattern list and the rest of the pattern following the
1132 if (FCT (STRCAT (list
->str
, p
), string
, string_end
,
1134 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
) == 0)
1135 /* It worked. Signal success. */
1137 while ((list
= list
->next
) != NULL
);
1139 /* None of the patterns lead to a match. */
1143 for (rs
= string
; rs
<= string_end
; ++rs
)
1145 struct patternlist
*runp
;
1147 for (runp
= list
; runp
!= NULL
; runp
= runp
->next
)
1148 if (FCT (runp
->str
, string
, rs
, no_leading_period
,
1149 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
) == 0)
1152 /* If none of the patterns matched see whether the rest does. */
1154 && (FCT (p
, rs
, string_end
,
1157 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1158 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
)
1160 /* This is successful. */
1164 /* None of the patterns together with the rest of the pattern
1169 assert (! "Invalid extended matching operator");