]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - filematch.c
made darkplaces compile successfully with g++ to test for errors C doesn't care about...
[xonotic/darkplaces.git] / filematch.c
index e3e35c800da5000dbb7f4158482f6451e7c6fc2e..ca0969ce9eff01131e2b678077ead274e1f5b669 100644 (file)
@@ -10,8 +10,10 @@ int matchpattern(char *in, char *pattern, int caseinsensitive)
        {
                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++;
@@ -19,23 +21,16 @@ int matchpattern(char *in, char *pattern, int caseinsensitive)
                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:
@@ -66,7 +61,7 @@ int matchpattern(char *in, char *pattern, int caseinsensitive)
 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);
@@ -90,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)
        {
@@ -123,41 +121,37 @@ stringlist_t *stringlistsort(stringlist_t *start)
 // operating system specific code
 #ifdef WIN32
 #include <io.h>
-stringlist_t *listdirectory(char *path)
+stringlist_t *listdirectory(const char *path)
 {
        char pattern[4096], *c;
        struct _finddata_t n_file;
-    long hFile;
+       long hFile;
        stringlist_t *start, *current;
        strlcpy (pattern, path, sizeof (pattern));
-       strlcat (pattern, "\\*", 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);
+       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';
+       // 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
-               start = stringlistsort(start);
-               return start;
-       }
-       else
-               return NULL;
+       // sort the list alphanumerically
+       return stringlistsort(start);
 }
 #else
 #include <dirent.h>
-stringlist_t *listdirectory(char *path)
+stringlist_t *listdirectory(const char *path)
 {
        DIR *dir;
        struct dirent *ent;
@@ -165,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);