modlib/file.lua

165 lines
4.4 KiB
Lua
Raw Normal View History

local dir_delim = ...
-- Localize globals
local assert, io, minetest, modlib, string, pcall = assert, io, minetest, modlib, string, pcall
2021-06-17 19:45:08 +02:00
-- Set environment
local _ENV = {}
setfenv(1, _ENV)
_ENV.dir_delim = dir_delim
2021-11-04 17:03:41 +01:00
function get_name(filepath)
2021-12-30 18:49:35 +01:00
return filepath:match("([^%" .. dir_delim .. "]+)$") or filepath
2021-11-04 17:03:41 +01:00
end
function split_extension(filename)
return filename:match"^(.*)%.(.*)$"
2021-09-01 17:07:26 +02:00
end
--! deprecated
get_extension = split_extension
2021-09-01 17:07:26 +02:00
2021-11-06 18:32:58 +01:00
function split_path(filepath)
return modlib.text.split_unlimited(filepath, dir_delim, true)
2021-11-06 18:32:58 +01:00
end
-- 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
2020-02-09 01:39:54 +01:00
function read(filename)
local file, err = io.open(filename, "r")
if file == nil then return nil, err end
2022-07-10 14:31:45 +02:00
local content = file:read"*a"
file:close()
return content
end
function read_binary(filename)
local file, err = io.open(filename, "rb")
if file == nil then return nil, err end
2020-12-22 11:32:35 +01:00
local content = file:read"*a"
file:close()
return content
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
2021-03-30 22:26:30 +02:00
function write_unsafe(filename, new_content)
local file, err = io.open(filename, "w")
if file == nil then return false, err end
2020-12-22 11:32:35 +01:00
file:write(new_content)
file:close()
return true
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
2021-03-30 22:26:30 +02:00
write = minetest and minetest.safe_file_write or write_unsafe
function write_binary_unsafe(filename, new_content)
local file, err = io.open(filename, "wb")
if file == nil then return false, err end
2021-12-28 00:04:58 +01:00
file:write(new_content)
file:close()
return true
end
write_binary = minetest and minetest.safe_file_write or write_binary_unsafe
2020-12-22 11:36:58 +01:00
function ensure_content(filename, ensured_content)
2021-03-27 20:10:49 +01:00
local content = read(filename)
if content ~= ensured_content then
return write(filename, ensured_content)
end
return true
2020-12-22 11:36:58 +01:00
end
2020-02-09 01:39:54 +01:00
function append(filename, new_content)
local file, err = io.open(filename, "a")
if file == nil then return false, err end
2020-12-22 11:32:35 +01:00
file:write(new_content)
file:close()
return true
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
2020-02-09 01:39:54 +01:00
function exists(filename)
local file, err = io.open(filename, "r")
if file == nil then return false, err end
2020-12-22 11:32:35 +01:00
file:close()
return true
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
2020-02-09 01:39:54 +01:00
function create_if_not_exists(filename, content)
2020-12-22 11:32:35 +01:00
if not exists(filename) then
return write(filename, content or "")
2020-12-22 11:32:35 +01:00
end
return false
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
function create_if_not_exists_from_file(filename, src_filename) return create_if_not_exists(filename, read(src_filename)) end
2021-03-04 12:18:26 +01:00
if not minetest then return end
2020-02-09 01:39:54 +01:00
-- Process Bridge Helpers
2020-12-22 11:32:35 +01:00
process_bridges = {}
2020-02-09 01:39:54 +01:00
function process_bridge_build(name, input, output, logs)
2020-12-22 11:32:35 +01:00
if not input or not output or not logs then
minetest.mkdir(minetest.get_worldpath() .. "/bridges/" .. name)
end
input = input or minetest.get_worldpath() .. "/bridges/" .. name .. "/input.txt"
output = output or minetest.get_worldpath() .. "/bridges/" .. name .. "/output.txt"
logs = logs or minetest.get_worldpath() .. "/bridges/" .. name .. "/logs.txt"
-- Clear input
write(input, "")
-- Clear output
write(output, "")
-- Create logs if not exists
create_if_not_exists(logs, "")
process_bridges[name] = {
input = input,
output = output,
logs = logs,
output_file = io.open(output, "a")
}
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
2020-02-09 01:39:54 +01:00
function process_bridge_listen(name, line_consumer, step)
2020-12-22 11:32:35 +01:00
local bridge = process_bridges[name]
2021-03-04 12:18:26 +01:00
modlib.minetest.register_globalstep(step or 0.1, function()
2022-07-17 21:33:54 +02:00
for line in io.lines(bridge.input) do
2020-12-22 11:32:35 +01:00
line_consumer(line)
end
write(bridge.input, "")
end)
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
2020-02-09 01:39:54 +01:00
function process_bridge_serve(name, step)
2020-12-22 11:32:35 +01:00
local bridge = process_bridges[name]
2021-03-04 12:18:26 +01:00
modlib.minetest.register_globalstep(step or 0.1, function()
2020-12-22 11:32:35 +01:00
bridge.output_file:close()
process_bridges[name].output_file = io.open(bridge.output, "a")
end)
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
2020-02-09 01:39:54 +01:00
function process_bridge_write(name, message)
2020-12-22 11:32:35 +01:00
local bridge = process_bridges[name]
bridge.output_file:write(message .. "\n")
2020-02-09 01:39:54 +01:00
end
2020-12-22 11:32:35 +01:00
2020-02-09 01:39:54 +01:00
function process_bridge_start(name, command, os_execute)
2020-12-22 11:32:35 +01:00
local bridge = process_bridges[name]
os_execute(string.format(command, bridge.output, bridge.input, bridge.logs))
2021-06-17 19:45:08 +02:00
end
-- Export environment
2022-07-17 20:34:18 +02:00
return _ENV