101 lines
3.0 KiB
Lua
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
|