Add file.with_open to ensure :close() is called

This commit is contained in:
Lars Mueller 2023-06-10 14:50:30 +02:00
parent 14de9219b7
commit 91a4ee521f

@ -1,6 +1,6 @@
local dir_delim = ... local dir_delim = ...
-- Localize globals -- Localize globals
local io, minetest, modlib, string = io, minetest, modlib, string local assert, io, minetest, modlib, string, pcall = assert, io, minetest, modlib, string, pcall
-- Set environment -- Set environment
local _ENV = {} local _ENV = {}
@ -24,6 +24,20 @@ end
-- concat_path is set by init.lua to avoid code duplication -- concat_path is set by init.lua to avoid code duplication
-- Lua 5.4 has `<close>` for this, but we're restricted to 5.1,
-- so we need to roll our own `try f = io.open(...); return func(f) finally f:close() end`.
function with_open(filename, mode, func --[[function(file), called with `file = io.open(filename, mode)`]])
local file = assert(io.open(filename, mode or "r"))
-- Throw away the stacktrace. The alternative would be to use `xpcall`
-- to bake the stack trace into the error string using `debug.traceback`.
-- Lua will have prepended `<source>:<line>:` already however.
return (function(status, ...)
file:close()
assert(status, ...)
return ...
end)(pcall(func, file))
end
function read(filename) function read(filename)
local file, err = io.open(filename, "r") local file, err = io.open(filename, "r")
if file == nil then return nil, err end if file == nil then return nil, err end