Updated from libc

This commit is contained in:
Roland McGrath 1996-03-20 03:12:54 +00:00
parent 46a1497b8e
commit ee7af57e3c
3 changed files with 118 additions and 38 deletions

View file

@ -1,3 +1,10 @@
Thu Mar 14 06:01:07 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* posix/glob.c (glob): In GLOB_BRACE brace expansion, fix buffer size
calculation to include trailing invariant portion. Don't use alloca;
instead use a dynamic auto array for GCC, malloc for non-GCC.
Handle nested braces properly.
Fri Mar 1 10:09:46 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* posix/glob.c: Use canonical code from autoconf manual for dirent

View file

@ -268,50 +268,123 @@ glob (pattern, flags, errfunc, pglob)
const char *begin = strchr (pattern, '{');
if (begin != NULL)
{
const char *end = strchr (begin + 1, '}');
if (end != NULL && end != begin + 1)
{
size_t restlen = strlen (end + 1) + 1;
const char *p, *comma;
char *buf;
size_t bufsz = 0;
int firstc;
size_t restlen;
const char *p, *end, *next;
unsigned int depth = 0;
/* Find the end of the brace expression, by counting braces.
While we're at it, notice the first comma at top brace level. */
end = begin + 1;
next = NULL;
while (1)
{
switch (*end++)
{
case ',':
if (depth == 0 && next == NULL)
next = end;
continue;
case '{':
++depth;
continue;
case '}':
if (depth-- == 0)
break;
continue;
case '\0':
return glob (pattern, flags &~ GLOB_BRACE, errfunc, pglob);
}
break;
}
restlen = strlen (end) + 1;
if (next == NULL)
next = end;
/* We have a brace expression. BEGIN points to the opening {,
NEXT points past the terminator of the first element, and END
points past the final }. We will accumulate result names from
recursive runs for each brace alternative in the buffer using
GLOB_APPEND. */
if (!(flags & GLOB_APPEND))
{
/* This call is to set a new vector, so clear out the
vector so we can append to it. */
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
}
firstc = pglob->gl_pathc;
for (p = begin + 1;; p = comma + 1)
/* In this loop P points to the beginning of the current element
and NEXT points past its terminator. */
p = begin + 1;
while (1)
{
/* Construct a whole name that is one of the brace
alternatives in a temporary buffer. */
int result;
comma = strchr (p, ',');
if (comma == NULL)
comma = strchr (p, '\0');
if ((begin - pattern) + (comma - p) + 1 > bufsz)
size_t bufsz = (begin - pattern) + (next - 1 - p) + restlen;
#ifdef __GNUC__
char onealt[bufsz];
#else
char *onealt = malloc (bufsz);
if (onealt == NULL)
{
if (bufsz * 2 < comma - p + 1)
bufsz *= 2;
else
bufsz = comma - p + 1;
buf = __alloca (bufsz);
if (!(flags & GLOB_APPEND))
globfree (&pglob);
return GLOB_NOSPACE;
}
memcpy (buf, pattern, begin - pattern);
memcpy (buf + (begin - pattern), p, comma - p);
memcpy (buf + (begin - pattern) + (comma - p), end, restlen);
result = glob (buf, ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) |
#endif
memcpy (onealt, pattern, begin - pattern);
memcpy (&onealt[begin - pattern], p, next - 1 - p);
memcpy (&onealt[(begin - pattern) + (next - 1 - p)],
end, restlen);
result = glob (onealt,
((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) |
GLOB_APPEND), errfunc, pglob);
#ifndef __GNUC__
free (onealt);
#endif
/* If we got an error, return it. */
if (result && result != GLOB_NOMATCH)
{
if (!(flags & GLOB_APPEND))
globfree (pglob);
return result;
if (*comma == '\0')
break;
}
/* Advance past this alternative and process the next. */
p = next;
depth = 0;
scan:
switch (*p++)
{
case ',':
if (depth == 0)
{
/* Found the next alternative. Loop to glob it. */
next = p;
continue;
}
goto scan;
case '{':
++depth;
goto scan;
case '}':
if (depth-- == 0)
/* End of the brace expression. Break out of the loop. */
break;
goto scan;
}
}
if (pglob->gl_pathc == firstc &&
!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
return GLOB_NOMATCH;
}
}
}
/* Find the filename. */
filename = strrchr (pattern, '/');