From 5b48c165b30e8f7c2262f277611e492a96be8123 Mon Sep 17 00:00:00 2001 From: Hans-Werner Hilse Date: Fri, 14 Nov 2014 16:33:52 +0100 Subject: [PATCH] factor out dump() function, handle reference loops --- frontend/dbg.lua | 4 +-- frontend/docsettings.lua | 51 +++-------------------------- frontend/dump.lua | 69 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 49 deletions(-) create mode 100644 frontend/dump.lua diff --git a/frontend/dbg.lua b/frontend/dbg.lua index d766e03d7..eb540ab84 100644 --- a/frontend/dbg.lua +++ b/frontend/dbg.lua @@ -1,4 +1,4 @@ -local DocSettings = require("docsettings") -- for dump method +local dump = require("dump") local isAndroid, android = pcall(require, "android") local Dbg = { @@ -12,7 +12,7 @@ local function LvDEBUG(lv, ...) local line = "" for i,v in ipairs({...}) do if type(v) == "table" then - line = line .. " " .. DocSettings:dump(v, lv) + line = line .. " " .. dump(v, lv) else line = line .. " " .. tostring(v) end diff --git a/frontend/docsettings.lua b/frontend/docsettings.lua index 76fe705ab..4005a4db5 100644 --- a/frontend/docsettings.lua +++ b/frontend/docsettings.lua @@ -1,5 +1,6 @@ local lfs = require("libs/libkoreader-lfs") local DocSettings = {} +local dump = require("dump") function DocSettings:getHistoryPath(fullpath) return "./history/[" .. fullpath:gsub("(.*/)([^/]+)","%1] %2"):gsub("/","#") .. ".lua" @@ -71,49 +72,6 @@ function DocSettings:delSetting(key) self.data[key] = nil end -function DocSettings:dump(data, max_lv) - local out = {} - self:_serialize(data, out, 0, max_lv) - return table.concat(out) -end - --- simple serialization function, won't do uservalues, functions, loops -function DocSettings:_serialize(what, outt, indent, max_lv) - if not max_lv then - max_lv = math.huge - end - - if indent > max_lv then - return - end - - if type(what) == "table" then - local didrun = false - table.insert(outt, "{") - for k, v in pairs(what) do - if didrun then - table.insert(outt, ",") - end - table.insert(outt, "\n") - table.insert(outt, string.rep("\t", indent+1)) - table.insert(outt, "[") - self:_serialize(k, outt, indent+1, max_lv) - table.insert(outt, "] = ") - self:_serialize(v, outt, indent+1, max_lv) - didrun = true - end - if didrun then - table.insert(outt, "\n") - table.insert(outt, string.rep("\t", indent)) - end - table.insert(outt, "}") - elseif type(what) == "string" then - table.insert(outt, string.format("%q", what)) - elseif type(what) == "number" or type(what) == "boolean" then - table.insert(outt, tostring(what)) - end -end - function DocSettings:flush() -- write serialized version of the data table into -- i) history directory in root directory of koreader @@ -130,13 +88,12 @@ function DocSettings:flush() pcall(table.insert, serials, io.open(self.sidecar_file, "w")) end os.setlocale('C', 'numeric') - local out = {"-- we can read Lua syntax here!\nreturn "} - self:_serialize(self.data, out, 0) - table.insert(out, "\n") - local s_out = table.concat(out) + local s_out = dump(self.data) for _, f_out in ipairs(serials) do if f_out ~= nil then + f_out:write("-- we can read Lua syntax here!\nreturn ") f_out:write(s_out) + f_out:write("\n") f_out:close() end end diff --git a/frontend/dump.lua b/frontend/dump.lua new file mode 100644 index 000000000..2f152ee9a --- /dev/null +++ b/frontend/dump.lua @@ -0,0 +1,69 @@ +--[[ +simple serialization function, won't do uservalues, functions, loops +]] + +local insert = table.insert + +local function _serialize(what, outt, indent, max_lv, history) + if not max_lv then + max_lv = math.huge + end + + if indent > max_lv then + return + end + + history = history or {} + for up, item in ipairs(history) do + if item == what then + insert(outt, "nil --[[ LOOP:\n") + insert(outt, string.rep("\t", indent - up)) + insert(outt, "^------- ]]") + return + end + end + + if type(what) == "table" then + local new_history = { what, unpack(history) } + local didrun = false + insert(outt, "{") + for k, v in pairs(what) do + if didrun then + insert(outt, ",") + end + insert(outt, "\n") + insert(outt, string.rep("\t", indent+1)) + insert(outt, "[") + _serialize(k, outt, indent+1, max_lv, new_history) + insert(outt, "] = ") + _serialize(v, outt, indent+1, max_lv, new_history) + didrun = true + end + if didrun then + insert(outt, "\n") + insert(outt, string.rep("\t", indent)) + end + insert(outt, "}") + elseif type(what) == "string" then + insert(outt, string.format("%q", what)) + elseif type(what) == "number" or type(what) == "boolean" then + insert(outt, tostring(what)) + elseif type(what) == "function" then + insert(outt, "nil --[[ FUNCTION ]]") + elseif type(what) == "nil" then + insert(outt, "nil") + end +end + +--[[ +Serializes whatever is in "data" to a string that is parseable by Lua + +You can optionally specify a maximum recursion depth in "max_lv" +--]] +local function dump(data, max_lv) + local out = {} + _serialize(data, out, 0, max_lv) + return table.concat(out) +end + +return dump