1 /* Copyright (C) 1991-1993,1996-2001,2003-2005,2007,2010
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
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 register 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. */
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
);
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
);
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'))
448 /* [ (unterminated) loses. */
457 if (c
== L('[') && *p
== L('.'))
460 _NL_CURRENT_WORD (LC_COLLATE
, _NL_COLLATE_NRULES
);
461 const CHAR
*startp
= p
;
467 if (c
== L('.') && p
[1] == L(']'))
477 /* We have to handling the symbols differently in
478 ranges since then the collation sequence is
480 is_range
= *p
== L('-') && p
[1] != L('\0');
484 /* There are no names defined in the collation
485 data. Therefore we only accept the trivial
486 names consisting of the character itself. */
490 if (!is_range
&& *n
== startp
[1])
499 const int32_t *symb_table
;
500 # ifdef WIDE_CHAR_VERSION
504 # define str (startp + 1)
506 const unsigned char *extra
;
512 # ifdef WIDE_CHAR_VERSION
513 /* We have to convert the name to a single-byte
514 string. This is possible since the names
515 consist of ASCII characters and the internal
516 representation is UCS4. */
517 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
518 str
[strcnt
] = startp
[1 + strcnt
];
522 _NL_CURRENT_WORD (LC_COLLATE
,
523 _NL_COLLATE_SYMB_HASH_SIZEMB
);
524 symb_table
= (const int32_t *)
525 _NL_CURRENT (LC_COLLATE
,
526 _NL_COLLATE_SYMB_TABLEMB
);
527 extra
= (const unsigned char *)
528 _NL_CURRENT (LC_COLLATE
,
529 _NL_COLLATE_SYMB_EXTRAMB
);
531 /* Locate the character in the hashing table. */
532 hash
= elem_hash (str
, c1
);
535 elem
= hash
% table_size
;
536 if (symb_table
[2 * elem
] != 0)
538 second
= hash
% (table_size
- 2) + 1;
542 /* First compare the hashing value. */
543 if (symb_table
[2 * elem
] == hash
545 == extra
[symb_table
[2 * elem
+ 1]])
547 &extra
[symb_table
[2 * elem
551 /* Yep, this is the entry. */
552 idx
= symb_table
[2 * elem
+ 1];
553 idx
+= 1 + extra
[idx
];
560 while (symb_table
[2 * elem
] != 0);
563 if (symb_table
[2 * elem
] != 0)
565 /* Compare the byte sequence but only if
566 this is not part of a range. */
567 # ifdef WIDE_CHAR_VERSION
570 idx
+= 1 + extra
[idx
];
571 /* Adjust for the alignment. */
572 idx
= (idx
+ 3) & ~3;
574 wextra
= (int32_t *) &extra
[idx
+ 4];
579 # ifdef WIDE_CHAR_VERSION
581 (int32_t) c1
< wextra
[idx
];
583 if (n
[c1
] != wextra
[1 + c1
])
586 if ((int32_t) c1
== wextra
[idx
])
589 for (c1
= 0; c1
< extra
[idx
]; ++c1
)
590 if (n
[c1
] != extra
[1 + c1
])
593 if (c1
== extra
[idx
])
598 /* Get the collation sequence value. */
600 # ifdef WIDE_CHAR_VERSION
601 cold
= wextra
[1 + wextra
[idx
]];
603 /* Adjust for the alignment. */
604 idx
+= 1 + extra
[idx
];
605 idx
= (idx
+ 3) & ~4;
606 cold
= *((int32_t *) &extra
[idx
]);
613 /* No valid character. Match it as a
615 if (!is_range
&& *n
== str
[0])
632 /* We have to handling the symbols differently in
633 ranges since then the collation sequence is
635 is_range
= (*p
== L('-') && p
[1] != L('\0')
638 if (!is_range
&& c
== fn
)
641 /* This is needed if we goto normal_bracket; from
642 outside of is_seqval's scope. */
648 if (c
== L('-') && *p
!= L(']'))
651 /* We have to find the collation sequence
652 value for C. Collation sequence is nothing
653 we can regularly access. The sequence
654 value is defined by the order in which the
655 definitions of the collation values for the
656 various characters appear in the source
657 file. A strange concept, nowhere
663 # ifdef WIDE_CHAR_VERSION
664 /* Search in the `names' array for the characters. */
665 fcollseq
= __collseq_table_lookup (collseq
, fn
);
666 if (fcollseq
== ~((uint32_t) 0))
667 /* XXX We don't know anything about the character
668 we are supposed to match. This means we are
670 goto range_not_matched
;
675 lcollseq
= __collseq_table_lookup (collseq
, cold
);
677 fcollseq
= collseq
[fn
];
678 lcollseq
= is_seqval
? cold
: collseq
[(UCHAR
) cold
];
682 if (cend
== L('[') && *p
== L('.'))
685 _NL_CURRENT_WORD (LC_COLLATE
,
687 const CHAR
*startp
= p
;
693 if (c
== L('.') && p
[1] == L(']'))
705 /* There are no names defined in the
706 collation data. Therefore we only
707 accept the trivial names consisting
708 of the character itself. */
717 const int32_t *symb_table
;
718 # ifdef WIDE_CHAR_VERSION
722 # define str (startp + 1)
724 const unsigned char *extra
;
730 # ifdef WIDE_CHAR_VERSION
731 /* We have to convert the name to a single-byte
732 string. This is possible since the names
733 consist of ASCII characters and the internal
734 representation is UCS4. */
735 for (strcnt
= 0; strcnt
< c1
; ++strcnt
)
736 str
[strcnt
] = startp
[1 + strcnt
];
740 _NL_CURRENT_WORD (LC_COLLATE
,
741 _NL_COLLATE_SYMB_HASH_SIZEMB
);
742 symb_table
= (const int32_t *)
743 _NL_CURRENT (LC_COLLATE
,
744 _NL_COLLATE_SYMB_TABLEMB
);
745 extra
= (const unsigned char *)
746 _NL_CURRENT (LC_COLLATE
,
747 _NL_COLLATE_SYMB_EXTRAMB
);
749 /* Locate the character in the hashing
751 hash
= elem_hash (str
, c1
);
754 elem
= hash
% table_size
;
755 if (symb_table
[2 * elem
] != 0)
757 second
= hash
% (table_size
- 2) + 1;
761 /* First compare the hashing value. */
762 if (symb_table
[2 * elem
] == hash
764 == extra
[symb_table
[2 * elem
+ 1]])
766 &extra
[symb_table
[2 * elem
+ 1]
769 /* Yep, this is the entry. */
770 idx
= symb_table
[2 * elem
+ 1];
771 idx
+= 1 + extra
[idx
];
778 while (symb_table
[2 * elem
] != 0);
781 if (symb_table
[2 * elem
] != 0)
783 /* Compare the byte sequence but only if
784 this is not part of a range. */
785 # ifdef WIDE_CHAR_VERSION
788 idx
+= 1 + extra
[idx
];
789 /* Adjust for the alignment. */
790 idx
= (idx
+ 3) & ~4;
792 wextra
= (int32_t *) &extra
[idx
+ 4];
794 /* Get the collation sequence value. */
796 # ifdef WIDE_CHAR_VERSION
797 cend
= wextra
[1 + wextra
[idx
]];
799 /* Adjust for the alignment. */
800 idx
+= 1 + extra
[idx
];
801 idx
= (idx
+ 3) & ~4;
802 cend
= *((int32_t *) &extra
[idx
]);
805 else if (symb_table
[2 * elem
] != 0 && c1
== 1)
817 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
824 /* XXX It is not entirely clear to me how to handle
825 characters which are not mentioned in the
826 collation specification. */
828 # ifdef WIDE_CHAR_VERSION
829 lcollseq
== 0xffffffff ||
831 lcollseq
<= fcollseq
)
833 /* We have to look at the upper bound. */
840 # ifdef WIDE_CHAR_VERSION
842 __collseq_table_lookup (collseq
, cend
);
843 if (hcollseq
== ~((uint32_t) 0))
845 /* Hum, no information about the upper
846 bound. The matching succeeds if the
847 lower bound is matched exactly. */
848 if (lcollseq
!= fcollseq
)
849 goto range_not_matched
;
854 hcollseq
= collseq
[cend
];
858 if (lcollseq
<= hcollseq
&& fcollseq
<= hcollseq
)
861 # ifdef WIDE_CHAR_VERSION
865 /* We use a boring value comparison of the character
866 values. This is better than comparing using
867 `strcoll' since the latter would have surprising
868 and sometimes fatal consequences. */
871 if (!(flags
& FNM_NOESCAPE
) && cend
== L('\\'))
877 if (cold
<= fn
&& fn
<= cend
)
894 /* Skip the rest of the [...] that already matched. */
901 /* [... (unterminated) loses. */
904 if (!(flags
& FNM_NOESCAPE
) && c
== L('\\'))
908 /* XXX 1003.2d11 is unclear if this is right. */
911 else if (c
== L('[') && *p
== L(':'))
914 const CHAR
*startp
= p
;
919 if (++c1
== CHAR_CLASS_MAX_LENGTH
)
922 if (*p
== L(':') && p
[1] == L(']'))
925 if (c
< L('a') || c
>= L('z'))
934 else if (c
== L('[') && *p
== L('='))
940 if (c
!= L('=') || p
[1] != L(']'))
945 else if (c
== L('[') && *p
== L('.'))
954 if (*p
== L('.') && p
[1] == L(']'))
970 if (__builtin_expect (flags
& FNM_EXTMATCH
, 0) && *p
== '(')
972 int res
= EXT (c
, p
, n
, string_end
, no_leading_period
, flags
,
980 if (NO_LEADING_PERIOD (flags
))
982 if (n
== string_end
|| c
!= (UCHAR
) *n
)
985 new_no_leading_period
= 1;
991 if (n
== string_end
|| c
!= FOLD ((UCHAR
) *n
))
995 no_leading_period
= new_no_leading_period
;
1002 if ((flags
& FNM_LEADING_DIR
) && n
!= string_end
&& *n
== L('/'))
1003 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
1012 END (const CHAR
*pattern
)
1014 const CHAR
*p
= pattern
;
1017 if (*++p
== L('\0'))
1018 /* This is an invalid pattern. */
1020 else if (*p
== L('['))
1022 /* Handle brackets special. */
1023 if (posixly_correct
== 0)
1024 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1026 /* Skip the not sign. We have to recognize it because of a possibly
1028 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1030 /* A leading ']' is recognized as such. */
1033 /* Skip over all characters of the list. */
1034 while (*p
!= L(']'))
1035 if (*p
++ == L('\0'))
1036 /* This is no valid pattern. */
1039 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1040 || *p
== L('!')) && p
[1] == L('('))
1042 else if (*p
== L(')'))
1051 EXT (INT opt
, const CHAR
*pattern
, const CHAR
*string
, const CHAR
*string_end
,
1052 int no_leading_period
, int flags
, size_t alloca_used
)
1058 struct patternlist
*next
;
1062 struct patternlist
**lastp
= &list
;
1063 size_t pattern_len
= STRLEN (pattern
);
1064 int any_malloced
= 0;
1069 /* Parse the pattern. Store the individual parts in the list. */
1071 for (startp
= p
= pattern
+ 1; level
>= 0; ++p
)
1074 /* This is an invalid pattern. */
1078 else if (*p
== L('['))
1080 /* Handle brackets special. */
1081 if (posixly_correct
== 0)
1082 posixly_correct
= getenv ("POSIXLY_CORRECT") != NULL
? 1 : -1;
1084 /* Skip the not sign. We have to recognize it because of a possibly
1086 if (*++p
== L('!') || (posixly_correct
< 0 && *p
== L('^')))
1088 /* A leading ']' is recognized as such. */
1091 /* Skip over all characters of the list. */
1092 while (*p
!= L(']'))
1093 if (*p
++ == L('\0'))
1095 /* This is no valid pattern. */
1100 else if ((*p
== L('?') || *p
== L('*') || *p
== L('+') || *p
== L('@')
1101 || *p
== L('!')) && p
[1] == L('('))
1102 /* Remember the nesting level. */
1104 else if (*p
== L(')'))
1108 /* This means we found the end of the pattern. */
1109 #define NEW_PATTERN \
1110 struct patternlist *newp; \
1111 size_t slen = (opt == L('?') || opt == L('@') \
1112 ? pattern_len : (p - startp + 1)); \
1113 slen = sizeof (struct patternlist) + (slen * sizeof (CHAR)); \
1114 int malloced = ! __libc_use_alloca (alloca_used + slen); \
1115 if (__builtin_expect (malloced, 0)) \
1117 newp = malloc (slen); \
1126 newp = alloca_account (slen, alloca_used); \
1127 newp->next = NULL; \
1128 newp->malloced = malloced; \
1129 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1135 else if (*p
== L('|'))
1143 assert (list
!= NULL
);
1144 assert (p
[-1] == L(')'));
1150 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1158 for (rs
= string
; rs
<= string_end
; ++rs
)
1159 /* First match the prefix with the current pattern with the
1161 if (FCT (list
->str
, string
, rs
, no_leading_period
,
1162 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1163 NULL
, alloca_used
) == 0
1164 /* This was successful. Now match the rest with the rest
1166 && (FCT (p
, rs
, string_end
,
1169 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1170 flags
& FNM_FILE_NAME
1171 ? flags
: flags
& ~FNM_PERIOD
, NULL
, alloca_used
) == 0
1172 /* This didn't work. Try the whole pattern. */
1174 && FCT (pattern
- 1, rs
, string_end
,
1177 : (rs
[-1] == '/' && NO_LEADING_PERIOD (flags
)
1179 flags
& FNM_FILE_NAME
1180 ? flags
: flags
& ~FNM_PERIOD
, NULL
,
1181 alloca_used
) == 0)))
1182 /* It worked. Signal success. */
1185 while ((list
= list
->next
) != NULL
);
1187 /* None of the patterns lead to a match. */
1188 retval
= FNM_NOMATCH
;
1192 if (FCT (p
, string
, string_end
, no_leading_period
, flags
, NULL
,
1199 /* I cannot believe it but `strcat' is actually acceptable
1200 here. Match the entire string with the prefix from the
1201 pattern list and the rest of the pattern following the
1203 if (FCT (STRCAT (list
->str
, p
), string
, string_end
,
1205 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1206 NULL
, alloca_used
) == 0)
1207 /* It worked. Signal success. */
1209 while ((list
= list
->next
) != NULL
);
1211 /* None of the patterns lead to a match. */
1212 retval
= FNM_NOMATCH
;
1216 for (rs
= string
; rs
<= string_end
; ++rs
)
1218 struct patternlist
*runp
;
1220 for (runp
= list
; runp
!= NULL
; runp
= runp
->next
)
1221 if (FCT (runp
->str
, string
, rs
, no_leading_period
,
1222 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1223 NULL
, alloca_used
) == 0)
1226 /* If none of the patterns matched see whether the rest does. */
1228 && (FCT (p
, rs
, string_end
,
1231 : rs
[-1] == '/' && NO_LEADING_PERIOD (flags
) ? 1 : 0,
1232 flags
& FNM_FILE_NAME
? flags
: flags
& ~FNM_PERIOD
,
1233 NULL
, alloca_used
) == 0))
1234 /* This is successful. */
1238 /* None of the patterns together with the rest of the pattern
1240 retval
= FNM_NOMATCH
;
1244 assert (! "Invalid extended matching operator");
1252 while (list
!= NULL
)
1254 struct patternlist
*old
= list
;