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.
This commit is contained in:
Fabian Greffrath 2016-11-22 23:53:48 +01:00 committed by Simon Howard
parent 8f95671864
commit 533e3726f0
3 changed files with 106 additions and 10 deletions

View file

@ -459,13 +459,15 @@ static boolean DirIsFile(char *path, char *filename)
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 @@ static char *CheckDirectoryHasIWAD(char *dir, char *iwadname)
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 @@ static void BuildIWADDirList(void)
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,18 +733,20 @@ char *D_FindWADByName(char *name)
// 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
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);

View file

@ -83,6 +83,75 @@ boolean M_FileExists(char *filename)
}
}
// 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.
//
@ -250,6 +319,24 @@ void M_ForceUppercase(char *text)
}
}
//---------------------------------------------------------------------------
//
// PROC M_ForceLowercase
//
// Change string to lowercase.
//
//---------------------------------------------------------------------------
void M_ForceLowercase(char *text)
{
char *p;
for (p = text; *p != '\0'; ++p)
{
*p = tolower(*p);
}
}
//
// M_StrCaseStr
//

View file

@ -30,10 +30,12 @@ int M_ReadFile(char *name, byte **buffer);
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);