1 /* Copyright (C) 1991-2013 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/>. */
22 int no_leading_period
;
25 /* Match STRING against the filename pattern PATTERN, returning zero if
26 it matches, nonzero if not. */
27 static int FCT (const CHAR
*pattern
, const CHAR
*string
,
28 const CHAR
*string_end
, int no_leading_period
, int flags
,
29 struct STRUCT
*ends
, size_t alloca_used
)
31 static int EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
,
32 const CHAR
*string_end
, int no_leading_period
, int flags
,
35 static const CHAR
*END (const CHAR
*patternp
) internal_function
;
39 FCT (pattern
, string
, string_end
, no_leading_period
, flags
, ends
, alloca_used
)
42 const CHAR
*string_end
;
43 int no_leading_period
;
48 register const CHAR
*p
= pattern
, *n
= string
;
51 # if WIDE_CHAR_VERSION
52 const char *collseq
= (const char *)
53 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQWC
);
55 const UCHAR
*collseq
= (const UCHAR
*)
56 _NL_CURRENT(LC_COLLATE
, _NL_COLLATE_COLLSEQMB
);
60 while ((c
= *p
++) != L('\0'))
62 int new_no_leading_period
= 0;
68 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
70 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
78 else if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
80 else if (*n
== L('.') && no_leading_period
)
85 if (!(flags
& FNM_NOESCAPE
))
89 /* Trailing \ loses. */
93 if (n
== string_end
|| FOLD ((UCHAR
) *n
) != c
)
98 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
100 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
,
105 else if (ends
!= NULL
)
107 ends
->pattern
= p
- 1;
109 ends
->no_leading_period
= no_leading_period
;
113 if (n
!= string_end
&& *n
== L('.') && no_leading_period
)
116 for (c
= *p
++; c
== L('?') || c
== L('*'); c
= *p
++)
118 if (*p
== L('(') && (flags
& FNM_EXTMATCH
) != 0)
120 const CHAR
*endp
= END (p
);
123 /* This is a pattern. Skip over it. */
131 /* A ? needs to match one character. */
133 /* There isn't another character; no match. */
135 else if (*n
== L('/')
136 && __builtin_expect (flags
& FNM_FILE_NAME
, 0))
137 /* A slash does not match a wildcard under
141 /* One character of the string is consumed in matching
142 this ? wildcard, so *??? won't match if there are
143 less than three characters. */
149 /* The wildcard(s) is/are the last element of the pattern.
150 If the name is a file name and contains another slash
151 this means it cannot match, unless the FNM_LEADING_DIR
154 int result
= (flags
& FNM_FILE_NAME
) == 0 ? 0 : FNM_NOMATCH
;
156 if (flags
& FNM_FILE_NAME
)
158 if (flags
& FNM_LEADING_DIR
)
162 if (MEMCHR (n
, L('/'), string_end
- n
) == NULL
)
175 endp
= MEMCHR (n
, (flags
& FNM_FILE_NAME
) ? L('/') : L('\0'),
181 || (__builtin_expect (flags
& FNM_EXTMATCH
, 0) != 0
182 && (c
== L('@') || c
== L('+') || c
== L('!'))
185 int flags2
= ((flags
& FNM_FILE_NAME
)
186 ? flags
: (flags
& ~FNM_PERIOD
));
188 for (--p
; n
< endp
; ++n
, no_leading_period
= 0)
189 if (FCT (p
, n
, string_end
, no_leading_period
, flags2
,
190 &end
, alloca_used
) == 0)
193 else if (c
== L('/') && (flags
& FNM_FILE_NAME
))
195 while (n
< string_end
&& *n
!= L('/'))
197 if (n
< string_end
&& *n
== L('/')
198 && (FCT (p
, n
+ 1, string_end
, flags
& FNM_PERIOD
, flags
,
199 NULL
, alloca_used
) == 0))
204 int flags2
= ((flags
& FNM_FILE_NAME
)
205 ? flags
: (flags
& ~FNM_PERIOD
));
207 if (c
== L('\\') && !(flags
& FNM_NOESCAPE
))
210 for (--p
; n
< endp
; ++n
, no_leading_period
= 0)
211 if (FOLD ((UCHAR
) *n
) == c
212 && (FCT (p
, n
, string_end
, no_leading_period
, flags2
,
213 &end
, alloca_used
) == 0))
216 if (end
.pattern
== NULL
)
220 if (end
.pattern
!= NULL
)
224 no_leading_period
= end
.no_leading_period
;
230 /* If we come here no match is possible with the wildcard. */
235 /* Nonzero if the sense of the character class is inverted. */
236 const CHAR
*p_init
= p
;
237 const CHAR
*n_init
= n
;
242 if (posixly_correct
== 0)
243 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
248 if (*n
== L('.') && no_leading_period
)
251 if (*n
== L('/') && (flags
& FNM_FILE_NAME
))
252 /* `/' cannot be matched. */
255 not = (*p
== L('!') || (posixly_correct
< 0 && *p
== L('^')));
259 fn
= FOLD ((UCHAR
) *n
);
264 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
268 c
= FOLD ((UCHAR
) *p
);
273 else if (c
== L('[') && *p
== L(':'))
275 /* Leave room for the null. */
276 CHAR str
[CHAR_CLASS_MAX_LENGTH
+ 1];
278 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
281 const CHAR
*startp
= p
;
285 if (c1
== CHAR_CLASS_MAX_LENGTH
)
286 /* The name is too long and therefore the pattern
291 if (c
== L(':') && p
[1] == L(']'))
296 if (c
< L('a') || c
>= L('z'))
298 /* This cannot possibly be a character class name.
299 Match it as a normal range. */
308 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
309 wt
= IS_CHAR_CLASS (str
);
311 /* Invalid character class name. */
314 # if defined _LIBC && ! WIDE_CHAR_VERSION
315 /* The following code is glibc specific but does
316 there a good job in speeding up the code since
317 we can avoid the btowc() call. */
318 if (_ISCTYPE ((UCHAR
) *n
, wt
))
321 if (ISWCTYPE (BTOWC ((UCHAR
) *n
), wt
))
325 if ((STREQ (str
, L("alnum")) && ISALNUM ((UCHAR
) *n
))
326 || (STREQ (str
, L("alpha")) && ISALPHA ((UCHAR
) *n
))
327 || (STREQ (str
, L("blank")) && ISBLANK ((UCHAR
) *n
))
328 || (STREQ (str
, L("cntrl")) && ISCNTRL ((UCHAR
) *n
))
329 || (STREQ (str
, L("digit")) && ISDIGIT ((UCHAR
) *n
))
330 || (STREQ (str
, L("graph")) && ISGRAPH ((UCHAR
) *n
))
331 || (STREQ (str
, L("lower")) && ISLOWER ((UCHAR
) *n
))
332 || (STREQ (str
, L("print")) && ISPRINT ((UCHAR
) *n
))
333 || (STREQ (str
, L("punct")) && ISPUNCT ((UCHAR
) *n
))
334 || (STREQ (str
, L("space")) && ISSPACE ((UCHAR
) *n
))
335 || (STREQ (str
, L("upper")) && ISUPPER ((UCHAR
) *n
))
336 || (STREQ (str
, L("xdigit")) && ISXDIGIT ((UCHAR
) *n
)))
342 else if (c
== L('[') && *p
== L('='))
346 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
347 const CHAR
*startp
= p
;
359 if (c
!= L('=') || p
[1] != L(']'))
369 if ((UCHAR
) *n
== str
[0])
374 const int32_t *table
;
375 # if WIDE_CHAR_VERSION
376 const int32_t *weights
;
377 const int32_t *extra
;
379 const unsigned char *weights
;
380 const unsigned char *extra
;
382 const int32_t *indirect
;
384 const UCHAR
*cp
= (const UCHAR
*) str
;
386 /* This #include defines a local function! */
387 # if WIDE_CHAR_VERSION
388 # include <locale/weightwc.h>
390 # include <locale/weight.h>
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 int32_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 (&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 (&np
, string_end
- n
);
425 && (idx
>> 24) == (idx2
>> 24)
426 && len
== weights
[idx2
& 0xffffff])
434 && (weights
[idx
+ 1 + cnt
]
435 == weights
[idx2
+ 1 + cnt
]))
447 else if (c
== L('\0'))
449 /* [ unterminated, treat as normal character. */
462 if (c
== L('[') && *p
== L('.'))
465 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
466 const CHAR
*startp
= p
;
472 if (c
== L('.') && p
[1] == L(']'))
482 /* We have to handling the symbols differently in
483 ranges since then the collation sequence is
485 is_range
= *p
== L('-') && p
[1] != L('\0');
489 /* There are no names defined in the collation
490 data. Therefore we only accept the trivial
491 names consisting of the character itself. */
495 if (!is_range
&& *n
== startp
[1])
504 const int32_t *symb_table
;
505 # ifdef WIDE_CHAR_VERSION
509 # define str (startp + 1)
511 const unsigned char *extra
;
517 # ifdef WIDE_CHAR_VERSION
518 /* We have to convert the name to a single-byte
519 string. This is possible since the names
520 consist of ASCII characters and the internal
521 representation is UCS4. */
522 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
523 str
[strcnt
] = startp
[1 + strcnt
];
527 _NL_CURRENT_WORD (LC_COLLATE
,
528 _NL_COLLATE_SYMB_HASH_SIZEMB
);
529 symb_table
= (const int32_t *)
530 _NL_CURRENT (LC_COLLATE
,
531 _NL_COLLATE_SYMB_TABLEMB
);
532 extra
= (const unsigned char *)
533 _NL_CURRENT (LC_COLLATE
,
534 _NL_COLLATE_SYMB_EXTRAMB
);
536 /* Locate the character in the hashing table. */
537 hash
= elem_hash (str
, c1
);
540 elem
= hash
% table_size
;
541 if (symb_table
[2 * elem
] != 0)
543 second
= hash
% (table_size
- 2) + 1;
547 /* First compare the hashing value. */
548 if (symb_table
[2 * elem
] == hash
550 == extra
[symb_table
[2 * elem
+ 1]])
552 &extra
[symb_table
[2 * elem
556 /* Yep, this is the entry. */
557 idx
= symb_table
[2 * elem
+ 1];
558 idx
+= 1 + extra
[idx
];
565 while (symb_table
[2 * elem
] != 0);
568 if (symb_table
[2 * elem
] != 0)
570 /* Compare the byte sequence but only if
571 this is not part of a range. */
572 # ifdef WIDE_CHAR_VERSION
575 idx
+= 1 + extra
[idx
];
576 /* Adjust for the alignment. */
577 idx
= (idx
+ 3) & ~3;
579 wextra
= (int32_t *) &extra
[idx
+ 4];
584 # ifdef WIDE_CHAR_VERSION
586 (int32_t) c1
< wextra
[idx
];
588 if (n
[c1
] != wextra
[1 + c1
])
591 if ((int32_t) c1
== wextra
[idx
])
594 for (c1
= 0; c1
< extra
[idx
]; ++c1
)
595 if (n
[c1
] != extra
[1 + c1
])
598 if (c1
== extra
[idx
])
603 /* Get the collation sequence value. */
605 # ifdef WIDE_CHAR_VERSION
606 cold
= wextra
[1 + wextra
[idx
]];
608 /* Adjust for the alignment. */
609 idx
+= 1 + extra
[idx
];
610 idx
= (idx
+ 3) & ~4;
611 cold
= *((int32_t *) &extra
[idx
]);
618 /* No valid character. Match it as a
620 if (!is_range
&& *n
== str
[0])
637 /* We have to handling the symbols differently in
638 ranges since then the collation sequence is
640 is_range
= (*p
== L('-') && p
[1] != L('\0')
643 if (!is_range
&& c
== fn
)
646 /* This is needed if we goto normal_bracket; from
647 outside of is_seqval's scope. */
653 if (c
== L('-') && *p
!= L(']'))
656 /* We have to find the collation sequence
657 value for C. Collation sequence is nothing
658 we can regularly access. The sequence
659 value is defined by the order in which the
660 definitions of the collation values for the
661 various characters appear in the source
662 file. A strange concept, nowhere
668 # ifdef WIDE_CHAR_VERSION
669 /* Search in the `names' array for the characters. */
670 fcollseq
= __collseq_table_lookup (collseq
, fn
);
671 if (fcollseq
== ~((uint32_t) 0))
672 /* XXX We don't know anything about the character
673 we are supposed to match. This means we are
675 goto range_not_matched
;
680 lcollseq
= __collseq_table_lookup (collseq
, cold
);
682 fcollseq
= collseq
[fn
];
683 lcollseq
= is_seqval
? cold
: collseq
[(UCHAR
) cold
];
687 if (cend
== L('[') && *p
== L('.'))
690 _NL_CURRENT_WORD (LC_COLLATE
,
692 const CHAR
*startp
= p
;
698 if (c
== L('.') && p
[1] == L(']'))
710 /* There are no names defined in the
711 collation data. Therefore we only
712 accept the trivial names consisting
713 of the character itself. */
722 const int32_t *symb_table
;
723 # ifdef WIDE_CHAR_VERSION
727 # define str (startp + 1)
729 const unsigned char *extra
;
735 # ifdef WIDE_CHAR_VERSION
736 /* We have to convert the name to a single-byte
737 string. This is possible since the names
738 consist of ASCII characters and the internal
739 representation is UCS4. */
740 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
741 str
[strcnt
] = startp
[1 + strcnt
];
745 _NL_CURRENT_WORD (LC_COLLATE
,
746 _NL_COLLATE_SYMB_HASH_SIZEMB
);
747 symb_table
= (const int32_t *)
748 _NL_CURRENT (LC_COLLATE
,
749 _NL_COLLATE_SYMB_TABLEMB
);
750 extra
= (const unsigned char *)
751 _NL_CURRENT (LC_COLLATE
,
752 _NL_COLLATE_SYMB_EXTRAMB
);
754 /* Locate the character in the hashing
756 hash
= elem_hash (str
, c1
);
759 elem
= hash
% table_size
;
760 if (symb_table
[2 * elem
] != 0)
762 second
= hash
% (table_size
- 2) + 1;
766 /* First compare the hashing value. */
767 if (symb_table
[2 * elem
] == hash
769 == extra
[symb_table
[2 * elem
+ 1]])
771 &extra
[symb_table
[2 * elem
+ 1]
774 /* Yep, this is the entry. */
775 idx
= symb_table
[2 * elem
+ 1];
776 idx
+= 1 + extra
[idx
];
783 while (symb_table
[2 * elem
] != 0);
786 if (symb_table
[2 * elem
] != 0)
788 /* Compare the byte sequence but only if
789 this is not part of a range. */
790 # ifdef WIDE_CHAR_VERSION
793 idx
+= 1 + extra
[idx
];
794 /* Adjust for the alignment. */
795 idx
= (idx
+ 3) & ~4;
797 wextra
= (int32_t *) &extra
[idx
+ 4];
799 /* Get the collation sequence value. */
801 # ifdef WIDE_CHAR_VERSION
802 cend
= wextra
[1 + wextra
[idx
]];
804 /* Adjust for the alignment. */
805 idx
+= 1 + extra
[idx
];
806 idx
= (idx
+ 3) & ~4;
807 cend
= *((int32_t *) &extra
[idx
]);
810 else if (symb_table
[2 * elem
] != 0 && c1
== 1)
822 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
829 /* XXX It is not entirely clear to me how to handle
830 characters which are not mentioned in the
831 collation specification. */
833 # ifdef WIDE_CHAR_VERSION
834 lcollseq
== 0xffffffff ||
836 lcollseq
<= fcollseq
)
838 /* We have to look at the upper bound. */
845 # ifdef WIDE_CHAR_VERSION
847 __collseq_table_lookup (collseq
, cend
);
848 if (hcollseq
== ~((uint32_t) 0))
850 /* Hum, no information about the upper
851 bound. The matching succeeds if the
852 lower bound is matched exactly. */
853 if (lcollseq
!= fcollseq
)
854 goto range_not_matched
;
859 hcollseq
= collseq
[cend
];
863 if (lcollseq
<= hcollseq
&& fcollseq
<= hcollseq
)
866 # ifdef WIDE_CHAR_VERSION
870 /* We use a boring value comparison of the character
871 values. This is better than comparing using
872 `strcoll' since the latter would have surprising
873 and sometimes fatal consequences. */
876 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
882 if (cold
<= fn
&& fn
<= cend
)
899 /* Skip the rest of the [...] that already matched. */
906 /* [... (unterminated) loses. */
909 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
913 /* XXX 1003.2d11 is unclear if this is right. */
916 else if (c
== L('[') && *p
== L(':'))
919 const CHAR
*startp
= p
;
924 if (++c1
== CHAR_CLASS_MAX_LENGTH
)
927 if (*p
== L(':') && p
[1] == L(']'))
930 if (c
< L('a') || c
>= L('z'))
939 else if (c
== L('[') && *p
== L('='))
945 if (c
!= L('=') || p
[1] != L(']'))
950 else if (c
== L('[') && *p
== L('.'))
959 if (*p
== L('.') && p
[1] == L(']'))
975 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
977 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
, flags
,
985 if (NO_LEADING_PERIOD (flags
))
987 if (n
== string_end
|| c
!= (UCHAR
) *n
)
990 new_no_leading_period
= 1;
996 if (n
== string_end
|| c
!= FOLD ((UCHAR
) *n
))
1000 no_leading_period
= new_no_leading_period
;
1004 if (n
== string_end
)
1007 if ((flags
& FNM_LEADING_DIR
) && n
!= string_end
&& *n
== L('/'))
1008 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
1017 END (const CHAR
*pattern
)
1019 const CHAR
*p
= pattern
;
1022 if (*++p
== L('\0'))
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('('))
1047 else if (*p
== L(')'))
1056 EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
1057 int no_leading_period
, int flags
, size_t alloca_used
)
1063 struct patternlist
*next
;
1067 struct patternlist
**lastp
= &list
;
1068 size_t pattern_len
= STRLEN (pattern
);
1069 int any_malloced
= 0;
1074 /* Parse the pattern. Store the individual parts in the list. */
1076 for (startp
= p
= pattern
+ 1; level
>= 0; ++p
)
1079 /* This is an invalid pattern. */
1083 else if (*p
== L('['))
1085 /* Handle brackets special. */
1086 if (posixly_correct
== 0)
1087 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1089 /* Skip the not sign. We have to recognize it because of a possibly
1091 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1093 /* A leading ']' is recognized as such. */
1096 /* Skip over all characters of the list. */
1097 while (*p
!= L(']'))
1098 if (*p
++ == L('\0'))
1100 /* This is no valid pattern. */
1105 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1106 || *p
== L('!')) && p
[1] == L('('))
1107 /* Remember the nesting level. */
1109 else if (*p
== L(')'))
1113 /* This means we found the end of the pattern. */
1114 #define NEW_PATTERN \
1115 struct patternlist *newp; \
1116 size_t slen = (opt == L('?') || opt == L('@') \
1117 ? pattern_len : (p - startp + 1)); \
1118 slen = sizeof (struct patternlist) + (slen * sizeof (CHAR)); \
1119 int malloced = ! __libc_use_alloca (alloca_used + slen); \
1120 if (__builtin_expect (malloced, 0)) \
1122 newp = malloc (slen); \
1131 newp = alloca_account (slen, alloca_used); \
1132 newp->next = NULL; \
1133 newp->malloced = malloced; \
1134 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1140 else if (*p
== L('|'))
1148 assert (list
!= NULL
);
1149 assert (p
[-1] == L(')'));
1155 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1163 for (rs
= string
; rs
<= string_end
; ++rs
)
1164 /* First match the prefix with the current pattern with the
1166 if (FCT (list
->str
, string
, rs
, no_leading_period
,
1167 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1168 NULL
, alloca_used
) == 0
1169 /* This was successful. Now match the rest with the rest
1171 && (FCT (p
, rs
, string_end
,
1174 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1175 flags
& FNM_FILE_NAME
1176 ? flags
: flags
& ~FNM_PERIOD
, NULL
, alloca_used
) == 0
1177 /* This didn't work. Try the whole pattern. */
1179 && FCT (pattern
- 1, rs
, string_end
,
1182 : (rs
[-1] == '/' && NO_LEADING_PERIOD (flags
)
1184 flags
& FNM_FILE_NAME
1185 ? flags
: flags
& ~FNM_PERIOD
, NULL
,
1186 alloca_used
) == 0)))
1187 /* It worked. Signal success. */
1190 while ((list
= list
->next
) != NULL
);
1192 /* None of the patterns lead to a match. */
1193 retval
= FNM_NOMATCH
;
1197 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1204 /* I cannot believe it but `strcat' is actually acceptable
1205 here. Match the entire string with the prefix from the
1206 pattern list and the rest of the pattern following the
1208 if (FCT (STRCAT (list
->str
, p
), string
, string_end
,
1210 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1211 NULL
, alloca_used
) == 0)
1212 /* It worked. Signal success. */
1214 while ((list
= list
->next
) != NULL
);
1216 /* None of the patterns lead to a match. */
1217 retval
= FNM_NOMATCH
;
1221 for (rs
= string
; rs
<= string_end
; ++rs
)
1223 struct patternlist
*runp
;
1225 for (runp
= list
; runp
!= NULL
; runp
= runp
->next
)
1226 if (FCT (runp
->str
, string
, rs
, no_leading_period
,
1227 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1228 NULL
, alloca_used
) == 0)
1231 /* If none of the patterns matched see whether the rest does. */
1233 && (FCT (p
, rs
, string_end
,
1236 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1237 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1238 NULL
, alloca_used
) == 0))
1239 /* This is successful. */
1243 /* None of the patterns together with the rest of the pattern
1245 retval
= FNM_NOMATCH
;
1249 assert (! "Invalid extended matching operator");
1257 while (list
!= NULL
)
1259 struct patternlist
*old
= list
;