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. */

Reply via email to