static int glob_dirs(const char *rest, char *epathbuf, int first, /* rest is ptr to null or ptr after slash, bp after slash */ int lower, int caseless) { // struct ffblk ff; HANDLE hf; WIN32_FIND_DATA wfd; BOOL done; /* printf("glob_dirs[%d]: rest=`%s' %c epathbuf=`%s' %c pathbuf=`%s'\n", wildcard_nesting, rest, *rest, epathbuf, *epathbuf, pathbuf); */ if (first) { if (*rest) { if (glob2(rest, epathbuf, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; } else { char sl = epathbuf[-1]; *epathbuf = 0; /* printf("end, checking `%s'\n", pathbuf); */ if (epathbuf == pathbuf) { epathbuf[0] = '.'; epathbuf[1] = 0; } else epathbuf[-1] = 0; if (CLY_FileExists(pathbuf)) if (add(pathbuf)) return GLOB_NOSPACE; epathbuf[-1] = sl; } } strcpy(epathbuf, "*.*"); hf = FindFirstFile(pathbuf, &wfd); done = (hf == INVALID_HANDLE_VALUE); while (!done) { if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (strcmp(wfd.cFileName, ".") && strcmp(wfd.cFileName, ".."))) { char *tp; strcpy(epathbuf, wfd.cFileName); tp = epathbuf + strlen(epathbuf); *tp++ = slash; *tp = 0; wildcard_nesting++; if (*rest) { if (glob2(rest, tp, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; } else { if (!(flags & GLOB_MARK)) tp[-1] = 0; if (add(pathbuf)) return GLOB_NOSPACE; tp[-1] = slash; } *tp = 0; if (glob_dirs(rest, tp, 0, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; wildcard_nesting--; } done = !FindNextFile(hf, &wfd); } FindClose(hf); return 0; }
static int glob_dirs(const char *rest, char *epathbuf, int first) /* rest is ptr to null or ptr after slash, bp after slash */ { struct ffblk ff; int done; /* printf("glob_dirs[%d]: rest=`%s' %c epathbuf=`%s' %c pathbuf=`%s'\n", wildcard_nesting, rest, *rest, epathbuf, *epathbuf, pathbuf); */ if (first) { if (*rest) { glob2(rest, epathbuf); } else { char sl = epathbuf[-1]; *epathbuf = 0; /* printf("end, checking `%s'\n", pathbuf); */ if (epathbuf == pathbuf) { epathbuf[0] = '.'; epathbuf[1] = 0; } else epathbuf[-1] = 0; if (__file_exists(pathbuf)) add(pathbuf); epathbuf[-1] = sl; } } strcpy(epathbuf, "*.*"); done = findfirst(pathbuf, &ff, FA_DIREC); while (!done) { if ((ff.ff_name[0] != '.') && (ff.ff_attrib & FA_DIREC)) { int i; char *tp; if (use_lower_case) for (i=0; ff.ff_name[i] && i<13; i++) ff.ff_name[i] = tolower(ff.ff_name[i]); /* printf("found `%s' `%s'\n", pathbuf, ff.ff_name); */ strcpy(epathbuf, ff.ff_name); tp = epathbuf + strlen(epathbuf); *tp++ = slash; *tp = 0; wildcard_nesting++; if (*rest) { glob2(rest, tp); } else { if (!(flags & GLOB_MARK)) tp[-1] = 0; add(pathbuf); tp[-1] = slash; } *tp = 0; glob_dirs(rest, tp, 0); wildcard_nesting--; } done = findnext(&ff); } return 0; }
static int glob2(const char *pattern, char *epathbuf, /* both point *after* the slash */ int lower, int caseless) { const char *pp, *pslash; char *bp; HANDLE hf; WIN32_FIND_DATA wfd; char *my_pattern; int done; if (strcmp(pattern, "...") == 0) { return glob_dirs(pattern+3, epathbuf, 1, lower, caseless); } if (strncmp(pattern, "...", 3) == 0 && (pattern[3] == '\\' || pattern[3] == '/')) { slash = pattern[3]; return glob_dirs(pattern+4, epathbuf, 1, lower, caseless); } *epathbuf = 0; /* copy as many non-wildcard segments as possible */ pp = pattern; bp = epathbuf; pslash = bp-1; while (1) { if (*pp == ':' || *pp == '\\' || *pp == '/') { pslash = bp; if (strcmp(pp+1, "...") == 0 || (strncmp(pp+1, "...", 3) == 0 && (pp[4] == '/' || pp[4] == '\\'))) { if (*pp != ':') slash = *pp; /* printf("glob2: dots at `%s'\n", pp); */ *bp++ = *pp++; break; } } else if (*pp == '*' || *pp == '?' || *pp == '[') { if (pslash > pathbuf) strncpy(epathbuf, pattern, pslash - pathbuf); pp = pattern + (pslash - epathbuf) + 1; bp = epathbuf + (pslash - epathbuf) + 1; break; } else if (*pp == 0) { break; } /* Upper-case or mixed-case patterns force case-sensitive matches in `fnmatch' for LFN filesystems. They also suppress downcasing 8+3 filenames (on all filesystems). */ else if (!preserve_case) { if (*pp >= 'A' && *pp <= 'Z') { if (use_lfn) caseless = 0; lower = 0; } else if (*pp >= 'a' && *pp <= 'z') lower = 1; } *bp++ = *pp++; } *bp = 0; if (*pp == 0) /* end of pattern? */ { if (CLY_FileExists(pathbuf)) { if (flags & GLOB_MARK) { HANDLE _hf; WIN32_FIND_DATA _wfd; _hf = FindFirstFile(pathbuf, &_wfd); //findfirst(pathbuf, &_ff, FA_RDONLY|FA_SYSTEM|FA_DIREC|FA_ARCH); if (_hf != INVALID_HANDLE_VALUE && _wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { char *_pathbuf = pathbuf + strlen(pathbuf); *_pathbuf++ = '/'; *_pathbuf = 0; } FindClose(_hf); } if (add(pathbuf)) return GLOB_NOSPACE; } return 0; } /* printf("glob2: initial segment is `%s'\n", pathbuf); */ if (wildcard_nesting) { char s = bp[-1]; bp[-1] = 0; if (!CLY_FileExists(pathbuf)) return 0; bp[-1] = s; } for (pslash = pp; *pslash && *pslash != '\\' && *pslash != '/'; pslash++) if (!preserve_case) { if (*pslash >= 'A' && *pslash <= 'Z') { if (use_lfn) caseless = 0; lower = 0; } else if (*pslash >= 'a' && *pslash <= 'z') lower = 1; } if (*pslash) slash = *pslash; my_pattern = (char *)alloca(pslash - pp + 1); if (my_pattern == 0) return GLOB_NOSPACE; strncpy(my_pattern, pp, pslash - pp); my_pattern[pslash-pp] = 0; /* printf("glob2: `%s' `%s'\n", pathbuf, my_pattern); */ if (strcmp(my_pattern, "...") == 0) { if (glob_dirs(*pslash ? pslash+1 : pslash, bp, 1, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; return 0; } strcpy(bp, "*.*"); hf = FindFirstFile(pathbuf, &wfd); done = (hf == INVALID_HANDLE_VALUE); //done = findfirst(pathbuf, &ff, FA_RDONLY|FA_SYSTEM|FA_DIREC|FA_ARCH); while (!done) { if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 || (strcmp(wfd.cFileName, ".") && strcmp(wfd.cFileName, ".."))) { if (fnmatch(my_pattern, wfd.cFileName, FNM_NOESCAPE|FNM_PATHNAME|(caseless ? FNM_NOCASE : 0)) == 0) { strcpy(bp, wfd.cFileName); if (*pslash) { char *tp = bp + strlen(bp); *tp++ = *pslash; *tp = 0; /* printf("nest: `%s' `%s'\n", pslash+1, pathbuf); */ wildcard_nesting++; if (glob2(pslash+1, tp, lower, caseless) == GLOB_NOSPACE) return GLOB_NOSPACE; wildcard_nesting--; } else { /* printf("ffmatch: `%s' matching `%s', add `%s'\n", wfd.cFileName, my_pattern, pathbuf); */ if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && (flags & GLOB_MARK)) { bp[strlen(bp)+1] = 0; bp[strlen(bp)] = slash; } if (add(pathbuf)) return GLOB_NOSPACE; } } } done = !FindNextFile(hf, &wfd); } return 0; }
static int glob2(const char *pattern, char *epathbuf) /* both point *after* the slash */ { const char *pp, *pslash; char *bp; struct ffblk ff; char *my_pattern; int done; if (strcmp(pattern, "...") == 0) { return glob_dirs(pattern+3, epathbuf, 1); } if (strncmp(pattern, "...", 3) == 0 && (pattern[3] == '\\' || pattern[3] == '/')) { slash = pattern[3]; return glob_dirs(pattern+4, epathbuf, 1); } *epathbuf = 0; /* copy as many non-wildcard segments as possible */ pp = pattern; bp = epathbuf; pslash = bp-1; while (1) { if (*pp == ':' || *pp == '\\' || *pp == '/') { pslash = bp; if (strcmp(pp+1, "...") == 0 || (strncmp(pp+1, "...", 3) == 0 && (pp[4] == '/' || pp[4] == '\\'))) { if (*pp != ':') slash = *pp; /* printf("glob2: dots at `%s'\n", pp); */ *bp++ = *pp++; break; } } else if (*pp == '*' || *pp == '?' || *pp == '[') { if (pslash > pathbuf) strncpy(epathbuf, pattern, pslash - pathbuf); pp = pattern + (pslash - epathbuf) + 1; bp = epathbuf + (pslash - epathbuf) + 1; break; } else if (*pp == 0) { break; } else if (islower(*pp)) use_lower_case = 1; else if (isupper(*pp)) use_lower_case = 0; *bp++ = *pp++; } *bp = 0; if (*pp == 0) /* end of pattern? */ { if (wildcard_nesting==0 || __file_exists(pathbuf)) add(pathbuf); return 0; } /* printf("glob2: initial segment is `%s'\n", pathbuf); */ if (wildcard_nesting) { char s = bp[-1]; bp[-1] = 0; if (!__file_exists(pathbuf)) return 0; bp[-1] = s; } for (pslash = pp; *pslash && *pslash != '\\' && *pslash != '/'; pslash++) { if (islower(*pslash)) use_lower_case = 1; else if (isupper(*pslash)) use_lower_case = 0; } if (*pslash) slash = *pslash; my_pattern = (char *)alloca(pslash - pp + 1); if (my_pattern == 0) return 0; strncpy(my_pattern, pp, pslash - pp); my_pattern[pslash-pp] = 0; /* printf("glob2: `%s' `%s'\n", pathbuf, my_pattern); */ if (strcmp(my_pattern, "...") == 0) { glob_dirs(*pslash ? pslash+1 : pslash, bp, 1); return 0; } strcpy(bp, "*.*"); done = findfirst(pathbuf, &ff, FA_RDONLY|FA_SYSTEM|FA_DIREC|FA_ARCH); while (!done) { int i; if (ff.ff_name[0] != '.') { if (use_lower_case) for (i=0; ff.ff_name[i] && i<13; i++) ff.ff_name[i] = tolower(ff.ff_name[i]); if (fnmatch(my_pattern, ff.ff_name, FNM_NOESCAPE|FNM_PATHNAME|FNM_NOCASE) == 0) { strcpy(bp, ff.ff_name); if (*pslash) { char *tp = bp + strlen(bp); *tp++ = *pslash; *tp = 0; /* printf("nest: `%s' `%s'\n", pslash+1, pathbuf); */ wildcard_nesting++; glob2(pslash+1, tp); wildcard_nesting--; } else { /* printf("ffmatch: `%s' matching `%s', add `%s'\n", ff.ff_name, my_pattern, pathbuf); */ if (ff.ff_attrib & FA_DIREC & (flags & GLOB_MARK)) { bp[strlen(bp)] = slash; bp[strlen(bp)+1] = 0; } add(pathbuf); } } } done = findnext(&ff); } return 0; }