diff --git a/SabreTools.IO/ParentablePath.cs b/SabreTools.IO/ParentablePath.cs
index 7fb4616d..5aa5e82f 100644
--- a/SabreTools.IO/ParentablePath.cs
+++ b/SabreTools.IO/ParentablePath.cs
@@ -31,6 +31,10 @@ namespace SabreTools.IO
/// Subpath for the file
public string GetNormalizedFileName(bool sanitize)
{
+ // If the current path is empty, we can't do anything
+ if (string.IsNullOrWhiteSpace(CurrentPath))
+ return null;
+
// Check that we have a combined path first
if (string.IsNullOrWhiteSpace(ParentPath))
{
@@ -70,8 +74,13 @@ namespace SabreTools.IO
/// Complete output path
public string GetOutputPath(string outDir, bool inplace)
{
- // First, we need to ensure the output directory
- outDir = outDir.Ensure();
+ // If the current path is empty, we can't do anything
+ if (string.IsNullOrWhiteSpace(CurrentPath))
+ return null;
+
+ // If the output dir is empty (and we're not inplace), we can't do anything
+ if (string.IsNullOrWhiteSpace(outDir) && !inplace)
+ return null;
// Check if we have a split path or not
bool splitpath = !string.IsNullOrWhiteSpace(ParentPath);
@@ -89,13 +98,20 @@ namespace SabreTools.IO
// If we are processing a path that is coming from a directory and we are outputting to the current directory, we want to get the subfolder to write to
else if (CurrentPath.Length != ParentPath.Length && outDir == Environment.CurrentDirectory)
{
- outDir = Path.GetDirectoryName(Path.Combine(outDir, CurrentPath.Remove(0, Path.GetDirectoryName(ParentPath).Length + 1)));
+ string nextDir = Path.GetDirectoryName(ParentPath);
+ int extraLength = nextDir.EndsWith(':')
+ || nextDir.EndsWith(Path.DirectorySeparatorChar)
+ || nextDir.EndsWith(Path.AltDirectorySeparatorChar) ? 0 : 1;
+ outDir = Path.GetDirectoryName(Path.Combine(outDir, CurrentPath.Remove(0, nextDir.Length + extraLength)));
}
// If we are processing a path that is coming from a directory, we want to get the subfolder to write to
else if (CurrentPath.Length != ParentPath.Length)
{
- outDir = Path.GetDirectoryName(Path.Combine(outDir, CurrentPath.Remove(0, ParentPath.Length + 1)));
+ int extraLength = ParentPath.EndsWith(':')
+ || ParentPath.EndsWith(Path.DirectorySeparatorChar)
+ || ParentPath.EndsWith(Path.AltDirectorySeparatorChar) ? 0 : 1;
+ outDir = Path.GetDirectoryName(Path.Combine(outDir, CurrentPath.Remove(0, ParentPath.Length + extraLength)));
}
// If we are processing a single file from the root of a directory, we just use the output directory
diff --git a/SabreTools.Test/IO/ParentablePathTests.cs b/SabreTools.Test/IO/ParentablePathTests.cs
new file mode 100644
index 00000000..843a23b0
--- /dev/null
+++ b/SabreTools.Test/IO/ParentablePathTests.cs
@@ -0,0 +1,80 @@
+using System;
+
+using SabreTools.IO;
+using Xunit;
+
+namespace SabreTools.Test.IO
+{
+ public class ParentablePathTests
+ {
+ [Theory]
+ [InlineData(null, null, false, null)]
+ [InlineData(null, null, true, null)]
+ [InlineData("", null, false, null)]
+ [InlineData("", null, true, null)]
+ [InlineData(" ", null, false, null)]
+ [InlineData(" ", null, true, null)]
+ [InlineData("C:\\Directory\\Filename.ext", null, false, "Filename.ext")]
+ [InlineData("C:\\Directory\\Filename.ext", null, true, "Filename.ext")]
+ [InlineData("C:\\Directory\\Filename.ext", "C:\\Directory\\Filename.ext", false, "Filename.ext")]
+ [InlineData("C:\\Directory\\Filename.ext", "C:\\Directory\\Filename.ext", true, "Filename.ext")]
+ [InlineData("C:\\Directory\\SubDir\\Filename.ext", "C:\\Directory", false, "SubDir\\Filename.ext")]
+ [InlineData("C:\\Directory\\SubDir\\Filename.ext", "C:\\Directory", true, "SubDir-Filename.ext")]
+ public void NormalizedFileNameTest(string current, string parent, bool sanitize, string expected)
+ {
+ var path = new ParentablePath(current, parent);
+ string actual = path.GetNormalizedFileName(sanitize);
+ Assert.Equal(expected, actual);
+ }
+
+ [Theory]
+ [InlineData(null, null, null, false, null)]
+ [InlineData(null, null, null, true, null)]
+ [InlineData("", null, null, false, null)]
+ [InlineData("", null, null, true, null)]
+ [InlineData(" ", null, null, false, null)]
+ [InlineData(" ", null, null, true, null)]
+ [InlineData("C:\\Directory\\Filename.ext", null, null, false, null)]
+ [InlineData("C:\\Directory\\Filename.ext", null, null, true, "C:\\Directory")]
+ [InlineData("C:\\Directory\\Filename.ext", "C:\\Directory\\Filename.ext", null, false, null)]
+ [InlineData("C:\\Directory\\Filename.ext", "C:\\Directory\\Filename.ext", null, true, "C:\\Directory")]
+ [InlineData("C:\\Directory\\SubDir\\Filename.ext", "C:\\Directory", null, false, null)]
+ [InlineData("C:\\Directory\\SubDir\\Filename.ext", "C:\\Directory", null, true, "C:\\Directory\\SubDir")]
+ [InlineData(null, null, "D:\\OutputDirectory", false, null)]
+ [InlineData(null, null, "D:\\OutputDirectory", true, null)]
+ [InlineData("", null, "D:\\OutputDirectory", false, null)]
+ [InlineData("", null, "D:\\OutputDirectory", true, null)]
+ [InlineData(" ", null, "D:\\OutputDirectory", false, null)]
+ [InlineData(" ", null, "D:\\OutputDirectory", true, null)]
+ [InlineData("C:\\Directory\\Filename.ext", null, "D:\\OutputDirectory", false, "D:\\OutputDirectory")]
+ [InlineData("C:\\Directory\\Filename.ext", null, "D:\\OutputDirectory", true, "C:\\Directory")]
+ [InlineData("C:\\Directory\\Filename.ext", "C:\\Directory\\Filename.ext", "D:\\OutputDirectory", false, "D:\\OutputDirectory")]
+ [InlineData("C:\\Directory\\Filename.ext", "C:\\Directory\\Filename.ext", "D:\\OutputDirectory", true, "C:\\Directory")]
+ [InlineData("C:\\Directory\\SubDir\\Filename.ext", "C:\\Directory", "D:\\OutputDirectory", false, "D:\\OutputDirectory\\SubDir")]
+ [InlineData("C:\\Directory\\SubDir\\Filename.ext", "C:\\Directory", "D:\\OutputDirectory", true, "C:\\Directory\\SubDir")]
+ [InlineData(null, null, "%cd%", false, null)]
+ [InlineData(null, null, "%cd%", true, null)]
+ [InlineData("", null, "%cd%", false, null)]
+ [InlineData("", null, "%cd%", true, null)]
+ [InlineData(" ", null, "%cd%", false, null)]
+ [InlineData(" ", null, "%cd%", true, null)]
+ [InlineData("C:\\Directory\\Filename.ext", null, "%cd%", false, "%cd%")]
+ [InlineData("C:\\Directory\\Filename.ext", null, "%cd%", true, "C:\\Directory")]
+ [InlineData("C:\\Directory\\Filename.ext", "C:\\Directory\\Filename.ext", "%cd%", false, "%cd%")]
+ [InlineData("C:\\Directory\\Filename.ext", "C:\\Directory\\Filename.ext", "%cd%", true, "C:\\Directory")]
+ [InlineData("C:\\Directory\\SubDir\\Filename.ext", "C:\\Directory", "%cd%", false, "%cd%\\Directory\\SubDir")]
+ [InlineData("C:\\Directory\\SubDir\\Filename.ext", "C:\\Directory", "%cd%", true, "C:\\Directory\\SubDir")]
+ public void GetOutputPathTest(string current, string parent, string outDir, bool inplace, string expected)
+ {
+ // Hacks because I can't use environment vars as parameters
+ if (outDir == "%cd%")
+ outDir = Environment.CurrentDirectory.TrimEnd('\\');
+ if (expected?.Contains("%cd%") == true)
+ expected = expected.Replace("%cd%", Environment.CurrentDirectory.TrimEnd('\\'));
+
+ var path = new ParentablePath(current, parent);
+ string actual = path.GetOutputPath(outDir, inplace);
+ Assert.Equal(expected, actual);
+ }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Test/SabreTools.Test.csproj b/SabreTools.Test/SabreTools.Test.csproj
index 7c6a49ee..b1017c22 100644
--- a/SabreTools.Test/SabreTools.Test.csproj
+++ b/SabreTools.Test/SabreTools.Test.csproj
@@ -7,6 +7,7 @@
+
diff --git a/SabreTools/Features/Split.cs b/SabreTools/Features/Split.cs
index 796e9cc2..1d67fc29 100644
--- a/SabreTools/Features/Split.cs
+++ b/SabreTools/Features/Split.cs
@@ -59,6 +59,7 @@ namespace SabreTools.Features
Parser.ParseInto(internalDat, file);
// Get the output directory
+ OutputDir = OutputDir.Ensure();
OutputDir = file.GetOutputPath(OutputDir, GetBoolean(features, InplaceValue));
// Extension splitting
diff --git a/SabreTools/Features/Update.cs b/SabreTools/Features/Update.cs
index a1e15734..bcd201e5 100644
--- a/SabreTools/Features/Update.cs
+++ b/SabreTools/Features/Update.cs
@@ -138,6 +138,9 @@ namespace SabreTools.Features
List inputPaths = PathTool.GetFilesOnly(Inputs, appendparent: true);
List basePaths = PathTool.GetFilesOnly(GetList(features, BaseDatListValue));
+ // Ensure the output directory
+ OutputDir = OutputDir.Ensure();
+
// If we're in standard update mode, run through all of the inputs
if (updateMode == UpdateMode.None)
{