foxygit / doom Log in
commit 0a85811d624b68684dad0469405a4850907dd03b
Author:     Simon Howard <fraggle@soulsphere.org>
AuthorDate: Mon Oct 29 20:05:55 2018 -0400
Commit:     Simon Howard <fraggle@soulsphere.org>
CommitDate: Mon Oct 29 20:05:55 2018 -0400

    glob: Add flags arg for case insensitive matching.

    It shouldn't matter if a file is named .cfg or .CFG.
---
 src/i_glob.c         | 27 +++++++++++++++++++++------
 src/i_glob.h         |  4 +++-
 src/i_musicpack.c    |  2 +-
 src/strife/m_saves.c |  8 ++++----
 4 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/src/i_glob.c b/src/i_glob.c
index 00a4d0a7..1ec915a6 100644
--- a/src/i_glob.c
+++ b/src/i_glob.c
@@ -17,6 +17,7 @@
 //

 #include <stdlib.h>
+#include <ctype.h>

 #include "i_glob.h"
 #include "m_misc.h"
@@ -74,12 +75,13 @@ static boolean IsDirectory(char *dir, struct dirent *de)
 struct glob_s
 {
     char *glob;
+    int flags;
     DIR *dir;
     char *directory;
     char *last_filename;
 };

-glob_t *I_StartGlob(const char *directory, const char *glob)
+glob_t *I_StartGlob(const char *directory, const char *glob, int flags)
 {
     glob_t *result;

@@ -98,6 +100,7 @@ glob_t *I_StartGlob(const char *directory, const char *glob)

     result->directory = M_StringDuplicate(directory);
     result->glob = M_StringDuplicate(glob);
+    result->flags = flags;
     result->last_filename = NULL;
     return result;
 }
@@ -116,18 +119,29 @@ void I_EndGlob(glob_t *glob)
     free(glob);
 }

-static boolean MatchesGlob(const char *name, const char *glob)
+static boolean MatchesGlob(const char *name, const char *glob, int flags)
 {
+    int n, g;
+
     while (*glob != '\0')
     {
-        if (*glob == '*')
+        n = *name;
+        g = *glob;
+
+        if ((flags & GLOB_FLAG_NOCASE) != 0)
+        {
+            n = tolower(n);
+            g = tolower(g);
+        }
+
+        if (g == '*')
         {
             // To handle *-matching we skip past the * and recurse
             // to check each subsequent character in turn. If none
             // match then the whole match is a failure.
             while (*name != '\0')
             {
-                if (MatchesGlob(name, glob + 1))
+                if (MatchesGlob(name, glob + 1, flags))
                 {
                     return true;
                 }
@@ -135,7 +149,7 @@ static boolean MatchesGlob(const char *name, const char *glob)
             }
             return glob[1] == '\0';
         }
-        else if (*glob != '?' && *name != *glob)
+        else if (g != '?' && n != g)
         {
             // For normal characters the name must match the glob,
             // but for ? we don't care what the character is.
@@ -161,7 +175,8 @@ const char *I_NextGlob(glob_t *glob)
         {
             return NULL;
         }
-    } while (IsDirectory(glob->directory, de) || !MatchesGlob(de->d_name, glob->glob));
+    } while (IsDirectory(glob->directory, de)
+          || !MatchesGlob(de->d_name, glob->glob, glob->flags));

     // Return the fully-qualified path, not just the bare filename.
     free(glob->last_filename);
diff --git a/src/i_glob.h b/src/i_glob.h
index 3a0ee1be..e63227cf 100644
--- a/src/i_glob.h
+++ b/src/i_glob.h
@@ -19,11 +19,13 @@
 #ifndef __I_GLOB__
 #define __I_GLOB__

+#define GLOB_FLAG_NOCASE  0x01
+
 typedef struct glob_s glob_t;

 // Start reading a list of file paths from the given directory which match
 // the given glob pattern. I_EndGlob() must be called on completion.
-glob_t *I_StartGlob(const char *directory, const char *glob);
+glob_t *I_StartGlob(const char *directory, const char *glob, int flags);

 // Finish reading file list.
 void I_EndGlob(glob_t *glob);
diff --git a/src/i_musicpack.c b/src/i_musicpack.c
index 26028b4f..f95e653b 100644
--- a/src/i_musicpack.c
+++ b/src/i_musicpack.c
@@ -947,7 +947,7 @@ static void LoadSubstituteConfigs(void)
     }

     // Load all music packs, by searching for .cfg files.
-    glob = I_StartGlob(musicdir, "*.cfg");
+    glob = I_StartGlob(musicdir, "*.cfg", GLOB_FLAG_NOCASE);
     for (;;)
     {
         path = I_NextGlob(glob);
diff --git a/src/strife/m_saves.c b/src/strife/m_saves.c
index bf9aa9d1..c2f6b7d0 100644
--- a/src/strife/m_saves.c
+++ b/src/strife/m_saves.c
@@ -56,7 +56,7 @@ void ClearTmp(void)
     if(savepathtemp == NULL)
         I_Error("you fucked up savedir man!");

-    glob = I_StartGlob(savepathtemp, "*");
+    glob = I_StartGlob(savepathtemp, "*", 0);
     if (glob == NULL)
         I_Error("ClearTmp: Couldn't open dir %s", savepathtemp);

@@ -86,7 +86,7 @@ void ClearSlot(void)
     if(savepath == NULL)
         I_Error("userdir is fucked up man!");

-    glob = I_StartGlob(savepath, "*");
+    glob = I_StartGlob(savepath, "*", 0);
     if (glob == NULL)
         I_Error("ClearSlot: Couldn't open dir %s", savepath);

@@ -114,7 +114,7 @@ void FromCurr(void)
 {
     glob_t *glob;

-    glob = I_StartGlob(savepathtemp, "*");
+    glob = I_StartGlob(savepathtemp, "*", 0);

     if (glob == NULL)
         I_Error("FromCurr: Couldn't open dir %s", savepathtemp);
@@ -157,7 +157,7 @@ void ToCurr(void)

     // BUG: Rogue copypasta'd this error message, which is why we don't know
     // the real original name of this function.
-    glob = I_StartGlob(savepath, "*");
+    glob = I_StartGlob(savepath, "*", 0);
     if (glob == NULL)
         I_Error("ClearSlot: Couldn't open dir %s", savepath);