local statewalk = require("luatraverse");
local format = string.format;
local type = type;
local tostring = tostring;
local io, os = io, os;
local getsize;
do
local ok, ret = pcall(require, "getsize");
if ok then
--luacheck: ignore 143/debug
if type(ret) == "function" then
getsize = ret;
elseif debug.getsize then
getsize = debug.getsize;
end
end
end
local function dump_state(f, config)
if io.type(f) ~= "file" then
local err;
f, err = io.open(f, "w+");
if not f then return false, err; end
end
local metadata = config and config.metadata;
local start_time = os.time();
f:write("# Lua state graph", "\n");
f:write("# Generated by dump.lua v2.1", "\n");
f:write("# at ", os.date("!%F %R UTC", start_time), "\n");
if metadata then
local keys = {};
for k in pairs(metadata) do
table.insert(keys, k);
end
table.sort(keys);
if #keys > 0 then
for _, k in ipairs(keys) do
f:write("## ", k, ": ", metadata[k], "\n");
end
end
end
local seenobjects, id = {}, 0;
local function edge(from, to, how, value)
if from and (not seenobjects[from] or seenobjects[from] == true) then
id = id + 1;
seenobjects[from] = id;
f:write("V:", id, ":", type(from), ":", (getsize and getsize(from)) or "?", "\n");
end
if not seenobjects[to] or seenobjects[to] == true then
id = id + 1;
seenobjects[to] = id;
f:write("V:", id, ":", type(to), ":", (getsize and getsize(to)) or "?", "\n");
end
if seenobjects[from] == true or seenobjects[to] == true then
return;
end
local value_rep = (value and format("%q", tostring(value))) or "?";
f:write("E:", seenobjects[from] or "?", ":", seenobjects[to], ":", tostring(how or "?"), ":", value_rep, "\n");
end
local ignore = {f, dump_state, statewalk, seenobjects, edge};
statewalk.traverse({edge=edge}, ignore, seenobjects);
f:write("# Completed in ", tostring(os.time() - start_time), "s", "\n");
f:close();
end
return {
dump_state = dump_state;
};