*** lib/fnmatch_loop.c.bak 2006-07-11 13:54:17.000000000 +0200
--- lib/fnmatch_loop.c 2006-07-30 21:03:04.000000000 +0200
***************
*** 1003,1022 ****
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 };
/* Parse the pattern. Store the individual parts in the list. */
level = 0;
for (startp = p = pattern + 1; ; ++p)
if (*p == L_('\0'))
/* This is an invalid pattern. */
! return -1;
else if (*p == L_('['))
{
/* Handle brackets special. */
--- 1003,1028 ----
struct patternlist
{
struct patternlist *next;
+ int malloced;
CHAR str[1];
} *list = NULL;
struct patternlist **lastp = &list;
size_t pattern_len = STRLEN (pattern);
const CHAR *p;
const CHAR *rs;
+ #if HAVE_ALLOCA || defined _LIBC
enum { ALLOCA_LIMIT = 8000 };
+ #else
+ enum { ALLOCA_LIMIT = 0 };
+ #endif
+ int retval;
/* Parse the pattern. Store the individual parts in the list. */
level = 0;
for (startp = p = pattern + 1; ; ++p)
if (*p == L_('\0'))
/* This is an invalid pattern. */
! goto failed;
else if (*p == L_('['))
{
/* Handle brackets special. */
***************
*** 1034,1040 ****
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_('('))
--- 1040,1046 ----
while (*p != L_(']'))
if (*p++ == L_('\0'))
/* This is no valid pattern. */
! goto failed;
}
else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
|| *p == L_('!')) && p[1] == L_('('))
***************
*** 1057,1067 ****
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
--- 1063,1083 ----
plensize = plen * sizeof (CHAR); \
newpsize = offsetof (struct patternlist, str) + plensize; \
if ((size_t) -1 / sizeof (CHAR) < plen \
! || newpsize < offsetof (struct patternlist, str)) \
! goto failed; \
! if (newpsize < ALLOCA_LIMIT) \
! { \
! newp = (struct patternlist *) alloca (newpsize); \
! newp->malloced = 0; \
! } \
! else \
! { \
! newp = (struct patternlist *) malloc (newpsize); \
! if (!newp) \
! goto failed; \
! newp->malloced = 1; \
! } \
! *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \
newp->next = NULL; \
*lastp = newp; \
lastp = &newp->next
***************
*** 1085,1096 ****
{
case L_('*'):
if (FCT (p, string, string_end, no_leading_period, flags) == 0)
! return 0;
/* FALLTHROUGH */
case L_('+'):
do
{
for (rs = string; rs <= string_end; ++rs)
/* First match the prefix with the current pattern with the
current pattern. */
--- 1101,1117 ----
{
case L_('*'):
if (FCT (p, string, string_end, no_leading_period, flags) == 0)
! {
! retval = 0;
! goto done;
! }
/* FALLTHROUGH */
case L_('+'):
do
{
+ struct patternlist *next;
+
for (rs = string; rs <= string_end; ++rs)
/* First match the prefix with the current pattern with the
current pattern. */
***************
*** 1112,1142 ****
: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
flags & FNM_FILE_NAME
? flags : flags & ~FNM_PERIOD) == 0)))
! /* It worked. Signal success. */
! return 0;
}
! while ((list = list->next) != NULL);
/* None of the patterns lead to a match. */
return FNM_NOMATCH;
case L_('?'):
if (FCT (p, string, string_end, no_leading_period, flags) == 0)
! return 0;
/* FALLTHROUGH */
case L_('@'):
do
! /* I cannot believe it but `strcat' is actually acceptable
! here. Match the entire string with the prefix from the
! pattern list and the rest of the pattern following the
! pattern list. */
! if (FCT (STRCAT (list->str, p), string, string_end,
! no_leading_period,
! flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
! /* It worked. Signal success. */
! return 0;
! while ((list = list->next) != NULL);
/* None of the patterns lead to a match. */
return FNM_NOMATCH;
--- 1133,1186 ----
: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
flags & FNM_FILE_NAME
? flags : flags & ~FNM_PERIOD) == 0)))
! {
! /* It worked. Signal success. */
! retval = 0;
! goto done;
! }
!
! next = list->next;
! if (list->malloced)
! free (list);
! list = next;
}
! while (list != NULL);
/* None of the patterns lead to a match. */
return FNM_NOMATCH;
case L_('?'):
if (FCT (p, string, string_end, no_leading_period, flags) == 0)
! {
! retval = 0;
! goto done;
! }
/* FALLTHROUGH */
case L_('@'):
do
! {
! struct patternlist *next;
!
! /* I cannot believe it but `strcat' is actually acceptable
! here. Match the entire string with the prefix from the
! pattern list and the rest of the pattern following the
! pattern list. */
! if (FCT (STRCAT (list->str, p), string, string_end,
! no_leading_period,
! flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
! {
! /* It worked. Signal success. */
! retval = 0;
! goto done;
! }
!
! next = list->next;
! if (list->malloced)
! free (list);
! list = next;
! }
! while (list != NULL);
/* None of the patterns lead to a match. */
return FNM_NOMATCH;
***************
*** 1159,1178 ****
: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
== 0))
! /* This is successful. */
! return 0;
}
/* None of the patterns together with the rest of the pattern
lead to a match. */
! return FNM_NOMATCH;
default:
assert (! "Invalid extended matching operator");
break;
}
! return -1;
}
--- 1203,1237 ----
: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
== 0))
! {
! /* This is successful. */
! retval = 0;
! goto done;
! }
}
/* None of the patterns together with the rest of the pattern
lead to a match. */
! retval = FNM_NOMATCH;
! goto done;
default:
assert (! "Invalid extended matching operator");
break;
}
! failed:
! retval = -1;
! done:
! while (list != NULL)
! {
! struct patternlist *next = list->next;
!
! if (list->malloced)
! free (list);
! list = next;
! }
! return retval;
}