static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
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,
bool no_leading_period, int flags)
{
register const CHAR *p = pattern, *n = string;
register UCHAR c;
#ifdef _LIBC
# if WIDE_CHAR_VERSION
const char *collseq = (const char *)
_NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
# else
const UCHAR *collseq = (const UCHAR *)
_NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
# endif
#endif
while ((c = *p++) != L_('\0'))
{
bool new_no_leading_period = false;
c = FOLD (c);
switch (c)
{
case L_('?'):
if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
{
int res;
res = EXT (c, p, n, string_end, no_leading_period,
flags);
if (res != -1)
return res;
}
if (n == string_end)
return FNM_NOMATCH;
else if (*n == L_('/') && (flags & FNM_FILE_NAME))
return FNM_NOMATCH;
else if (*n == L_('.') && no_leading_period)
return FNM_NOMATCH;
break;
case L_('\\'):
if (!(flags & FNM_NOESCAPE))
{
c = *p++;
if (c == L_('\0'))
return FNM_NOMATCH;
c = FOLD (c);
}
if (n == string_end || FOLD ((UCHAR) *n) != c)
return FNM_NOMATCH;
break;
case L_('*'):
if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
{
int res;
res = EXT (c, p, n, string_end, no_leading_period,
flags);
if (res != -1)
return res;
}
if (n != string_end && *n == L_('.') && no_leading_period)
return FNM_NOMATCH;
for (c = *p++; c == L_('?') || c == L_('*'); c = *p++)
{
if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0)
{
const CHAR *endp = END (p);
if (endp != p)
{
p = endp;
continue;
}
}
if (c == L_('?'))
{
if (n == string_end)
return FNM_NOMATCH;
else if (*n == L_('/')
&& __builtin_expect (flags & FNM_FILE_NAME, 0))
return FNM_NOMATCH;
else
++n;
}
}
if (c == L_('\0'))
{
int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
if (flags & FNM_FILE_NAME)
{
if (flags & FNM_LEADING_DIR)
result = 0;
else
{
if (MEMCHR (n, L_('/'), string_end - n) == NULL)
result = 0;
}
}
return result;
}
else
{
const CHAR *endp;
endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'),
string_end - n);
if (endp == NULL)
endp = string_end;
if (c == L_('[')
|| (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
&& (c == L_('@') || c == L_('+') || c == L_('!'))
&& *p == L_('(')))
{
int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD));
bool no_leading_period2 = no_leading_period;
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))
{
while (n < string_end && *n != L_('/'))
++n;
if (n < string_end && *n == L_('/')
&& (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
== 0))
return 0;
}
else
{
int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD));
int no_leading_period2 = no_leading_period;
if (c == L_('\\') && !(flags & FNM_NOESCAPE))
c = *p;
c = FOLD (c);
for (--p; n < endp; ++n, no_leading_period2 = false)
if (FOLD ((UCHAR) *n) == c
&& (FCT (p, n, string_end, no_leading_period2, flags2)
== 0))
return 0;
}
}
return FNM_NOMATCH;
case L_('['):
{
register bool not;
CHAR cold;
UCHAR fn;
if (posixly_correct == 0)
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
if (n == string_end)
return FNM_NOMATCH;
if (*n == L_('.') && no_leading_period)
return FNM_NOMATCH;
if (*n == L_('/') && (flags & FNM_FILE_NAME))
return FNM_NOMATCH;
not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^')));
if (not)
++p;
fn = FOLD ((UCHAR) *n);
c = *p++;
for (;;)
{
if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
{
if (*p == L_('\0'))
return FNM_NOMATCH;
c = FOLD ((UCHAR) *p);
++p;
goto normal_bracket;
}
else if (c == L_('[') && *p == L_(':'))
{
CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
size_t c1 = 0;
#if defined _LIBC || WIDE_CHAR_SUPPORT
wctype_t wt;
#endif
const CHAR *startp = p;
for (;;)
{
if (c1 == CHAR_CLASS_MAX_LENGTH)
return FNM_NOMATCH;
c = *++p;
if (c == L_(':') && p[1] == L_(']'))
{
p += 2;
break;
}
if (c < L_('a') || c >= L_('z'))
{
p = startp;
c = L_('[');
goto normal_bracket;
}
str[c1++] = c;
}
str[c1] = L_('\0');
#if defined _LIBC || WIDE_CHAR_SUPPORT
wt = IS_CHAR_CLASS (str);
if (wt == 0)
return FNM_NOMATCH;
# if defined _LIBC && ! WIDE_CHAR_VERSION
if (_ISCTYPE ((UCHAR) *n, wt))
goto matched;
# else
if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
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)))
goto matched;
#endif
c = *p++;
}
#ifdef _LIBC
else if (c == L_('[') && *p == L_('='))
{
UCHAR str[1];
uint32_t nrules =
_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
const CHAR *startp = p;
c = *++p;
if (c == L_('\0'))
{
p = startp;
c = L_('[');
goto normal_bracket;
}
str[0] = c;
c = *++p;
if (c != L_('=') || p[1] != L_(']'))
{
p = startp;
c = L_('[');
goto normal_bracket;
}
p += 2;
if (nrules == 0)
{
if ((UCHAR) *n == str[0])
goto matched;
}
else
{
const int32_t *table;
# if WIDE_CHAR_VERSION
const int32_t *weights;
const int32_t *extra;
# else
const unsigned char *weights;
const unsigned char *extra;
# endif
const int32_t *indirect;
int32_t idx;
const UCHAR *cp = (const UCHAR *) str;
# if WIDE_CHAR_VERSION
# include <locale/weightwc.h>
# else
# include <locale/weight.h>
# endif
# if WIDE_CHAR_VERSION
table = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
weights = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
extra = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
indirect = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
# else
table = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
weights = (const unsigned char *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
extra = (const unsigned char *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
indirect = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
# endif
idx = findidx (&cp);
if (idx != 0)
{
int len = weights[idx];
int32_t idx2;
const UCHAR *np = (const UCHAR *) n;
idx2 = findidx (&np);
if (idx2 != 0 && len == weights[idx2])
{
int cnt = 0;
while (cnt < len
&& (weights[idx + 1 + cnt]
== weights[idx2 + 1 + cnt]))
++cnt;
if (cnt == len)
goto matched;
}
}
}
c = *p++;
}
#endif
else if (c == L_('\0'))
return FNM_NOMATCH;
else
{
bool is_range = false;
#ifdef _LIBC
bool is_seqval = false;
if (c == L_('[') && *p == L_('.'))
{
uint32_t nrules =
_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
const CHAR *startp = p;
size_t c1 = 0;
while (1)
{
c = *++p;
if (c == L_('.') && p[1] == L_(']'))
{
p += 2;
break;
}
if (c == '\0')
return FNM_NOMATCH;
++c1;
}
is_range = *p == L_('-') && p[1] != L_('\0');
if (nrules == 0)
{
if (c1 != 1)
return FNM_NOMATCH;
if (!is_range && *n == startp[1])
goto matched;
cold = startp[1];
c = *p++;
}
else
{
int32_t table_size;
const int32_t *symb_table;
# ifdef WIDE_CHAR_VERSION
char str[c1];
size_t strcnt;
# else
# define str (startp + 1)
# endif
const unsigned char *extra;
int32_t idx;
int32_t elem;
int32_t second;
int32_t hash;
# ifdef WIDE_CHAR_VERSION
for (strcnt = 0; strcnt < c1; ++strcnt)
str[strcnt] = startp[1 + strcnt];
# endif
table_size =
_NL_CURRENT_WORD (LC_COLLATE,
_NL_COLLATE_SYMB_HASH_SIZEMB);
symb_table = (const int32_t *)
_NL_CURRENT (LC_COLLATE,
_NL_COLLATE_SYMB_TABLEMB);
extra = (const unsigned char *)
_NL_CURRENT (LC_COLLATE,
_NL_COLLATE_SYMB_EXTRAMB);
hash = elem_hash (str, c1);
idx = 0;
elem = hash % table_size;
if (symb_table[2 * elem] != 0)
{
second = hash % (table_size - 2) + 1;
do
{
if (symb_table[2 * elem] == hash
&& (c1
== extra[symb_table[2 * elem + 1]])
&& memcmp (str,
&extra[symb_table[2 * elem
+ 1]
+ 1], c1) == 0)
{
idx = symb_table[2 * elem + 1];
idx += 1 + extra[idx];
break;
}
elem += second;
}
while (symb_table[2 * elem] != 0);
}
if (symb_table[2 * elem] != 0)
{
# ifdef WIDE_CHAR_VERSION
int32_t *wextra;
idx += 1 + extra[idx];
idx = (idx + 3) & ~3;
wextra = (int32_t *) &extra[idx + 4];
# endif
if (! is_range)
{
# ifdef WIDE_CHAR_VERSION
for (c1 = 0;
(int32_t) c1 < wextra[idx];
++c1)
if (n[c1] != wextra[1 + c1])
break;
if ((int32_t) c1 == wextra[idx])
goto matched;
# else
for (c1 = 0; c1 < extra[idx]; ++c1)
if (n[c1] != extra[1 + c1])
break;
if (c1 == extra[idx])
goto matched;
# endif
}
is_seqval = true;
# ifdef WIDE_CHAR_VERSION
cold = wextra[1 + wextra[idx]];
# else
idx += 1 + extra[idx];
idx = (idx + 3) & ~4;
cold = *((int32_t *) &extra[idx]);
# endif
c = *p++;
}
else if (c1 == 1)
{
if (!is_range && *n == str[0])
goto matched;
cold = str[0];
c = *p++;
}
else
return FNM_NOMATCH;
}
}
else
# undef str
#endif
{
c = FOLD (c);
normal_bracket:
is_range = (*p == L_('-') && p[1] != L_('\0')
&& p[1] != L_(']'));
if (!is_range && c == fn)
goto matched;
#if _LIBC
is_seqval = false;
#endif
cold = c;
c = *p++;
}
if (c == L_('-') && *p != L_(']'))
{
#if _LIBC
uint32_t fcollseq;
uint32_t lcollseq;
UCHAR cend = *p++;
# ifdef WIDE_CHAR_VERSION
fcollseq = __collseq_table_lookup (collseq, fn);
if (fcollseq == ~((uint32_t) 0))
goto range_not_matched;
if (is_seqval)
lcollseq = cold;
else
lcollseq = __collseq_table_lookup (collseq, cold);
# else
fcollseq = collseq[fn];
lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
# endif
is_seqval = false;
if (cend == L_('[') && *p == L_('.'))
{
uint32_t nrules =
_NL_CURRENT_WORD (LC_COLLATE,
_NL_COLLATE_NRULES);
const CHAR *startp = p;
size_t c1 = 0;
while (1)
{
c = *++p;
if (c == L_('.') && p[1] == L_(']'))
{
p += 2;
break;
}
if (c == '\0')
return FNM_NOMATCH;
++c1;
}
if (nrules == 0)
{
if (c1 != 1)
return FNM_NOMATCH;
cend = startp[1];
}
else
{
int32_t table_size;
const int32_t *symb_table;
# ifdef WIDE_CHAR_VERSION
char str[c1];
size_t strcnt;
# else
# define str (startp + 1)
# endif
const unsigned char *extra;
int32_t idx;
int32_t elem;
int32_t second;
int32_t hash;
# ifdef WIDE_CHAR_VERSION
for (strcnt = 0; strcnt < c1; ++strcnt)
str[strcnt] = startp[1 + strcnt];
# endif
table_size =
_NL_CURRENT_WORD (LC_COLLATE,
_NL_COLLATE_SYMB_HASH_SIZEMB);
symb_table = (const int32_t *)
_NL_CURRENT (LC_COLLATE,
_NL_COLLATE_SYMB_TABLEMB);
extra = (const unsigned char *)
_NL_CURRENT (LC_COLLATE,
_NL_COLLATE_SYMB_EXTRAMB);
hash = elem_hash (str, c1);
idx = 0;
elem = hash % table_size;
if (symb_table[2 * elem] != 0)
{
second = hash % (table_size - 2) + 1;
do
{
if (symb_table[2 * elem] == hash
&& (c1
== extra[symb_table[2 * elem + 1]])
&& memcmp (str,
&extra[symb_table[2 * elem + 1]
+ 1], c1) == 0)
{
idx = symb_table[2 * elem + 1];
idx += 1 + extra[idx];
break;
}
elem += second;
}
while (symb_table[2 * elem] != 0);
}
if (symb_table[2 * elem] != 0)
{
# ifdef WIDE_CHAR_VERSION
int32_t *wextra;
idx += 1 + extra[idx];
idx = (idx + 3) & ~4;
wextra = (int32_t *) &extra[idx + 4];
# endif
is_seqval = true;
# ifdef WIDE_CHAR_VERSION
cend = wextra[1 + wextra[idx]];
# else
idx += 1 + extra[idx];
idx = (idx + 3) & ~4;
cend = *((int32_t *) &extra[idx]);
# endif
}
else if (symb_table[2 * elem] != 0 && c1 == 1)
{
cend = str[0];
c = *p++;
}
else
return FNM_NOMATCH;
}
# undef str
}
else
{
if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
cend = *p++;
if (cend == L_('\0'))
return FNM_NOMATCH;
cend = FOLD (cend);
}
if (
# ifdef WIDE_CHAR_VERSION
lcollseq == 0xffffffff ||
# endif
lcollseq <= fcollseq)
{
uint32_t hcollseq;
if (is_seqval)
hcollseq = cend;
else
{
# ifdef WIDE_CHAR_VERSION
hcollseq =
__collseq_table_lookup (collseq, cend);
if (hcollseq == ~((uint32_t) 0))
{
if (lcollseq != fcollseq)
goto range_not_matched;
goto matched;
}
# else
hcollseq = collseq[cend];
# endif
}
if (lcollseq <= hcollseq && fcollseq <= hcollseq)
goto matched;
}
# ifdef WIDE_CHAR_VERSION
range_not_matched:
# endif
#else
UCHAR cend = *p++;
if (!(flags & FNM_NOESCAPE) && cend == L_('\\'))
cend = *p++;
if (cend == L_('\0'))
return FNM_NOMATCH;
if (cold <= fn && fn <= cend)
goto matched;
#endif
c = *p++;
}
}
if (c == L_(']'))
break;
}
if (!not)
return FNM_NOMATCH;
break;
matched:
do
{
ignore_next:
c = *p++;
if (c == L_('\0'))
return FNM_NOMATCH;
if (!(flags & FNM_NOESCAPE) && c == L_('\\'))
{
if (*p == L_('\0'))
return FNM_NOMATCH;
++p;
}
else if (c == L_('[') && *p == L_(':'))
{
int c1 = 0;
const CHAR *startp = p;
while (1)
{
c = *++p;
if (++c1 == CHAR_CLASS_MAX_LENGTH)
return FNM_NOMATCH;
if (*p == L_(':') && p[1] == L_(']'))
break;
if (c < L_('a') || c >= L_('z'))
{
p = startp;
goto ignore_next;
}
}
p += 2;
c = *p++;
}
else if (c == L_('[') && *p == L_('='))
{
c = *++p;
if (c == L_('\0'))
return FNM_NOMATCH;
c = *++p;
if (c != L_('=') || p[1] != L_(']'))
return FNM_NOMATCH;
p += 2;
c = *p++;
}
else if (c == L_('[') && *p == L_('.'))
{
++p;
while (1)
{
c = *++p;
if (c == '\0')
return FNM_NOMATCH;
if (*p == L_('.') && p[1] == L_(']'))
break;
}
p += 2;
c = *p++;
}
}
while (c != L_(']'));
if (not)
return FNM_NOMATCH;
}
break;
case L_('+'):
case L_('@'):
case L_('!'):
if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
{
int res;
res = EXT (c, p, n, string_end, no_leading_period, flags);
if (res != -1)
return res;
}
goto normal_match;
case L_('/'):
if (NO_LEADING_PERIOD (flags))
{
if (n == string_end || c != (UCHAR) *n)
return FNM_NOMATCH;
new_no_leading_period = true;
break;
}
default:
normal_match:
if (n == string_end || c != FOLD ((UCHAR) *n))
return FNM_NOMATCH;
}
no_leading_period = new_no_leading_period;
++n;
}
if (n == string_end)
return 0;
if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/'))
return 0;
return FNM_NOMATCH;
}
static const CHAR *
internal_function
END (const CHAR *pattern)
{
const CHAR *p = pattern;
while (1)
if (*++p == L_('\0'))
return pattern;
else if (*p == L_('['))
{
if (posixly_correct == 0)
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
++p;
if (*p == L_(']'))
++p;
while (*p != L_(']'))
if (*p++ == L_('\0'))
return pattern;
}
else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
|| *p == L_('!')) && p[1] == L_('('))
p = END (p + 1);
else if (*p == L_(')'))
break;
return p + 1;
}
static int
internal_function
EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
bool no_leading_period, int flags)
{
const CHAR *startp;
size_t level;
struct patternlist
{
struct patternlist *next;
CHAR str[1];
} *list = NULL;
struct patternlist **lastp = &list;
size_t pattern_len = STRLEN (pattern);
const CHAR *p;
const CHAR *rs;
enum { ALLOCA_LIMIT = 8000 };
level = 0;
for (startp = p = pattern + 1; ; ++p)
if (*p == L_('\0'))
return -1;
else if (*p == L_('['))
{
if (posixly_correct == 0)
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^')))
++p;
if (*p == L_(']'))
++p;
while (*p != L_(']'))
if (*p++ == L_('\0'))
return -1;
}
else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
|| *p == L_('!')) && p[1] == L_('('))
++level;
else if (*p == L_(')'))
{
if (level-- == 0)
{
#define NEW_PATTERN \
struct patternlist *newp; \
size_t plen; \
size_t plensize; \
size_t newpsize; \
\
plen = (opt == L_('?') || opt == L_('@') \
? pattern_len \
: p - startp + 1); \
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_('|'))
{
if (level == 0)
{
NEW_PATTERN;
startp = p + 1;
}
}
assert (list != NULL);
assert (p[-1] == L_(')'));
#undef NEW_PATTERN
switch (opt)
{
case L_('*'):
if (FCT (p, string, string_end, no_leading_period, flags) == 0)
return 0;
case L_('+'):
do
{
for (rs = string; rs <= string_end; ++rs)
if (FCT (list->str, string, rs, no_leading_period,
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
&& (FCT (p, rs, string_end,
rs == string
? no_leading_period
: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
flags & FNM_FILE_NAME
? flags : flags & ~FNM_PERIOD) == 0
|| (rs != string
&& FCT (pattern - 1, rs, string_end,
rs == string
? no_leading_period
: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
flags & FNM_FILE_NAME
? flags : flags & ~FNM_PERIOD) == 0)))
return 0;
}
while ((list = list->next) != NULL);
return FNM_NOMATCH;
case L_('?'):
if (FCT (p, string, string_end, no_leading_period, flags) == 0)
return 0;
case L_('@'):
do
if (FCT (STRCAT (list->str, p), string, string_end,
no_leading_period,
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
return 0;
while ((list = list->next) != NULL);
return FNM_NOMATCH;
case L_('!'):
for (rs = string; rs <= string_end; ++rs)
{
struct patternlist *runp;
for (runp = list; runp != NULL; runp = runp->next)
if (FCT (runp->str, string, rs, no_leading_period,
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
break;
if (runp == NULL
&& (FCT (p, rs, string_end,
rs == string
? no_leading_period
: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
== 0))
return 0;
}
return FNM_NOMATCH;
default:
assert (! "Invalid extended matching operator");
break;
}
return -1;
}
#undef FOLD
#undef CHAR
#undef UCHAR
#undef INT
#undef FCT
#undef EXT
#undef END
#undef MEMPCPY
#undef MEMCHR
#undef STRCOLL
#undef STRLEN
#undef STRCAT
#undef L_
#undef BTOWC