X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ffnmatch_loop.c;h=d1008c247df2a8553bd9ee5f663c86aa76d7b58d;hb=810a812bee90d6bab12e9628dc7745eea49f188c;hp=a83dd96169e6c627ab1144d18d4a6108df4a46c6;hpb=23adca690664e60bd61bd4bacbe987863a3b7327;p=gnulib.git diff --git a/lib/fnmatch_loop.c b/lib/fnmatch_loop.c index a83dd9616..d1008c247 100644 --- a/lib/fnmatch_loop.c +++ b/lib/fnmatch_loop.c @@ -1,5 +1,6 @@ -/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,19 +14,19 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* Match STRING against the filename pattern PATTERN, returning zero if +/* Match STRING against the file name pattern PATTERN, returning zero if it matches, nonzero if not. */ static int EXT (INT opt, const CHAR *pattern, const CHAR *string, - const CHAR *string_end, int no_leading_period, int flags) + const CHAR *string_end, bool no_leading_period, int flags) internal_function; static const CHAR *END (const CHAR *patternp) internal_function; static int internal_function FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, - int no_leading_period, int flags) + bool no_leading_period, int flags) { register const CHAR *p = pattern, *n = string; register UCHAR c; @@ -39,14 +40,14 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, # endif #endif - while ((c = *p++) != L('\0')) + while ((c = *p++) != L_('\0')) { - int new_no_leading_period = 0; + bool new_no_leading_period = false; c = FOLD (c); switch (c) { - case L('?'): + case L_('?'): if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { int res; @@ -59,17 +60,17 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (n == string_end) return FNM_NOMATCH; - else if (*n == L('/') && (flags & FNM_FILE_NAME)) + else if (*n == L_('/') && (flags & FNM_FILE_NAME)) return FNM_NOMATCH; - else if (*n == L('.') && no_leading_period) + else if (*n == L_('.') && no_leading_period) return FNM_NOMATCH; break; - case L('\\'): + case L_('\\'): if (!(flags & FNM_NOESCAPE)) { c = *p++; - if (c == L('\0')) + if (c == L_('\0')) /* Trailing \ loses. */ return FNM_NOMATCH; c = FOLD (c); @@ -78,7 +79,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, return FNM_NOMATCH; break; - case L('*'): + case L_('*'): if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { int res; @@ -89,12 +90,12 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, return res; } - if (n != string_end && *n == L('.') && no_leading_period) + if (n != string_end && *n == L_('.') && no_leading_period) return FNM_NOMATCH; - for (c = *p++; c == L('?') || c == L('*'); c = *p++) + for (c = *p++; c == L_('?') || c == L_('*'); c = *p++) { - if (*p == L('(') && (flags & FNM_EXTMATCH) != 0) + if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0) { const CHAR *endp = END (p); if (endp != p) @@ -105,13 +106,13 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, } } - if (c == L('?')) + if (c == L_('?')) { /* A ? needs to match one character. */ if (n == string_end) /* There isn't another character; no match. */ return FNM_NOMATCH; - else if (*n == L('/') + else if (*n == L_('/') && __builtin_expect (flags & FNM_FILE_NAME, 0)) /* A slash does not match a wildcard under FNM_FILE_NAME. */ @@ -124,7 +125,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, } } - if (c == L('\0')) + if (c == L_('\0')) /* The wildcard(s) is/are the last element of the pattern. If the name is a file name and contains another slash this means it cannot match, unless the FNM_LEADING_DIR @@ -138,7 +139,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, result = 0; else { - if (MEMCHR (n, L('/'), string_end - n) == NULL) + if (MEMCHR (n, L_('/'), string_end - n) == NULL) result = 0; } } @@ -149,30 +150,30 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, { const CHAR *endp; - endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L('/') : L('\0'), + endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'), string_end - n); if (endp == NULL) endp = string_end; - if (c == L('[') + if (c == L_('[') || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0 - && (c == L('@') || c == L('+') || c == L('!')) - && *p == L('('))) + && (c == L_('@') || c == L_('+') || c == L_('!')) + && *p == L_('('))) { int flags2 = ((flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD)); - int no_leading_period2 = no_leading_period; + bool no_leading_period2 = no_leading_period; - for (--p; n < endp; ++n, no_leading_period2 = 0) + for (--p; n < endp; ++n, no_leading_period2 = false) if (FCT (p, n, string_end, no_leading_period2, flags2) == 0) return 0; } - else if (c == L('/') && (flags & FNM_FILE_NAME)) + else if (c == L_('/') && (flags & FNM_FILE_NAME)) { - while (n < string_end && *n != L('/')) + while (n < string_end && *n != L_('/')) ++n; - if (n < string_end && *n == L('/') + if (n < string_end && *n == L_('/') && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags) == 0)) return 0; @@ -183,10 +184,10 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, ? flags : (flags & ~FNM_PERIOD)); int no_leading_period2 = no_leading_period; - if (c == L('\\') && !(flags & FNM_NOESCAPE)) + if (c == L_('\\') && !(flags & FNM_NOESCAPE)) c = *p; c = FOLD (c); - for (--p; n < endp; ++n, no_leading_period2 = 0) + for (--p; n < endp; ++n, no_leading_period2 = false) if (FOLD ((UCHAR) *n) == c && (FCT (p, n, string_end, no_leading_period2, flags2) == 0)) @@ -197,10 +198,10 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, /* If we come here no match is possible with the wildcard. */ return FNM_NOMATCH; - case L('['): + case L_('['): { /* Nonzero if the sense of the character class is inverted. */ - register int not; + register bool not; CHAR cold; UCHAR fn; @@ -210,14 +211,14 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (n == string_end) return FNM_NOMATCH; - if (*n == L('.') && no_leading_period) + if (*n == L_('.') && no_leading_period) return FNM_NOMATCH; - if (*n == L('/') && (flags & FNM_FILE_NAME)) + if (*n == L_('/') && (flags & FNM_FILE_NAME)) /* `/' cannot be matched. */ return FNM_NOMATCH; - not = (*p == L('!') || (posixly_correct < 0 && *p == L('^'))); + not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^'))); if (not) ++p; @@ -226,17 +227,16 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, c = *p++; for (;;) { - if (!(flags & FNM_NOESCAPE) && c == L('\\')) + if (!(flags & FNM_NOESCAPE) && c == L_('\\')) { - if (*p == L('\0')) + if (*p == L_('\0')) return FNM_NOMATCH; c = FOLD ((UCHAR) *p); ++p; - if (c == fn) - goto matched; + goto normal_bracket; } - else if (c == L('[') && *p == L(':')) + else if (c == L_('[') && *p == L_(':')) { /* Leave room for the null. */ CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; @@ -254,22 +254,22 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, return FNM_NOMATCH; c = *++p; - if (c == L(':') && p[1] == L(']')) + if (c == L_(':') && p[1] == L_(']')) { p += 2; break; } - if (c < L('a') || c >= L('z')) + if (c < L_('a') || c >= L_('z')) { /* This cannot possibly be a character class name. Match it as a normal range. */ p = startp; - c = L('['); + c = L_('['); goto normal_bracket; } str[c1++] = c; } - str[c1] = L('\0'); + str[c1] = L_('\0'); #if defined _LIBC || WIDE_CHAR_SUPPORT wt = IS_CHAR_CLASS (str); @@ -288,24 +288,24 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, goto matched; # endif #else - if ((STREQ (str, L("alnum")) && ISALNUM ((UCHAR) *n)) - || (STREQ (str, L("alpha")) && ISALPHA ((UCHAR) *n)) - || (STREQ (str, L("blank")) && ISBLANK ((UCHAR) *n)) - || (STREQ (str, L("cntrl")) && ISCNTRL ((UCHAR) *n)) - || (STREQ (str, L("digit")) && ISDIGIT ((UCHAR) *n)) - || (STREQ (str, L("graph")) && ISGRAPH ((UCHAR) *n)) - || (STREQ (str, L("lower")) && ISLOWER ((UCHAR) *n)) - || (STREQ (str, L("print")) && ISPRINT ((UCHAR) *n)) - || (STREQ (str, L("punct")) && ISPUNCT ((UCHAR) *n)) - || (STREQ (str, L("space")) && ISSPACE ((UCHAR) *n)) - || (STREQ (str, L("upper")) && ISUPPER ((UCHAR) *n)) - || (STREQ (str, L("xdigit")) && ISXDIGIT ((UCHAR) *n))) + if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n)) + || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n)) + || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n)) + || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n)) + || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n)) + || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n)) + || (STREQ (str, L_("lower")) && islower ((UCHAR) *n)) + || (STREQ (str, L_("print")) && isprint ((UCHAR) *n)) + || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n)) + || (STREQ (str, L_("space")) && isspace ((UCHAR) *n)) + || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n)) + || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n))) goto matched; #endif c = *p++; } #ifdef _LIBC - else if (c == L('[') && *p == L('=')) + else if (c == L_('[') && *p == L_('=')) { UCHAR str[1]; uint32_t nrules = @@ -313,19 +313,19 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, const CHAR *startp = p; c = *++p; - if (c == L('\0')) + if (c == L_('\0')) { p = startp; - c = L('['); + c = L_('['); goto normal_bracket; } str[0] = c; c = *++p; - if (c != L('=') || p[1] != L(']')) + if (c != L_('=') || p[1] != L_(']')) { p = startp; - c = L('['); + c = L_('['); goto normal_bracket; } p += 2; @@ -405,17 +405,17 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, c = *p++; } #endif - else if (c == L('\0')) + else if (c == L_('\0')) /* [ (unterminated) loses. */ return FNM_NOMATCH; else { - int is_range = 0; + bool is_range = false; #ifdef _LIBC - int is_seqval = 0; + bool is_seqval = false; - if (c == L('[') && *p == L('.')) + if (c == L_('[') && *p == L_('.')) { uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); @@ -425,7 +425,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, while (1) { c = *++p; - if (c == L('.') && p[1] == L(']')) + if (c == L_('.') && p[1] == L_(']')) { p += 2; break; @@ -438,7 +438,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, /* We have to handling the symbols differently in ranges since then the collation sequence is important. */ - is_range = *p == L('-') && p[1] != L('\0'); + is_range = *p == L_('-') && p[1] != L_('\0'); if (nrules == 0) { @@ -460,7 +460,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, const int32_t *symb_table; # ifdef WIDE_CHAR_VERSION char str[c1]; - unsigned int strcnt; + size_t strcnt; # else # define str (startp + 1) # endif @@ -494,24 +494,31 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, idx = 0; elem = hash % table_size; - second = hash % (table_size - 2); - while (symb_table[2 * elem] != 0) + if (symb_table[2 * elem] != 0) { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - && c1 == extra[symb_table[2 * elem + 1]] - && memcmp (str, - &extra[symb_table[2 * elem + 1] - + 1], c1) == 0) + second = hash % (table_size - 2) + 1; + + do { - /* Yep, this is the entry. */ - idx = symb_table[2 * elem + 1]; - idx += 1 + extra[idx]; - break; - } + /* First compare the hashing value. */ + if (symb_table[2 * elem] == hash + && (c1 + == extra[symb_table[2 * elem + 1]]) + && memcmp (str, + &extra[symb_table[2 * elem + + 1] + + 1], c1) == 0) + { + /* Yep, this is the entry. */ + idx = symb_table[2 * elem + 1]; + idx += 1 + extra[idx]; + break; + } - /* Next entry. */ - elem += second; + /* Next entry. */ + elem += second; + } + while (symb_table[2 * elem] != 0); } if (symb_table[2 * elem] != 0) @@ -531,11 +538,13 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (! is_range) { # ifdef WIDE_CHAR_VERSION - for (c1 = 0; c1 < wextra[idx]; ++c1) + for (c1 = 0; + (int32_t) c1 < wextra[idx]; + ++c1) if (n[c1] != wextra[1 + c1]) break; - if (c1 == wextra[idx]) + if ((int32_t) c1 == wextra[idx]) goto matched; # else for (c1 = 0; c1 < extra[idx]; ++c1) @@ -548,7 +557,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, } /* Get the collation sequence value. */ - is_seqval = 1; + is_seqval = true; # ifdef WIDE_CHAR_VERSION cold = wextra[1 + wextra[idx]]; # else @@ -584,17 +593,23 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, /* We have to handling the symbols differently in ranges since then the collation sequence is important. */ - is_range = (*p == L('-') && p[1] != L('\0') - && p[1] != L(']')); + is_range = (*p == L_('-') && p[1] != L_('\0') + && p[1] != L_(']')); if (!is_range && c == fn) goto matched; +#if _LIBC + /* This is needed if we goto normal_bracket; from + outside of is_seqval's scope. */ + is_seqval = false; +#endif + cold = c; c = *p++; } - if (c == L('-') && *p != L(']')) + if (c == L_('-') && *p != L_(']')) { #if _LIBC /* We have to find the collation sequence @@ -611,7 +626,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, # ifdef WIDE_CHAR_VERSION /* Search in the `names' array for the characters. */ - fcollseq = collseq_table_lookup (collseq, fn); + fcollseq = __collseq_table_lookup (collseq, fn); if (fcollseq == ~((uint32_t) 0)) /* XXX We don't know anything about the character we are supposed to match. This means we are @@ -621,14 +636,14 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (is_seqval) lcollseq = cold; else - lcollseq = collseq_table_lookup (collseq, cold); + lcollseq = __collseq_table_lookup (collseq, cold); # else fcollseq = collseq[fn]; lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; # endif - is_seqval = 0; - if (cend == L('[') && *p == L('.')) + is_seqval = false; + if (cend == L_('[') && *p == L_('.')) { uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, @@ -639,7 +654,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, while (1) { c = *++p; - if (c == L('.') && p[1] == L(']')) + if (c == L_('.') && p[1] == L_(']')) { p += 2; break; @@ -666,7 +681,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, const int32_t *symb_table; # ifdef WIDE_CHAR_VERSION char str[c1]; - unsigned int strcnt; + size_t strcnt; # else # define str (startp + 1) # endif @@ -701,25 +716,30 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, idx = 0; elem = hash % table_size; - second = hash % (table_size - 2); - while (symb_table[2 * elem] != 0) + if (symb_table[2 * elem] != 0) { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - && (c1 - == extra[symb_table[2 * elem + 1]]) - && memcmp (str, - &extra[symb_table[2 * elem + 1] - + 1], c1) == 0) + second = hash % (table_size - 2) + 1; + + do { - /* Yep, this is the entry. */ - idx = symb_table[2 * elem + 1]; - idx += 1 + extra[idx]; - break; + /* First compare the hashing value. */ + if (symb_table[2 * elem] == hash + && (c1 + == extra[symb_table[2 * elem + 1]]) + && memcmp (str, + &extra[symb_table[2 * elem + 1] + + 1], c1) == 0) + { + /* Yep, this is the entry. */ + idx = symb_table[2 * elem + 1]; + idx += 1 + extra[idx]; + break; + } + + /* Next entry. */ + elem += second; } - - /* Next entry. */ - elem += second; + while (symb_table[2 * elem] != 0); } if (symb_table[2 * elem] != 0) @@ -736,7 +756,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, wextra = (int32_t *) &extra[idx + 4]; # endif /* Get the collation sequence value. */ - is_seqval = 1; + is_seqval = true; # ifdef WIDE_CHAR_VERSION cend = wextra[1 + wextra[idx]]; # else @@ -758,9 +778,9 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, } else { - if (!(flags & FNM_NOESCAPE) && cend == L('\\')) + if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) cend = *p++; - if (cend == L('\0')) + if (cend == L_('\0')) return FNM_NOMATCH; cend = FOLD (cend); } @@ -783,7 +803,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, { # ifdef WIDE_CHAR_VERSION hcollseq = - collseq_table_lookup (collseq, cend); + __collseq_table_lookup (collseq, cend); if (hcollseq == ~((uint32_t) 0)) { /* Hum, no information about the upper @@ -812,9 +832,9 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, and sometimes fatal consequences. */ UCHAR cend = *p++; - if (!(flags & FNM_NOESCAPE) && cend == L('\\')) + if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) cend = *p++; - if (cend == L('\0')) + if (cend == L_('\0')) return FNM_NOMATCH; /* It is a range. */ @@ -826,7 +846,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, } } - if (c == L(']')) + if (c == L_(']')) break; } @@ -841,18 +861,18 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, ignore_next: c = *p++; - if (c == L('\0')) + if (c == L_('\0')) /* [... (unterminated) loses. */ return FNM_NOMATCH; - if (!(flags & FNM_NOESCAPE) && c == L('\\')) + if (!(flags & FNM_NOESCAPE) && c == L_('\\')) { - if (*p == L('\0')) + if (*p == L_('\0')) return FNM_NOMATCH; /* XXX 1003.2d11 is unclear if this is right. */ ++p; } - else if (c == L('[') && *p == L(':')) + else if (c == L_('[') && *p == L_(':')) { int c1 = 0; const CHAR *startp = p; @@ -863,10 +883,10 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (++c1 == CHAR_CLASS_MAX_LENGTH) return FNM_NOMATCH; - if (*p == L(':') && p[1] == L(']')) + if (*p == L_(':') && p[1] == L_(']')) break; - if (c < L('a') || c >= L('z')) + if (c < L_('a') || c >= L_('z')) { p = startp; goto ignore_next; @@ -875,18 +895,18 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, p += 2; c = *p++; } - else if (c == L('[') && *p == L('=')) + else if (c == L_('[') && *p == L_('=')) { c = *++p; - if (c == L('\0')) + if (c == L_('\0')) return FNM_NOMATCH; c = *++p; - if (c != L('=') || p[1] != L(']')) + if (c != L_('=') || p[1] != L_(']')) return FNM_NOMATCH; p += 2; c = *p++; } - else if (c == L('[') && *p == L('.')) + else if (c == L_('[') && *p == L_('.')) { ++p; while (1) @@ -895,22 +915,22 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (c == '\0') return FNM_NOMATCH; - if (*p == L('.') && p[1] == L(']')) + if (*p == L_('.') && p[1] == L_(']')) break; } p += 2; c = *p++; } } - while (c != L(']')); + while (c != L_(']')); if (not) return FNM_NOMATCH; } break; - case L('+'): - case L('@'): - case L('!'): + case L_('+'): + case L_('@'): + case L_('!'): if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { int res; @@ -921,13 +941,13 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, } goto normal_match; - case L('/'): + case L_('/'): if (NO_LEADING_PERIOD (flags)) { - if (n == string_end || c != *n) + if (n == string_end || c != (UCHAR) *n) return FNM_NOMATCH; - new_no_leading_period = 1; + new_no_leading_period = true; break; } /* FALLTHROUGH */ @@ -944,7 +964,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (n == string_end) return 0; - if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L('/')) + if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/')) /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ return 0; @@ -959,10 +979,10 @@ END (const CHAR *pattern) const CHAR *p = pattern; while (1) - if (*++p == L('\0')) + if (*++p == L_('\0')) /* This is an invalid pattern. */ return pattern; - else if (*p == L('[')) + else if (*p == L_('[')) { /* Handle brackets special. */ if (posixly_correct == 0) @@ -970,21 +990,21 @@ END (const CHAR *pattern) /* Skip the not sign. We have to recognize it because of a possibly following ']'. */ - if (*++p == L('!') || (posixly_correct < 0 && *p == L('^'))) + if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) ++p; /* A leading ']' is recognized as such. */ - if (*p == L(']')) + if (*p == L_(']')) ++p; /* Skip over all characters of the list. */ - while (*p != L(']')) - if (*p++ == L('\0')) + while (*p != L_(']')) + if (*p++ == L_('\0')) /* This is no valid pattern. */ return pattern; } - else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@') - || *p == L('!')) && p[1] == L('(')) + else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') + || *p == L_('!')) && p[1] == L_('(')) p = END (p + 1); - else if (*p == L(')')) + else if (*p == L_(')')) break; return p + 1; @@ -994,10 +1014,10 @@ END (const CHAR *pattern) static int internal_function EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, - int no_leading_period, int flags) + bool no_leading_period, int flags) { const CHAR *startp; - int level; + size_t level; struct patternlist { struct patternlist *next; @@ -1007,14 +1027,15 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, size_t pattern_len = STRLEN (pattern); const CHAR *p; const CHAR *rs; + enum { ALLOCA_LIMIT = 8000 }; /* Parse the pattern. Store the individual parts in the list. */ level = 0; - for (startp = p = pattern + 1; level >= 0; ++p) - if (*p == L('\0')) + for (startp = p = pattern + 1; ; ++p) + if (*p == L_('\0')) /* This is an invalid pattern. */ return -1; - else if (*p == L('[')) + else if (*p == L_('[')) { /* Handle brackets special. */ if (posixly_correct == 0) @@ -1022,22 +1043,22 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, /* Skip the not sign. We have to recognize it because of a possibly following ']'. */ - if (*++p == L('!') || (posixly_correct < 0 && *p == L('^'))) + if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) ++p; /* A leading ']' is recognized as such. */ - if (*p == L(']')) + if (*p == L_(']')) ++p; /* Skip over all characters of the list. */ - while (*p != L(']')) - if (*p++ == L('\0')) + while (*p != L_(']')) + if (*p++ == L_('\0')) /* This is no valid pattern. */ return -1; } - else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@') - || *p == L('!')) && p[1] == L('(')) + else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') + || *p == L_('!')) && p[1] == L_('(')) /* Remember the nesting level. */ ++level; - else if (*p == L(')')) + else if (*p == L_(')')) { if (level-- == 0) { @@ -1045,21 +1066,28 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, #define NEW_PATTERN \ struct patternlist *newp; \ size_t plen; \ + size_t plensize; \ + size_t newpsize; \ \ - plen = (opt == L('?') || opt == L('@') \ + plen = (opt == L_('?') || opt == L_('@') \ ? pattern_len \ : p - startp + 1); \ - newp = (struct patternlist *) \ - alloca (offsetof (struct patternlist, str) \ - + (plen * sizeof (CHAR))); \ - *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \ + plensize = plen * sizeof (CHAR); \ + newpsize = offsetof (struct patternlist, str) + plensize; \ + if ((size_t) -1 / sizeof (CHAR) < plen \ + || newpsize < offsetof (struct patternlist, str) \ + || ALLOCA_LIMIT <= newpsize) \ + return -1; \ + newp = (struct patternlist *) alloca (newpsize); \ + *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ newp->next = NULL; \ *lastp = newp; \ lastp = &newp->next NEW_PATTERN; + break; } } - else if (*p == L('|')) + else if (*p == L_('|')) { if (level == 0) { @@ -1068,17 +1096,17 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, } } assert (list != NULL); - assert (p[-1] == L(')')); + assert (p[-1] == L_(')')); #undef NEW_PATTERN switch (opt) { - case L('*'): + case L_('*'): if (FCT (p, string, string_end, no_leading_period, flags) == 0) return 0; /* FALLTHROUGH */ - case L('+'): + case L_('+'): do { for (rs = string; rs <= string_end; ++rs) @@ -1091,7 +1119,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, && (FCT (p, rs, string_end, rs == string ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0, + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0 /* This didn't work. Try the whole pattern. */ @@ -1099,8 +1127,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, && FCT (pattern - 1, rs, string_end, rs == string ? no_leading_period - : (rs[-1] == '/' && NO_LEADING_PERIOD (flags) - ? 1 : 0), + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0))) /* It worked. Signal success. */ @@ -1111,12 +1138,12 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, /* None of the patterns lead to a match. */ return FNM_NOMATCH; - case L('?'): + case L_('?'): if (FCT (p, string, string_end, no_leading_period, flags) == 0) return 0; /* FALLTHROUGH */ - case L('@'): + case L_('@'): do /* I cannot believe it but `strcat' is actually acceptable here. Match the entire string with the prefix from the @@ -1132,7 +1159,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, /* None of the patterns lead to a match. */ return FNM_NOMATCH; - case L('!'): + case L_('!'): for (rs = string; rs <= string_end; ++rs) { struct patternlist *runp; @@ -1147,7 +1174,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, && (FCT (p, rs, string_end, rs == string ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0, + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)) /* This is successful. */ @@ -1179,5 +1206,5 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, #undef STRCOLL #undef STRLEN #undef STRCAT -#undef L +#undef L_ #undef BTOWC