Here's a diff that hews a bit more closely to the example code in
https://research.swtch.com/glob
- todd
Index: lib/libc/gen/glob.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/glob.c,v
retrieving revision 1.46
diff -u -p -u -r1.46 glob.c
--- lib/libc/gen/glob.c 28 Dec 2015 22:08:18 -0000 1.46
+++ lib/libc/gen/glob.c 28 Apr 2017 21:29:24 -0000
@@ -126,9 +126,6 @@ typedef char Char;
#define GLOB_LIMIT_STAT 2048
#define GLOB_LIMIT_READDIR 16384
-/* Limit of recursion during matching attempts. */
-#define GLOB_LIMIT_RECUR 64
-
struct glob_lim {
size_t glim_malloc;
size_t glim_stat;
@@ -161,7 +158,7 @@ static const Char *
static int globexp1(const Char *, glob_t *, struct glob_lim *);
static int globexp2(const Char *, const Char *, glob_t *,
struct glob_lim *);
-static int match(Char *, Char *, Char *, int);
+static int match(Char *, Char *, Char *);
#ifdef DEBUG
static void qprintf(const char *, Char *);
#endif
@@ -753,7 +750,7 @@ glob3(Char *pathbuf, Char *pathbuf_last,
break;
}
- if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) {
+ if (!match(pathend, pattern, restpattern)) {
*pathend = EOS;
continue;
}
@@ -882,17 +879,15 @@ globextend(const Char *path, glob_t *pgl
/*
- * pattern matching function for filenames. Each occurrence of the *
- * pattern causes a recursion level.
+ * pattern matching function for filenames.
*/
static int
-match(Char *name, Char *pat, Char *patend, int recur)
+match(Char *name, Char *pat, Char *patend)
{
int ok, negate_range;
Char c, k;
-
- if (recur-- == 0)
- return(GLOB_NOSPACE);
+ Char *nextName = NULL;
+ Char *nextPat = NULL;
while (pat < patend) {
c = *pat++;
@@ -900,21 +895,18 @@ match(Char *name, Char *pat, Char *paten
case M_ALL:
while (pat < patend && (*pat & M_MASK) == M_ALL)
pat++; /* eat consecutive '*' */
- if (pat == patend)
- return(1);
- do {
- if (match(name, pat, patend, recur))
- return(1);
- } while (*name++ != EOS);
- return(0);
+ /* If no match we will restart at name + 1 */
+ nextPat = pat - 1;
+ nextName = name + 1;
+ continue;
case M_ONE:
if (*name++ == EOS)
- return(0);
- break;
+ break;
+ continue;
case M_SET:
ok = 0;
if ((k = *name++) == EOS)
- return(0);
+ break;
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END) {
@@ -933,15 +925,22 @@ match(Char *name, Char *pat, Char *paten
ok = 1;
}
if (ok == negate_range)
- return(0);
- break;
+ break;
+ continue;
default:
if (*name++ != c)
- return(0);
- break;
+ break;
+ continue;
}
+ /* No match, restart if we hit a '*' in pattern. */
+ if (nextName != NULL && *nextName != EOS) {
+ pat = nextPat;
+ name = nextName;
+ continue;
+ }
+ return(0);
}
- return(*name == EOS);
+ return(1);
}
/* Free allocated data belonging to a glob_t structure. */