1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-08-28 08:12:18 +00:00

Fix the signature of loadfile

Lua 5.2+ uses loadfile(filename, mode, env), not loadfile(filename,
env). While this is a minor incompatibility, it'd be nice to be
consistent as much as possible.

We try to handle the incorrect case too, as obviously we don't want to
break existing programs.
This commit is contained in:
SquidDev 2019-07-12 22:04:28 +01:00
parent bafab1ac07
commit f9929cb27d
6 changed files with 49 additions and 19 deletions

View File

@ -539,23 +539,28 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
return sLine return sLine
end end
function loadfile( _sFile, _tEnv ) function loadfile( filename, mode, env )
expect(1, _sFile, "string") -- Support the previous `loadfile(filename, env)` form instead.
expect(2, _tEnv, "table", "nil") if type(mode) == "table" and env == nil then
mode, env = nil, mode
local file = fs.open( _sFile, "r" )
if file then
local func, err = load( file.readAll(), "@" .. fs.getName( _sFile ), "t", _tEnv )
file.close()
return func, err
end end
return nil, "File not found"
expect(1, filename, "string")
expect(2, mode, "string", "nil")
expect(3, env, "table", "nil")
local file = fs.open( filename, "r" )
if not file then return nil, "File not found" end
local func, err = load( file.readAll(), "@" .. fs.getName( filename ), mode, env )
file.close()
return func, err
end end
function dofile( _sFile ) function dofile( _sFile )
expect(1, _sFile, "string") expect(1, _sFile, "string")
local fnFile, e = loadfile( _sFile, _G ) local fnFile, e = loadfile( _sFile, nil, _G )
if fnFile then if fnFile then
return fnFile() return fnFile()
else else
@ -571,7 +576,7 @@ function os.run( _tEnv, _sPath, ... )
local tArgs = table.pack( ... ) local tArgs = table.pack( ... )
local tEnv = _tEnv local tEnv = _tEnv
setmetatable( tEnv, { __index = _G } ) setmetatable( tEnv, { __index = _G } )
local fnFile, err = loadfile( _sPath, tEnv ) local fnFile, err = loadfile( _sPath, nil, tEnv )
if fnFile then if fnFile then
local ok, err = pcall( function() local ok, err = pcall( function()
fnFile( table.unpack( tArgs, 1, tArgs.n ) ) fnFile( table.unpack( tArgs, 1, tArgs.n ) )
@ -605,7 +610,7 @@ function os.loadAPI( _sPath )
local tEnv = {} local tEnv = {}
setmetatable( tEnv, { __index = _G } ) setmetatable( tEnv, { __index = _G } )
local fnAPI, err = loadfile( _sPath, tEnv ) local fnAPI, err = loadfile( _sPath, nil, tEnv )
if fnAPI then if fnAPI then
local ok, err = pcall( fnAPI ) local ok, err = pcall( fnAPI )
if not ok then if not ok then

View File

@ -56,7 +56,7 @@ local function createShellEnv( sDir )
sPath = fs.combine(sDir, sPath) sPath = fs.combine(sDir, sPath)
end end
if fs.exists(sPath) and not fs.isDir(sPath) then if fs.exists(sPath) and not fs.isDir(sPath) then
local fnFile, sError = loadfile( sPath, tEnv ) local fnFile, sError = loadfile( sPath, nil, tEnv )
if fnFile then if fnFile then
return fnFile, sPath return fnFile, sPath
else else

View File

@ -91,7 +91,7 @@ public class ComputerTestDelegate
try( WritableByteChannel channel = mount.openChannelForWrite( "startup.lua" ); try( WritableByteChannel channel = mount.openChannelForWrite( "startup.lua" );
Writer writer = Channels.newWriter( channel, StandardCharsets.UTF_8.newEncoder(), -1 ) ) Writer writer = Channels.newWriter( channel, StandardCharsets.UTF_8.newEncoder(), -1 ) )
{ {
writer.write( "loadfile('test/mcfly.lua', _ENV)('test/spec') cct_test.finish()" ); writer.write( "loadfile('test/mcfly.lua', nil, _ENV)('test/spec') cct_test.finish()" );
} }
computer = new Computer( new BasicEnvironment( mount ), term, 0 ); computer = new Computer( new BasicEnvironment( mount ), term, 0 );

View File

@ -40,7 +40,7 @@ public class ComputerBootstrap
{ {
MemoryMount mount = new MemoryMount() MemoryMount mount = new MemoryMount()
.addFile( "test.lua", program ) .addFile( "test.lua", program )
.addFile( "startup", "assertion.assert(pcall(loadfile('test.lua', _ENV))) os.shutdown()" ); .addFile( "startup", "assertion.assert(pcall(loadfile('test.lua', nil, _ENV))) os.shutdown()" );
run( mount, x -> { } ); run( mount, x -> { } );
} }

View File

@ -501,7 +501,7 @@ do
if fs.isDir(file) then if fs.isDir(file) then
run_in(file) run_in(file)
elseif file:sub(-#suffix) == suffix then elseif file:sub(-#suffix) == suffix then
local fun, err = loadfile(file, env) local fun, err = loadfile(file, nil, env)
if not fun then if not fun then
do_test { name = file:sub(#root_dir + 2), error = { message = err } } do_test { name = file:sub(#root_dir + 2), error = { message = err } }
else else

View File

@ -16,18 +16,43 @@ describe("The Lua base library", function()
end) end)
describe("loadfile", function() describe("loadfile", function()
local function make_file()
local tmp = fs.open("test-files/out.lua", "w")
tmp.write("return _ENV")
tmp.close()
end
it("validates arguments", function() it("validates arguments", function()
loadfile("") loadfile("")
loadfile("", {}) loadfile("", "")
loadfile("", "", {})
expect.error(loadfile, nil):eq("bad argument #1 (expected string, got nil)") expect.error(loadfile, nil):eq("bad argument #1 (expected string, got nil)")
expect.error(loadfile, "", false):eq("bad argument #2 (expected table, got boolean)") expect.error(loadfile, "", false):eq("bad argument #2 (expected string, got boolean)")
expect.error(loadfile, "", "", false):eq("bad argument #3 (expected table, got boolean)")
end) end)
it("prefixes the filename with @", function() it("prefixes the filename with @", function()
local info = debug.getinfo(loadfile("/rom/startup.lua"), "S") local info = debug.getinfo(loadfile("/rom/startup.lua"), "S")
expect(info):matches { short_src = "startup.lua", source = "@startup.lua" } expect(info):matches { short_src = "startup.lua", source = "@startup.lua" }
end) end)
it("loads a file with the global environment", function()
make_file()
expect(loadfile("test-files/out.lua")()):eq(_G)
end)
it("loads a file with a specific environment", function()
make_file()
local env = {}
expect(loadfile("test-files/out.lua", nil, env)()):eq(env)
end)
it("supports the old-style argument form", function()
make_file()
local env = {}
expect(loadfile("test-files/out.lua", env)()):eq(env)
end)
end) end)
describe("dofile", function() describe("dofile", function()