101 lines
3.0 KiB
Lua

--- Utility module for loading files into tables and
-- saving tables into files.
-- Implemented separately to avoid interdependencies,
-- as it is used in the bootstrapping stage of the cfg module.
module("luarocks.persist", package.seeall)
--- 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 or (nil, string): a table with the file's assignments
-- as fields, or nil and a message in case of errors.
function load_into_table(filename, tbl)
assert(type(filename) == "string")
assert(type(tbl) == "table" or not tbl)
local chunk, err = loadfile(filename)
if not chunk then
return nil, err
end
local result = tbl or {}
setfenv(chunk, result)
chunk()
return result
end
--- Write a table as Lua code representing a table to disk
-- (that is, in curly brackets notation).
-- This function handles only numbers, strings and tables
-- are keys (tables are handled recursively).
-- @param out userdata: a file object, open for writing.
-- @param tbl table: the table to be written.
local function write_table(out, tbl, level)
out:write("{")
local size = table.getn(tbl)
local sep = "\n"
local indent = true
local i = 1
for k, v in pairs(tbl) do
out:write(sep)
if indent then
for n = 1,level do out:write(" ") end
end
sep = ",\n"
indent = true
if type(k) == "number" then
if k ~= i then
out:write(tostring(k).."=")
else
i = i + 1
end
indent = false
sep = ", "
elseif type(k) == "table" then
out:write("[")
write_table(out, k, level + 1)
out:write("]=")
else
if k:match("^[a-z_]+$") then
out:write(k.."=")
else
out:write("['"..k:gsub("'", "\\'").."']=")
end
end
if type(v) == "table" then
write_table(out, v, level + 1)
elseif type(v) == "string" then
out:write("'"..v:gsub("'", "\\'").."'")
else
out:write(tostring(v))
end
end
if sep ~= "\n" then
out:write("\n")
for n = 1,level-1 do out:write(" ") end
end
out:write("}")
end
--- Save the contents of a table in a file.
-- Each element of the table is saved as a global assignment.
-- Only numbers, strings and tables (containing numbers, strings
-- or other recursively processed tables) are supported.
-- @return boolean or (nil, string): true if successful, or nil and a
-- message in case of errors.
function save_from_table(filename, tbl)
local out = io.open(filename, "w")
if not out then
return nil, "Cannot create file at "..filename
end
for k, v in pairs(tbl) do
out:write(k.." = ")
write_table(out, v, 1)
out:write("\n")
end
out:close()
return true
end