shithub: choc

Download patch

ref: 533e3726f0fdeb0f679fedd96ab4877f80922456
parent: 8f956718644e9f6e59c1ac3e9d527a7799e55d87
author: Fabian Greffrath <fabian@greffrath.com>
date: Tue Nov 22 18:53:48 EST 2016

Try multiple capitalizations when searching for WADs.

Add M_FileCaseExists() that checks if a file exists by trying
multiple different capitalization formats, and change WAD
search code to use this when locating WAD files.

--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -459,13 +459,15 @@
 static char *CheckDirectoryHasIWAD(char *dir, char *iwadname)
 {
     char *filename; 
+    char *probe;
 
     // As a special case, the "directory" may refer directly to an
     // IWAD file if the path comes from DOOMWADDIR or DOOMWADPATH.
 
-    if (DirIsFile(dir, iwadname) && M_FileExists(dir))
+    probe = M_FileCaseExists(dir);
+    if (DirIsFile(dir, iwadname) && probe != NULL)
     {
-        return M_StringDuplicate(dir);
+        return probe;
     }
 
     // Construct the full path to the IWAD if it is located in
@@ -480,9 +482,10 @@
         filename = M_StringJoin(dir, DIR_SEPARATOR_S, iwadname, NULL);
     }
 
-    if (M_FileExists(filename))
+    probe = M_FileCaseExists(filename);
+    if (probe != NULL)
     {
-        return filename;
+        return probe;
     }
 
     free(filename);
@@ -709,13 +712,15 @@
 char *D_FindWADByName(char *name)
 {
     char *path;
+    char *probe;
     int i;
     
     // Absolute path?
 
-    if (M_FileExists(name))
+    probe = M_FileCaseExists(name);
+    if (probe != NULL)
     {
-        return name;
+        return probe;
     }
 
     BuildIWADDirList();
@@ -728,9 +733,10 @@
         // the "directory" may actually refer directly to an IWAD
         // file.
 
-        if (DirIsFile(iwad_dirs[i], name) && M_FileExists(iwad_dirs[i]))
+        probe = M_FileCaseExists(iwad_dirs[i]);
+        if (DirIsFile(iwad_dirs[i], name) && probe != NULL)
         {
-            return M_StringDuplicate(iwad_dirs[i]);
+            return probe;
         }
 
         // Construct a string for the full path
@@ -737,9 +743,10 @@
 
         path = M_StringJoin(iwad_dirs[i], DIR_SEPARATOR_S, name, NULL);
 
-        if (M_FileExists(path))
+        probe = M_FileCaseExists(path);
+        if (probe != NULL)
         {
-            return path;
+            return probe;
         }
 
         free(path);
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -83,6 +83,75 @@
     }
 }
 
+// Check if a file exists by probing for common case variation of its filename.
+// Returns a newly allocated string that the caller is responsible for freeing.
+
+char *M_FileCaseExists(char *path)
+{
+    char *path_dup, *filename, *ext;
+
+    path_dup = M_StringDuplicate(path);
+
+    // 0: actual path
+    if (M_FileExists(path_dup))
+    {
+        return path_dup;
+    }
+
+    filename = strrchr(path_dup, DIR_SEPARATOR);
+    if (filename != NULL)
+    {
+        filename++;
+    }
+    else
+    {
+        filename = path_dup;
+    }
+
+    // 1: lowercase filename, e.g. doom2.wad
+    M_ForceLowercase(filename);
+
+    if (M_FileExists(path_dup))
+    {
+        return path_dup;
+    }
+
+    // 2: uppercase filename, e.g. DOOM2.WAD
+    M_ForceUppercase(filename);
+
+    if (M_FileExists(path_dup))
+    {
+        return path_dup;
+    }
+
+    // 3. uppercase basename with lowercase extension, e.g. DOOM2.wad
+    ext = strrchr(path_dup, '.');
+    if (ext != NULL && ext > filename)
+    {
+        M_ForceLowercase(ext + 1);
+
+        if (M_FileExists(path_dup))
+        {
+            return path_dup;
+        }
+    }
+
+    // 4. lowercase filename with uppercase first letter, e.g. Doom2.wad
+    if (strlen(filename) > 1)
+    {
+        M_ForceLowercase(filename + 1);
+
+        if (M_FileExists(path_dup))
+        {
+            return path_dup;
+        }
+    }
+
+    // 5. no luck
+    free(path_dup);
+    return NULL;
+}
+
 //
 // Determine the length of an open file.
 //
@@ -247,6 +316,24 @@
     for (p = text; *p != '\0'; ++p)
     {
         *p = toupper(*p);
+    }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC M_ForceLowercase
+//
+// Change string to lowercase.
+//
+//---------------------------------------------------------------------------
+
+void M_ForceLowercase(char *text)
+{
+    char *p;
+
+    for (p = text; *p != '\0'; ++p)
+    {
+        *p = tolower(*p);
     }
 }
 
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -30,10 +30,12 @@
 void M_MakeDirectory(char *dir);
 char *M_TempFile(char *s);
 boolean M_FileExists(char *file);
+char *M_FileCaseExists(char *file);
 long M_FileLength(FILE *handle);
 boolean M_StrToInt(const char *str, int *result);
 void M_ExtractFileBase(char *path, char *dest);
 void M_ForceUppercase(char *text);
+void M_ForceLowercase(char *text);
 char *M_StrCaseStr(char *haystack, char *needle);
 char *M_StringDuplicate(const char *orig);
 boolean M_StringCopy(char *dest, const char *src, size_t dest_size);