]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - fs.c
New attempt to change listdirectory.
[xonotic/darkplaces.git] / fs.c
diff --git a/fs.c b/fs.c
index ad6e55b50e774a05f7e9eef5bcf87f9c8672996a..ad8066859b4a02eb8691ef699eac3a5c00ee60c8 100644 (file)
--- 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);
        strlcpy (fs_gamedir, dir, sizeof (fs_gamedir));
 
        stringlistinit(&list);
-       listdirectory(&list, dir);
+       listdirectory(&list, "", dir);
        stringlistsort(&list);
 
        // add any PAK package in the directory
        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);
        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;
        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;
        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++)
        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
                {
                }
                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++)
                                {
                                        for (resultlistindex = 0;resultlistindex < resultlist.numstrings;resultlistindex++)
-                                               if (!strcmp(resultlist.strings[resultlistindex], direntry))
+                                               if (!strcmp(resultlist.strings[resultlistindex], temp))
                                                        break;
                                        if (resultlistindex == resultlist.numstrings)
                                        {
                                                        break;
                                        if (resultlistindex == resultlist.numstrings)
                                        {
-                                               stringlistappend(&resultlist, direntry);
+                                               stringlistappend(&resultlist, temp);
                                                if (!quiet && developer_loading.integer)
                                                if (!quiet && developer_loading.integer)
-                                                       Con_Printf("SearchDirFile: %s\n", direntry);
+                                                       Con_Printf("SearchDirFile: %s\n", temp);
                                        }
                                }
                        }
                                        }
                                }
                        }
-                       stringlistfreecontents(&dirlist);
+                       stringlistfreecontents( &matchedSet );
                }
        }
 
                }
        }