X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=filematch.c;h=ca0969ce9eff01131e2b678077ead274e1f5b669;hb=e80a362bdb11a1192b828defe4ecc6953a4b8dbe;hp=9ac649134b57beb5d40dce1eb8b2185ba787e3fe;hpb=65c62180df611f0010ad6da4ed294904c0acdecd;p=xonotic%2Fdarkplaces.git diff --git a/filematch.c b/filematch.c index 9ac64913..ca0969ce 100644 --- a/filematch.c +++ b/filematch.c @@ -3,14 +3,17 @@ // LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such... -int matchpattern(char *in, char *pattern) +int matchpattern(char *in, char *pattern, int caseinsensitive) { + int c1, c2; while (*pattern) { switch (*pattern) { + case 0: + return 1; // end of pattern case '?': // match any single character - if (!*in) + if (*in == 0 || *in == '/' || *in == '\\' || *in == ':') return 0; // no match in++; pattern++; @@ -18,28 +21,32 @@ int matchpattern(char *in, char *pattern) case '*': // match anything until following string if (!*in) return 1; // match - while (*pattern == '*') - pattern++; - if (*pattern == '?') - { - // *? (weird) - break; - } - else if (*pattern) - { - // *text (typical) - while (*in && *in != *pattern) - in++; - } - else + pattern++; + while (*in) { - // *null (* at end of pattern) - return 1; + if (*in == '/' || *in == '\\' || *in == ':') + break; + // see if pattern matches at this offset + if (matchpattern(in, pattern, caseinsensitive)) + return 1; + // nope, advance to next offset + in++; } break; default: if (*in != *pattern) - return 0; // no match + { + if (!caseinsensitive) + return 0; // no match + c1 = *in; + if (c1 >= 'A' && c1 <= 'Z') + c1 += 'a' - 'A'; + c2 = *pattern; + if (c2 >= 'A' && c2 <= 'Z') + c2 += 'a' - 'A'; + if (c1 != c2) + return 0; // no match + } in++; pattern++; break; @@ -54,7 +61,7 @@ int matchpattern(char *in, char *pattern) stringlist_t *stringlistappend(stringlist_t *current, char *text) { stringlist_t *newitem; - newitem = Z_Malloc(strlen(text) + 1 + sizeof(stringlist_t)); + newitem = (stringlist_t *)Z_Malloc(strlen(text) + 1 + sizeof(stringlist_t)); newitem->next = NULL; newitem->text = (char *)(newitem + 1); strcpy(newitem->text, text); @@ -78,6 +85,9 @@ stringlist_t *stringlistsort(stringlist_t *start) { int notdone; stringlist_t *current, *previous, *temp2, *temp3, *temp4; + // exit early if there's nothing to sort + if (start == NULL || start->next == NULL) + return start; notdone = 1; while (notdone) { @@ -111,33 +121,37 @@ stringlist_t *stringlistsort(stringlist_t *start) // operating system specific code #ifdef WIN32 #include -stringlist_t *listdirectory(char *path) +stringlist_t *listdirectory(const char *path) { - char pattern[4096]; + char pattern[4096], *c; struct _finddata_t n_file; - long hFile; + long hFile; stringlist_t *start, *current; - strcpy(pattern, path); - strcat(pattern, "\\*"); + strlcpy (pattern, path, sizeof (pattern)); + strlcat (pattern, "*", sizeof (pattern)); // ask for the directory listing handle hFile = _findfirst(pattern, &n_file); - if(hFile != -1) - { - // start a new chain with the the first name - start = current = stringlistappend(NULL, n_file.name); - // iterate through the directory - while (_findnext(hFile, &n_file) == 0) - current = stringlistappend(current, n_file.name); - _findclose(hFile); - // sort the list alphanumerically - return stringlistsort(start); - } - else + if(hFile == -1) return NULL; + // start a new chain with the the first name + start = current = stringlistappend(NULL, n_file.name); + // iterate through the directory + while (_findnext(hFile, &n_file) == 0) + current = stringlistappend(current, n_file.name); + _findclose(hFile); + + // convert names to lowercase because windows does not care, but pattern matching code often does + for (current = start;current;current = current->next) + for (c = current->text;*c;c++) + if (*c >= 'A' && *c <= 'Z') + *c += 'a' - 'A'; + + // sort the list alphanumerically + return stringlistsort(start); } #else #include -stringlist_t *listdirectory(char *path) +stringlist_t *listdirectory(const char *path) { DIR *dir; struct dirent *ent; @@ -145,15 +159,16 @@ stringlist_t *listdirectory(char *path) dir = opendir(path); if (!dir) return NULL; - ent = readdir(dir); - if (!ent) + start = current = NULL; + while ((ent = readdir(dir))) { - closedir(dir); - return NULL; + if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, "..")) + { + current = stringlistappend(current, ent->d_name); + if (!start) + start = current; + } } - start = current = stringlistappend(NULL, ent->d_name); - while((ent = readdir(dir))) - current = stringlistappend(current, ent->d_name); closedir(dir); // sort the list alphanumerically return stringlistsort(start);