Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/torch/luajit-rocks.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'luarocks/src/luarocks/persist.lua')
-rw-r--r--luarocks/src/luarocks/persist.lua151
1 files changed, 87 insertions, 64 deletions
diff --git a/luarocks/src/luarocks/persist.lua b/luarocks/src/luarocks/persist.lua
index 9d601a4..354b17c 100644
--- a/luarocks/src/luarocks/persist.lua
+++ b/luarocks/src/luarocks/persist.lua
@@ -9,60 +9,85 @@ package.loaded["luarocks.persist"] = persist
local util = require("luarocks.util")
+--- 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.
+local function 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 or (nil, string): a table with the file's assignments
--- as fields, or nil and a message in case of errors.
+-- @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, chunk, ran, err
- result = tbl or {}
+ local result = tbl or {}
local globals = {}
local globals_mt = {
- __index = function(t, n)
- globals[n] = true
- return rawget(t, n)
+ __index = function(t, k)
+ globals[k] = true
end
}
local save_mt = getmetatable(result)
setmetatable(result, globals_mt)
- if _VERSION == "Lua 5.1" then -- Lua 5.1
- chunk, err = loadfile(filename)
- if chunk then
- setfenv(chunk, result)
- ran, err = pcall(chunk)
- end
- else -- Lua 5.2
- chunk, err = loadfile(filename, "t", result)
- if chunk then
- ran, err = pcall(chunk)
- end
- end
- setmetatable(result, save_mt)
- if not chunk then
- if err:sub(1,5) ~= filename:sub(1,5) then
- return false, err
- end
- return nil, "Error loading file: "..err
- end
- if not ran then
- return nil, "Error running file: "..err
+ local ok, err, errcode = run_file(filename, result)
+
+ setmetatable(result, save_mt)
+
+ if not ok then
+ return nil, err, errcode
end
return result, globals
end
local write_table
---- Write a value as Lua code, invoking write_table.
--- This function handles only numbers, strings and tables
--- are keys (tables are handled recursively).
--- @param out userdata: a file object, open for writing.
+--- Write a value as Lua code.
+-- This function handles only numbers and strings, invoking write_table
+-- to write tables.
+-- @param out table or userdata: a writer object supporting :write() method.
-- @param v: the value to be written.
-- @param level number: the indentation level
-- @param sub_order table: optional prioritization table
@@ -71,28 +96,27 @@ local function write_value(out, v, level, sub_order)
if type(v) == "table" then
write_table(out, v, level + 1, sub_order)
elseif type(v) == "string" then
- if v:match("\n") then
+ if v:match("[\r\n]") then
local open, close = "[[", "]]"
local equals = 0
- while v:find(open,1,true) or v:find(close,1,true) do
+ while v:find(close, 1, true) do
equals = equals + 1
local eqs = ("="):rep(equals)
open, close = "["..eqs.."[", "]"..eqs.."]"
end
out:write(open.."\n"..v..close)
else
- out:write("\""..v:gsub("\"", "\\\"").."\"")
+ out:write("\""..v:gsub("\\", "\\\\"):gsub("\"", "\\\"").."\"")
end
else
out:write(tostring(v))
end
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.
+--- Write a table as Lua code in curly brackets notation to a writer object.
+-- Only numbers, strings and tables (containing numbers, strings
+-- or other recursively processed tables) are supported.
+-- @param out table or userdata: a writer object supporting :write() method.
-- @param tbl table: the table to be written.
-- @param level number: the indentation level
-- @param field_order table: optional prioritization table
@@ -107,28 +131,29 @@ write_table = function(out, tbl, level, field_order)
if indent then
for n = 1,level do out:write(indentation) 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("] = ")
+
+ if k == i then
+ i = i + 1
else
- if k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then
- out:write(k.." = ")
+ if type(k) == "string" and k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then
+ out:write(k)
else
- out:write("['"..k:gsub("'", "\\'").."'] = ")
+ out:write("[")
+ write_value(out, k, level)
+ out:write("]")
end
+
+ out:write(" = ")
end
+
write_value(out, v, level, sub_order)
+ if type(k) == "number" then
+ sep = ", "
+ indent = false
+ else
+ sep = ",\n"
+ indent = true
+ end
end
if sep ~= "\n" then
out:write("\n")
@@ -137,18 +162,16 @@ write_table = function(out, tbl, level, field_order)
out:write("}")
end
---- Writes a table to an io-like object.
--- @param out userdata: a file object, open for writing.
+--- Write a table as series of assignments to a writer object.
+-- @param out table or userdata: a writer object supporting :write() method.
-- @param tbl table: the table to be written.
-- @param field_order table: optional prioritization table
--- @return userdata The file object originally passed in as the `out` parameter.
-local function write_table(out, tbl, field_order)
+local function write_table_as_assignments(out, tbl, field_order)
for k, v, sub_order in util.sortedpairs(tbl, field_order) do
out:write(k.." = ")
write_value(out, v, 0, sub_order)
out:write("\n")
end
- return out
end
--- Save the contents of a table to a string.
@@ -161,7 +184,7 @@ end
function persist.save_from_table_to_string(tbl, field_order)
local out = {buffer = {}}
function out:write(data) table.insert(self.buffer, data) end
- write_table(out, tbl, field_order)
+ write_table_as_assignments(out, tbl, field_order)
return table.concat(out.buffer)
end
@@ -179,7 +202,7 @@ function persist.save_from_table(filename, tbl, field_order)
if not out then
return nil, "Cannot create file at "..filename
end
- write_table(out, tbl, field_order)
+ write_table_as_assignments(out, tbl, field_order)
out:close()
return true
end