From d4199064ae5ae8023c589f80f12d94e1c6bbc2b5 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Sat, 28 Nov 2020 11:41:03 +0000 Subject: [PATCH] Make fs.combine accept multiple arguments Means we can now do fs.combine("a", "b", "c"). Of course, one may just write "a/b/c" in this case, but it's definitely useful elsewhere. This is /technically/ a breaking change as fs.combine(a, b:gsub(...)) will no longer function (as gsub returns multiple arguments). However, I've done a quick search through GH and my Pastebin archives and can't find any programs which would break. Fingers crossed. --- .../dan200/computercraft/core/apis/FSAPI.java | 24 ++++++++++++++----- .../core/filesystem/FileSystem.java | 4 ++-- .../resources/test-rom/spec/apis/fs_spec.lua | 18 ++++++++------ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/main/java/dan200/computercraft/core/apis/FSAPI.java b/src/main/java/dan200/computercraft/core/apis/FSAPI.java index 4f122ae4c..34a2e0f4c 100644 --- a/src/main/java/dan200/computercraft/core/apis/FSAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/FSAPI.java @@ -5,6 +5,7 @@ */ package dan200.computercraft.core.apis; +import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.ILuaAPI; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; @@ -83,17 +84,28 @@ public class FSAPI implements ILuaAPI } /** - * Combines two parts of a path into one full path, adding separators as + * Combines several parts of a path into one full path, adding separators as * needed. * - * @param pathA The first part of the path. For example, a parent directory path. - * @param pathB The second part of the path. For example, a file name. + * @param arguments The paths to combine. * @return The new path, with separators added between parts as needed. + * @cc.tparam string path The first part of the path. For example, a parent directory path. + * @cc.tparam string ... Additional parts of the path to combine. */ @LuaFunction - public final String combine( String pathA, String pathB ) + public final String combine( IArguments arguments ) throws LuaException { - return fileSystem.combine( pathA, pathB ); + StringBuilder result = new StringBuilder(); + result.append( FileSystem.sanitizePath( arguments.getString( 0 ), true ) ); + + for( int i = 1, n = arguments.count(); i < n; i++ ) + { + String part = FileSystem.sanitizePath( arguments.getString( i ), true ); + if( result.length() != 0 && !part.isEmpty() ) result.append( '/' ); + result.append( part ); + } + + return FileSystem.sanitizePath( result.toString(), true ); } /** @@ -385,8 +397,8 @@ public class FSAPI implements ILuaAPI * * @param path The path to check the free space for. * @return The amount of free space available, in bytes. - * @cc.treturn number|"unlimited" The amount of free space available, in bytes, or "unlimited". * @throws LuaException If the path doesn't exist. + * @cc.treturn number|"unlimited" The amount of free space available, in bytes, or "unlimited". */ @LuaFunction public final Object getFreeSpace( String path ) throws LuaException diff --git a/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java b/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java index 644515e1c..bb6c7149c 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java +++ b/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java @@ -98,7 +98,7 @@ public class FileSystem mounts.remove( sanitizePath( path ) ); } - public synchronized String combine( String path, String childPath ) + public String combine( String path, String childPath ) { path = sanitizePath( path, true ); childPath = sanitizePath( childPath, true ); @@ -479,7 +479,7 @@ public class FileSystem private static final Pattern threeDotsPattern = Pattern.compile( "^\\.{3,}$" ); - private static String sanitizePath( String path, boolean allowWildcards ) + public static String sanitizePath( String path, boolean allowWildcards ) { // Allow windowsy slashes path = path.replace( '\\', '/' ); diff --git a/src/test/resources/test-rom/spec/apis/fs_spec.lua b/src/test/resources/test-rom/spec/apis/fs_spec.lua index 58db9e566..9a861af34 100644 --- a/src/test/resources/test-rom/spec/apis/fs_spec.lua +++ b/src/test/resources/test-rom/spec/apis/fs_spec.lua @@ -39,15 +39,19 @@ describe("The fs library", function() end) end) - describe("fs.list", function() - it("fails on files", function() - expect.error(fs.list, "rom/startup.lua"):eq("/rom/startup.lua: Not a directory") - expect.error(fs.list, "startup.lua"):eq("/startup.lua: Not a directory") + describe("fs.combine", function() + it("removes . and ..", function() + expect(fs.combine("./a/b")):eq("a/b") + expect(fs.combine("a/b", "../c")):eq("a/c") + expect(fs.combine("a", "../c")):eq("c") + expect(fs.combine("a", "../../c")):eq("../c") end) - it("fails on non-existent nodes", function() - expect.error(fs.list, "rom/x"):eq("/rom/x: Not a directory") - expect.error(fs.list, "x"):eq("/x: Not a directory") + it("combines empty paths", function() + expect(fs.combine("a")):eq("a") + expect(fs.combine("a", "")):eq("a") + expect(fs.combine("", "a")):eq("a") + expect(fs.combine("a", "", "b", "c")):eq("a/b/c") end) end)