| version 1.26, 2010/07/06 14:59:22 |
version 1.27, 2010/09/06 14:40:25 |
| Line 160 static Char *g_strchr(const Char *, int) |
|
| Line 160 static Char *g_strchr(const Char *, int) |
|
| static int g_stat(Char *, __gl_stat_t *, glob_t *); |
static int g_stat(Char *, __gl_stat_t *, glob_t *); |
| static int glob0(const Char *, glob_t *, size_t *); |
static int glob0(const Char *, glob_t *, size_t *); |
| static int glob1(Char *, glob_t *, size_t *); |
static int glob1(Char *, glob_t *, size_t *); |
| static int glob2(Char *, Char *, Char *, Char *, glob_t *, |
static int glob2(Char *, Char *, Char *, const Char *, glob_t *, |
| size_t *); |
|
| static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, |
|
| size_t *); |
size_t *); |
| |
static int glob3(Char *, Char *, Char *, const Char *, const Char *, |
| |
const Char *, glob_t *, size_t *); |
| static int globextend(const Char *, glob_t *, size_t *); |
static int globextend(const Char *, glob_t *, size_t *); |
| static const Char *globtilde(const Char *, Char *, size_t, glob_t *); |
static const Char *globtilde(const Char *, Char *, size_t, glob_t *); |
| static int globexp1(const Char *, glob_t *, size_t *); |
static int globexp1(const Char *, glob_t *, size_t *); |
| static int globexp2(const Char *, const Char *, glob_t *, int *, |
static int globexp2(const Char *, const Char *, glob_t *, int *, |
| size_t *); |
size_t *); |
| static int match(Char *, Char *, Char *); |
static int match(const Char *, const Char *, const Char *); |
| #ifdef DEBUG |
#ifdef DEBUG |
| static void qprintf(const char *, Char *); |
static void qprintf(const char *, Char *); |
| #endif |
#endif |
| Line 346 globexp2(const Char *ptr, const Char *pa |
|
| Line 346 globexp2(const Char *ptr, const Char *pa |
|
| |
|
| /* Expand the current pattern */ |
/* Expand the current pattern */ |
| #ifdef DEBUG |
#ifdef DEBUG |
| qprintf("globexp2:", patbuf); |
qprintf("globexp2", patbuf); |
| #endif |
#endif |
| *rv = globexp1(patbuf, pglob, limit); |
*rv = globexp1(patbuf, pglob, limit); |
| |
|
| Line 513 glob0(const Char *pattern, glob_t *pglob |
|
| Line 513 glob0(const Char *pattern, glob_t *pglob |
|
| break; |
break; |
| case STAR: |
case STAR: |
| pglob->gl_flags |= GLOB_MAGCHAR; |
pglob->gl_flags |= GLOB_MAGCHAR; |
| /* collapse adjacent stars to one, |
/* collapse adjacent stars to one [or three if globstar] |
| * to avoid exponential behavior |
* to avoid exponential behavior |
| */ |
*/ |
| if (bufnext == patbuf || bufnext[-1] != M_ALL) |
if (bufnext == patbuf || bufnext[-1] != M_ALL || |
| |
((pglob->gl_flags & GLOB_STAR) != 0 && |
| |
(bufnext - 1 == patbuf || bufnext[-2] != M_ALL || |
| |
bufnext - 2 == patbuf || bufnext[-3] != M_ALL))) |
| *bufnext++ = M_ALL; |
*bufnext++ = M_ALL; |
| break; |
break; |
| default: |
default: |
| Line 526 glob0(const Char *pattern, glob_t *pglob |
|
| Line 529 glob0(const Char *pattern, glob_t *pglob |
|
| } |
} |
| *bufnext = EOS; |
*bufnext = EOS; |
| #ifdef DEBUG |
#ifdef DEBUG |
| qprintf("glob0:", patbuf); |
qprintf("glob0", patbuf); |
| #endif |
#endif |
| |
|
| if ((error = glob1(patbuf, pglob, limit)) != 0) |
if ((error = glob1(patbuf, pglob, limit)) != 0) |
| Line 592 glob1(Char *pattern, glob_t *pglob, size |
|
| Line 595 glob1(Char *pattern, glob_t *pglob, size |
|
| * meta characters. |
* meta characters. |
| */ |
*/ |
| static int |
static int |
| glob2(Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern, glob_t *pglob, |
glob2(Char *pathbuf, Char *pathend, Char *pathlim, const Char *pattern, |
| size_t *limit) |
glob_t *pglob, size_t *limit) |
| { |
{ |
| __gl_stat_t sb; |
__gl_stat_t sb; |
| Char *p, *q; |
const Char *p; |
| |
Char *q; |
| int anymeta; |
int anymeta; |
| Char *pend; |
Char *pend; |
| ptrdiff_t diff; |
ptrdiff_t diff; |
| Line 606 glob2(Char *pathbuf, Char *pathend, Char |
|
| Line 610 glob2(Char *pathbuf, Char *pathend, Char |
|
| _DIAGASSERT(pattern != NULL); |
_DIAGASSERT(pattern != NULL); |
| _DIAGASSERT(pglob != NULL); |
_DIAGASSERT(pglob != NULL); |
| |
|
| |
#ifdef DEBUG |
| |
qprintf("glob2", pathbuf); |
| |
#endif |
| /* |
/* |
| * Loop over pattern segments until end of pattern or until |
* Loop over pattern segments until end of pattern or until |
| * segment with meta character found. |
* segment with meta character found. |
| Line 677 glob2(Char *pathbuf, Char *pathend, Char |
|
| Line 684 glob2(Char *pathbuf, Char *pathend, Char |
|
| } |
} |
| } else /* Need expansion, recurse. */ |
} else /* Need expansion, recurse. */ |
| return glob3(pathbuf, pathend, pathlim, pattern, p, |
return glob3(pathbuf, pathend, pathlim, pattern, p, |
| pglob, limit); |
pattern, pglob, limit); |
| } |
} |
| /* NOTREACHED */ |
/* NOTREACHED */ |
| } |
} |
| |
|
| static int |
static int |
| glob3(Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern, |
glob3(Char *pathbuf, Char *pathend, Char *pathlim, const Char *pattern, |
| Char *restpattern, glob_t *pglob, size_t *limit) |
const Char *restpattern, const Char *pglobstar, glob_t *pglob, |
| |
size_t *limit) |
| { |
{ |
| struct dirent *dp; |
struct dirent *dp; |
| DIR *dirp; |
DIR *dirp; |
| |
__gl_stat_t sbuf; |
| int error; |
int error; |
| char buf[MAXPATHLEN]; |
char buf[MAXPATHLEN]; |
| |
int globstar = 0; |
| |
int chase_symlinks = 0; |
| |
const Char *termstar = NULL; |
| |
|
| /* |
/* |
| * The readdirfunc declaration can't be prototyped, because it is |
* The readdirfunc declaration can't be prototyped, because it is |
| Line 708 glob3(Char *pathbuf, Char *pathend, Char |
|
| Line 720 glob3(Char *pathbuf, Char *pathend, Char |
|
| *pathend = EOS; |
*pathend = EOS; |
| errno = 0; |
errno = 0; |
| |
|
| |
while (pglobstar < restpattern) { |
| |
if ((pglobstar[0] & M_MASK) == M_ALL && |
| |
(pglobstar[1] & M_MASK) == M_ALL) { |
| |
globstar = 1; |
| |
chase_symlinks = (pglobstar[2] & M_MASK) == M_ALL; |
| |
termstar = pglobstar + (2 + chase_symlinks); |
| |
break; |
| |
} |
| |
pglobstar++; |
| |
} |
| |
|
| |
if (globstar) { |
| |
error = pglobstar == pattern && termstar == restpattern ? |
| |
*restpattern == EOS ? |
| |
glob2(pathbuf, pathend, pathlim, restpattern - 1, pglob, |
| |
limit) : |
| |
glob2(pathbuf, pathend, pathlim, restpattern + 1, pglob, |
| |
limit) : |
| |
glob3(pathbuf, pathend, pathlim, pattern, restpattern, |
| |
termstar, pglob, limit); |
| |
if (error) |
| |
return error; |
| |
*pathend = EOS; |
| |
} |
| |
|
| |
if (*pathbuf && (g_lstat(pathbuf, &sbuf, pglob) || |
| |
!S_ISDIR(sbuf.st_mode) |
| |
#ifdef S_IFLINK |
| |
&& ((globstar && !chase_symlinks) || !S_ISLNK(sbuf.st_mode)) |
| |
#endif |
| |
)) |
| |
return 0; |
| |
|
| if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { |
if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { |
| if (pglob->gl_errfunc) { |
if (pglob->gl_errfunc) { |
| if (g_Ctoc(pathbuf, buf, sizeof(buf))) |
if (g_Ctoc(pathbuf, buf, sizeof(buf))) |
| Line 789 glob3(Char *pathbuf, Char *pathend, Char |
|
| Line 834 glob3(Char *pathbuf, Char *pathend, Char |
|
| } |
} |
| } |
} |
| |
|
| if (!match(pathend, pattern, restpattern)) { |
if (globstar) { |
| |
#ifdef S_IFLNK |
| |
if (!chase_symlinks && |
| |
(g_lstat(pathbuf, &sbuf, pglob) || |
| |
S_ISLNK(sbuf.st_mode))) |
| |
continue; |
| |
#endif |
| |
|
| |
if (!match(pathend, pattern, termstar)) |
| |
continue; |
| |
|
| |
if (--dc < pathlim - 2) |
| |
*dc++ = SEP; |
| |
*dc = EOS; |
| |
error = glob2(pathbuf, dc, pathlim, pglobstar, |
| |
pglob, limit); |
| |
if (error) |
| |
break; |
| *pathend = EOS; |
*pathend = EOS; |
| continue; |
} else { |
| |
if (!match(pathend, pattern, restpattern)) { |
| |
*pathend = EOS; |
| |
continue; |
| |
} |
| |
error = glob2(pathbuf, --dc, pathlim, restpattern, |
| |
pglob, limit); |
| |
if (error) |
| |
break; |
| } |
} |
| error = glob2(pathbuf, --dc, pathlim, restpattern, pglob, |
|
| limit); |
|
| if (error) |
|
| break; |
|
| } |
} |
| |
|
| if (pglob->gl_flags & GLOB_ALTDIRFUNC) |
if (pglob->gl_flags & GLOB_ALTDIRFUNC) |
| (*pglob->gl_closedir)(dirp); |
(*pglob->gl_closedir)(dirp); |
| else |
else |
| Line 881 globextend(const Char *path, glob_t *pgl |
|
| Line 946 globextend(const Char *path, glob_t *pgl |
|
| * pattern causes a recursion level. |
* pattern causes a recursion level. |
| */ |
*/ |
| static int |
static int |
| match(Char *name, Char *pat, Char *patend) |
match(const Char *name, const Char *pat, const Char *patend) |
| { |
{ |
| int ok, negate_range; |
int ok, negate_range; |
| Char c, k; |
Char c, k; |
| Line 894 match(Char *name, Char *pat, Char *paten |
|
| Line 959 match(Char *name, Char *pat, Char *paten |
|
| c = *pat++; |
c = *pat++; |
| switch (c & M_MASK) { |
switch (c & M_MASK) { |
| case M_ALL: |
case M_ALL: |
| |
while (pat < patend && (*pat & M_MASK) == M_ALL) |
| |
pat++; /* eat consecutive '*' */ |
| if (pat == patend) |
if (pat == patend) |
| return 1; |
return 1; |
| do |
for (; !match(name, pat, patend); name++) |
| if (match(name, pat, patend)) |
if (*name == EOS) |
| return 1; |
return 0; |
| while (*name++ != EOS); |
return 1; |
| return 0; |
|
| case M_ONE: |
case M_ONE: |
| if (*name++ == EOS) |
if (*name++ == EOS) |
| return 0; |
return 0; |
| Line 963 glob_pattern_p(const char *pattern, int |
|
| Line 1029 glob_pattern_p(const char *pattern, int |
|
| return 1; |
return 1; |
| |
|
| case QUOTE: |
case QUOTE: |
| if (quote && pattern[1] != '\0') |
if (quote && pattern[1] != EOS) |
| ++pattern; |
++pattern; |
| break; |
break; |
| |
|