X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=fs.c;h=ad8066859b4a02eb8691ef699eac3a5c00ee60c8;hp=ad6e55b50e774a05f7e9eef5bcf87f9c8672996a;hb=1c83503f63868a30f2090ce88e0bc0d76dd6dc16;hpb=c7a8692c9ec712226c377c06ae013f5727c3b470 diff --git a/fs.c b/fs.c index ad6e55b5..ad806685 100644 --- a/fs.c +++ b/fs.c @@ -964,7 +964,7 @@ void FS_AddGameDirectory (const char *dir) strlcpy (fs_gamedir, dir, sizeof (fs_gamedir)); stringlistinit(&list); - listdirectory(&list, dir); + listdirectory(&list, "", dir); stringlistsort(&list); // add any PAK package in the directory @@ -1319,7 +1319,7 @@ qboolean FS_CheckGameDir(const char *gamedir) qboolean success; stringlist_t list; stringlistinit(&list); - listdirectory(&list, va("%s%s/", fs_basedir, gamedir)); + listdirectory(&list, va("%s%s/", fs_basedir, gamedir), ""); success = list.numstrings > 0; stringlistfreecontents(&list); return success; @@ -2527,7 +2527,6 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) stringlist_t dirlist; const char *slash, *backslash, *colon, *separator; char *basepath; - char netpath[MAX_OSPATH]; char temp[MAX_OSPATH]; for (i = 0;pattern[i] == '.' || pattern[i] == ':' || pattern[i] == '/' || pattern[i] == '\\';i++) @@ -2596,27 +2595,94 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet) } else { - // get a directory listing and look at each name - dpsnprintf(netpath, sizeof (netpath), "%s%s", searchpath->filename, basepath); - stringlistinit(&dirlist); - listdirectory(&dirlist, netpath); - for (dirlistindex = 0;dirlistindex < dirlist.numstrings;dirlistindex++) + stringlist_t matchedSet, foundSet; + int resultindex = 0; + const char *start = pattern; + + stringlistinit(&matchedSet); + stringlistinit(&foundSet); + // add a first entry to the set + stringlistappend(&matchedSet, ""); + // iterate through pattern's path + while (*start) { - const char *direntry = dirlist.strings[dirlistindex]; - if (matchpattern(direntry, (char *)pattern, true)) + const char *asterisk, *wildcard, *nextseparator, *prevseparator; + char subpath[MAX_OSPATH]; + char subpattern[MAX_OSPATH]; + + // find the next wildcard + wildcard = strchr(start, '?'); + asterisk = strchr(start, '*'); + if (asterisk && (!wildcard || asterisk < wildcard)) + { + wildcard = asterisk; + } + + if (wildcard) + { + nextseparator = strchr( wildcard, '/' ); + } + else + { + nextseparator = NULL; + } + + if( !nextseparator ) { + nextseparator = start + strlen( start ); + } + + // copy everything up except nextseperator + strlcpy(subpattern, pattern, min(sizeof(subpattern), nextseparator - pattern + 1)); + // find the last / + prevseparator = strrchr( subpattern, '/' ) + 1; + if (!prevseparator) + { + prevseparator = subpattern; + } + // copy everything including the last '/' + strlcpy(subpath, start, min(sizeof(subpath), (prevseparator - subpattern) - (start - pattern) + 1)); + + // prevseparator points to the one right before the wildcard and nextseparator to the one following it (or past the end of the string (at \0)) + // start to prevseparator can be opened now and added to the other resultset + for( dirlistindex = 0 ; dirlistindex < matchedSet.numstrings ; dirlistindex++ ) { + strlcpy( temp, matchedSet.strings[ dirlistindex ], sizeof(temp) ); + strlcat( temp, subpath, sizeof(temp) ); + listdirectory( &foundSet, searchpath->filename, temp ); + } + if( dirlistindex == 0 ) { + break; + } + // reset the current result set + stringlistfreecontents( &matchedSet ); + // match against the pattern + for( dirlistindex = 0 ; dirlistindex < foundSet.numstrings ; dirlistindex++ ) { + const char *direntry = foundSet.strings[ dirlistindex ]; + if (matchpattern(direntry, subpattern, true)) { + stringlistappend( &matchedSet, direntry ); + } + } + stringlistfreecontents( &foundSet ); + + start = nextseparator; + } + + for (dirlistindex = 0;dirlistindex < matchedSet.numstrings;dirlistindex++) + { + const char *temp = matchedSet.strings[dirlistindex]; + if (matchpattern(temp, (char *)pattern, true)) { for (resultlistindex = 0;resultlistindex < resultlist.numstrings;resultlistindex++) - if (!strcmp(resultlist.strings[resultlistindex], direntry)) + if (!strcmp(resultlist.strings[resultlistindex], temp)) break; if (resultlistindex == resultlist.numstrings) { - stringlistappend(&resultlist, direntry); + stringlistappend(&resultlist, temp); if (!quiet && developer_loading.integer) - Con_Printf("SearchDirFile: %s\n", direntry); + Con_Printf("SearchDirFile: %s\n", temp); } } } - stringlistfreecontents(&dirlist); + stringlistfreecontents( &matchedSet ); } }