Add dump.lua to write state graphs to file v2.1

Wed, 23 Sep 2020 14:25:20 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Wed, 23 Sep 2020 14:25:20 +0100
changeset 13
9bd292b35f23
parent 12
e3e3cbe544ec
child 14
3931ed7eb9ce

Add dump.lua to write state graphs to file

dump.lua file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dump.lua	Wed Sep 23 14:25:20 2020 +0100
@@ -0,0 +1,72 @@
+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;
+};

mercurial