Merge pull request #448 from Talon1024/fix/UnixCaseSensitivity

Attempt to improve Unix filesystem support
This commit is contained in:
Magnus Norddahl 2020-09-12 15:42:29 +02:00 committed by GitHub
commit 626af9e85e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 39 deletions

View file

@ -467,12 +467,13 @@ namespace CodeImp.DoomBuilder.Data
internal override MemoryStream LoadFile(string filename)
{
MemoryStream s = null;
string casecorrectfilename = GetCorrectCaseForFile(filename);
try
try
{
lock(this)
{
s = new MemoryStream(File.ReadAllBytes(Path.Combine(location.location, filename)));
s = new MemoryStream(File.ReadAllBytes(Path.Combine(location.location, casecorrectfilename)));
}
}
catch(Exception e)
@ -514,6 +515,16 @@ namespace CodeImp.DoomBuilder.Data
return tempfile;
}
/// <summary>
/// Returns the correctly cased file from a path/file. This is required for case sensitive file systems.
/// </summary>
/// <param name="filepathname">File name get the the correctly cased name from</param>
/// <returns></returns>
protected override string GetCorrectCaseForFile(string filepathname)
{
return files.GetFileInfo(filepathname).filepathname;
}
#endregion
#region ================== Compiling (mxd)

View file

@ -501,17 +501,7 @@ namespace CodeImp.DoomBuilder.Data
if(filename.IndexOf('.') > -1)
{
string fullname = Path.Combine(pathname, filename);
if(FileExists(fullname))
{
allfilenames = new string[1];
allfilenames[0] = Path.Combine(pathname, filename);
}
else
{
allfilenames = new string[0];
General.ErrorLogger.Add(ErrorType.Warning, "Unable to load DECORATE file \"" + fullname + "\"");
}
allfilenames = GetFileAtPath(filename, pathname, "DECORATE");
}
else
allfilenames = GetAllFilesWithTitle(pathname, filename, false);
@ -545,17 +535,7 @@ namespace CodeImp.DoomBuilder.Data
if (filename.IndexOf('.') > -1)
{
string fullname = Path.Combine(pathname, filename);
if (FileExists(fullname))
{
allfilenames = new string[1];
allfilenames[0] = Path.Combine(pathname, filename);
}
else
{
allfilenames = new string[0];
General.ErrorLogger.Add(ErrorType.Warning, "Unable to load ZSCRIPT file \"" + fullname + "\"");
}
allfilenames = GetFileAtPath(filename, pathname, "ZSCRIPT");
}
else
allfilenames = GetAllFilesWithTitle(pathname, filename, false);
@ -589,17 +569,7 @@ namespace CodeImp.DoomBuilder.Data
if (filename.IndexOf('.') > -1)
{
string fullname = Path.Combine(pathname, filename);
if (FileExists(fullname))
{
allfilenames = new string[1];
allfilenames[0] = Path.Combine(pathname, filename);
}
else
{
allfilenames = new string[0];
General.ErrorLogger.Add(ErrorType.Warning, "Unable to load MODELDEF file \"" + fullname + "\"");
}
allfilenames = GetFileAtPath(filename, pathname, "MODELDEF");
}
else
allfilenames = GetAllFilesWithTitle(pathname, filename, false);
@ -770,7 +740,29 @@ namespace CodeImp.DoomBuilder.Data
// Return result
return images;
}
/// <summary>
/// Gets a correctly cased file from a path/file. This is required for case sensitive file systems.
/// </summary>
/// <param name="filename">File name without path</param>
/// <param name="pathname">Path to the file</param>
/// <param name="type">Type of file (i.e. everything before the first dot)</param>
/// <returns>Array with one element on success, array with no elements on failure</returns>
protected string[] GetFileAtPath(string filename, string pathname, string type)
{
string fullname = Path.Combine(pathname, filename);
if (FileExists(fullname))
{
return new string[1] { fullname };
}
else
{
General.ErrorLogger.Add(ErrorType.Warning, "Unable to load " + type + " file \"" + fullname + "\"");
return new string[0];
}
}
// This copies images from a collection unless they already exist in the list
private static void AddImagesToList(Dictionary<long, ImageData> targetlist, IEnumerable<ImageData> sourcelist)
{
@ -834,6 +826,16 @@ namespace CodeImp.DoomBuilder.Data
}
}
/// <summary>
/// Returns the correctly cased file from a path/file. This is required for case sensitive file systems. For PK3s the input will already have the correct case.
/// </summary>
/// <param name="filepathname">File name get the the correctly cased name from</param>
/// <returns></returns>
protected virtual string GetCorrectCaseForFile(string filepathname)
{
return filepathname;
}
//mxd. Archives and Folders don't have lump indices
internal override MemoryStream LoadFile(string name, int unused)
{

View file

@ -77,7 +77,7 @@ namespace CodeImp.DoomBuilder.IO
}
if(skipfolder) continue;
entries.Add(e.filepathname, e);
AddOrReplaceEntry(e);
}
}
@ -113,7 +113,7 @@ namespace CodeImp.DoomBuilder.IO
continue;
}
entries.Add(e.filepathname, e);
AddOrReplaceEntry(e);
}
}
@ -121,6 +121,31 @@ namespace CodeImp.DoomBuilder.IO
#region ================== Methods
// This checks whether a file is in the entry dictionary, adds it if it
// isn't, and replaces the existing entry if the new entry is lowercase
private void AddOrReplaceEntry(DirectoryFileEntry e)
{
// If the entry is already in the dictionary, add the one with
// greater ordinal value (prefer lowercase)
if(entries.ContainsKey(e.filepathname))
{
// Get the key for the existing entry. It may have a
// different case, since the dictionary is set up to be
// case insensitive.
string existingEntryPath = entries[e.filepathname].filepathname;
if(e.filepathname.CompareTo(existingEntryPath) == -1)
{
entries.Remove(e.filepathname);
entries.Add(e.filepathname, e);
}
}
else
{
// Just add the entry, since it's not in the dictionary yet.
entries.Add(e.filepathname, e);
}
}
// This checks if a given file exists
// The given file path must not be absolute
public bool FileExists(string filepathname)

View file

@ -102,7 +102,7 @@ namespace CodeImp.DoomBuilder.ZDoom
{
case "path":
parser.SkipWhitespace(true);
path = parser.StripTokenQuotes(parser.ReadToken(false)).Replace("/", "\\"); // Don't skip newline
path = parser.StripTokenQuotes(parser.ReadToken(false)).Replace("\\", "/"); // Don't skip newline
if(string.IsNullOrEmpty(path))
{
parser.ReportError("Expected model path");