Mercurial > repo
diff share/lua/5.2/luarocks/persist.lua @ 1132:d137f631bad5
<GreyKnight> (cd luabuild/luarocks-2.0.12; make install)
author | HackBot |
---|---|
date | Fri, 14 Dec 2012 22:24:27 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/lua/5.2/luarocks/persist.lua Fri Dec 14 22:24:27 2012 +0000 @@ -0,0 +1,173 @@ + +--- 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) + +local util = require("luarocks.util") + +--- 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 result, chunk, ran, err + local result = tbl or {} + if setfenv 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 + + 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 + end + return result +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. +-- @param v: the value to be written. +-- @param level number: the indentation level +-- @param sub_order table: optional prioritization table +-- @see write_table +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 + local open, close = "[[", "]]" + local equals = 0 + while v:find(open,1,true) or 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("\"", "\\\"").."\"") + 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. +-- @param tbl table: the table to be written. +-- @param level number: the indentation level +-- @param field_order table: optional prioritization table +write_table = function(out, tbl, level, field_order) + out:write("{") + local sep = "\n" + local indentation = " " + local indent = true + local i = 1 + for k, v, sub_order in util.sortedpairs(tbl, field_order) do + out:write(sep) + 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("] = ") + else + if k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then + out:write(k.." = ") + else + out:write("['"..k:gsub("'", "\\'").."'] = ") + end + end + write_value(out, v, level, sub_order) + end + if sep ~= "\n" then + out:write("\n") + for n = 1,level-1 do out:write(indentation) end + end + out:write("}") +end + +--- Writes a table to an io-like object. +-- @param out userdata: a file object, open for writing. +-- @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) + 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. +-- 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. +-- @param tbl table: the table containing the data to be written +-- @param field_order table: an optional array indicating the order of top-level fields. +-- @return string +function 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) + return table.concat(out.buffer) +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. +-- @param filename string: the output filename +-- @param tbl table: the table containing the data to be written +-- @param field_order table: an optional array indicating the order of top-level fields. +-- @return boolean or (nil, string): true if successful, or nil and a +-- message in case of errors. +function save_from_table(filename, tbl, field_order) + local out = io.open(filename, "w") + if not out then + return nil, "Cannot create file at "..filename + end + write_table(out, tbl, field_order) + out:close() + return true +end