summaryrefslogtreecommitdiff
path: root/src/luarocks/core/persist.lua
diff options
context:
space:
mode:
authorMike Vink <mike@pionative.com>2025-02-03 21:29:42 +0100
committerMike Vink <mike@pionative.com>2025-02-03 21:29:42 +0100
commit5155816b7b925dec5d5feb1568b1d7ceb00938b9 (patch)
treedeca28ea15e79f6f804c3d90d2ba757881638af5 /src/luarocks/core/persist.lua
fetch tarballHEADmaster
Diffstat (limited to 'src/luarocks/core/persist.lua')
-rw-r--r--src/luarocks/core/persist.lua81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/luarocks/core/persist.lua b/src/luarocks/core/persist.lua
new file mode 100644
index 0000000..57e7b5d
--- /dev/null
+++ b/src/luarocks/core/persist.lua
@@ -0,0 +1,81 @@
+
+local persist = {}
+
+local require = nil
+--------------------------------------------------------------------------------
+
+--- Load and run a Lua file in an environment.
+-- @param filename string: the name of the file.
+-- @param env table: the environment table.
+-- @return (true, any) or (nil, string, string): true and the return value
+-- of the file, or nil, an error message and an error code ("open", "load"
+-- or "run") in case of errors.
+function persist.run_file(filename, env)
+ local fd, err = io.open(filename)
+ if not fd then
+ return nil, err, "open"
+ end
+ local str, err = fd:read("*a")
+ fd:close()
+ if not str then
+ return nil, err, "open"
+ end
+ str = str:gsub("^#![^\n]*\n", "")
+ local chunk, ran
+ if _VERSION == "Lua 5.1" then -- Lua 5.1
+ chunk, err = loadstring(str, filename)
+ if chunk then
+ setfenv(chunk, env)
+ ran, err = pcall(chunk)
+ end
+ else -- Lua 5.2
+ chunk, err = load(str, filename, "t", env)
+ if chunk then
+ ran, err = pcall(chunk)
+ end
+ end
+ if not chunk then
+ return nil, "Error loading file: "..err, "load"
+ end
+ if not ran then
+ return nil, "Error running file: "..err, "run"
+ end
+ return true, err
+end
+
+--- Load a Lua file containing assignments, storing them in a table.
+-- The global environment is not propagated to the loaded file.
+-- @param filename string: the name of the file.
+-- @param tbl table or nil: if given, this table is used to store
+-- loaded values.
+-- @return (table, table) or (nil, string, string): a table with the file's assignments
+-- as fields and set of undefined globals accessed in file,
+-- or nil, an error message and an error code ("open"; couldn't open the file,
+-- "load"; compile-time error, or "run"; run-time error)
+-- in case of errors.
+function persist.load_into_table(filename, tbl)
+ assert(type(filename) == "string")
+ assert(type(tbl) == "table" or not tbl)
+
+ local result = tbl or {}
+ local globals = {}
+ local globals_mt = {
+ __index = function(t, k)
+ globals[k] = true
+ end
+ }
+ local save_mt = getmetatable(result)
+ setmetatable(result, globals_mt)
+
+ local ok, err, errcode = persist.run_file(filename, result)
+
+ setmetatable(result, save_mt)
+
+ if not ok then
+ return nil, err, errcode
+ end
+ return result, globals
+end
+
+return persist
+