Modul:Sandlådan/SM5POR/Diag

Från Wikipedia

Dokumentation [visa] [redigera] [historik] [rensa sidcachen]


Introduction[redigera wikitext]

Technical reference[redigera wikitext]

Exported functions[redigera wikitext]

diag[redigera wikitext]

diag.diag( frame )

Given the calling module frame, parses the diag calling option (if found), sets the module diagnostic level accordingly, and returns its resulting value (possibly unchanged) to the caller.

The diagnostic level default value is 0.

Diagnostic levels 1 and 2 are not used internally by the Qutil module, but reserved for the calling library or application. The remaining levels are used as follows:

Level Use
3 Selected diagnostic messages are produced, but not displayed.
4 Messages produced on level 3 are displayed.
5 In addition to the level 3-4 production and display of selected diagnostic messages, detailed diagnostic messages are produced in most parts of the code, but not displayed.
6 Messages produced on level 5 are displayed.

The intention of producing diagnostic messages internally without also showing them is to allow for fine-tuned debugging or optimization procedures, where the performance issue or error condition may be related to the diagnostic code itself.

License[redigera wikitext]

The software module described here, as well as this documentation, is available under CC0 (effectively public domain). To avoid confusion and duplicated work due to multiple forks or versions being distributed simultaneously, you are still both welcome and encouraged to contact the author to discuss potential coordination or cooperation.

local nilindex = function(maybe)
	if maybe then
		return maybe
	else
		return {}
	end
end

local tohtml = function(tag, text)
	local element = mw.html.create(tag)
	element
		:wikitext(text)
	return tostring(element)
end

local xxhtml = function(text)
	local td = mw.html.create("td")
	td
		:wikitext(text)
	return tostring(td)
end

local tocell = function(tag, att, v)
	local htcell = mw.html.create(tag)
	htcell
		:attr(att)
		:wikitext(v)
	return tostring(htcell)
end

local tohtmltr = function(tag, row, colspan, rowspan)
	local r = {}
	local csi = nilindex(colspan)
	local rsi = nilindex(rowspan)
	local attr
	for k, v in pairs(row) do
		cs = csi[k]
		rs = rsi[k]
		attr = {}
		if cs then
			attr["colspan"] = cs
		end
		if rs then
			attr["rowspan"] = rs
		end
		r[k] = tocell(tag, attr, tostring(v))
	end
	local httr = mw.html.create("tr")
	httr
		:wikitext(table.concat(r))
	return tostring(httr)
end

local totsect = function(tag, text)
	local element = mw.html.create(tag)
	element
		:wikitext(text)
	return tostring(element)
end


local tohtsect = function(stag, ctag, rows, colspan, rowspan)
	local s = {}
	local cs = nilindex(colspan)
	local rs = nilindex(rowspan)
	for k, v in pairs(rows) do
		s[k] = tohtmltr(ctag, v, cs[k], rs[k])
	end
	return tohtml(stag, table.concat(s))
end

local tohtmltable = function(crhdr, crtbl)
	local hthead
	local htbody
	if crhdr then
		hdrrows = crhdr
		hthead = tohtsect("thead", "th", crhdr.data, crhdr.cols, crhdr.rows)
	else
		hthead = ""
	end
	htbody = tohtsect("tbody", "td", crtbl.data, crtbl.cols, crtbl.rows)
	return tohtml("table", tostring(hthead .. htbody))
end

local cstr = function(v)
	if v then
		r = tostring(v)
	else
		r = "nil"
	end
	return r
end

local numval = function(x, l)
	local n = tonumber(x)
	local s
	if l and x then
		s = #x
	else
		s = 0
	end
	local r
	if n then
		if l and x then
			r = "[" .. tostring(n) .. "/" .. tostring(s) .. "] "
		else
			r = "[" .. tostring(n) .. "/?] "
		end
	else
		if l and x then
			r = "[?/" .. tostring(s) .. "] "
		else
			r = ""
		end
	end
	return r
end

local showvar = function(hook, depth, name, x)
	local r
	local kf = hook[type(name)]
	local vf = hook[type(x)]
	if hook["verbose"] and name then
		r = cstr(kf(hook, depth, name)) .. ": " .. cstr(vf(hook, depth, x))
	else
		r = cstr(vf(hook, depth, x))
	end
	return r
end

local shownil = function(hook, depth, x)
	if hook["verbose"] then
		return numval(x, true) .. "nil"
	else
		return "nil"
	end
end

local shownumber = function(hook, depth, x)
	if hook["verbose"] then
		return numval(x) .. tostring(x)
	else
		return tostring(x)
	end
end

local showstring = function(hook, depth, x)
	if hook["verbose"] then
		return numval(x, true) .. '"' .. tostring(x) .. '"'
	else
		return '"' .. tostring(x) .. '"'
	end
end

local showboolean = function(hook, depth, x)
	if hook["verbose"] then
		return numval(x) .. tostring(x)
	else
		return tostring(x)
	end
end

local showtable = function(hook, depth, x)
	local r
	local r0
	local t = {}
	local i = 0
	local k
	local v
	local verbose = hook["verbose"]
	for k, v in pairs(x) do
		i = i + 1
		if depth > 0 then
			if verbose then
				t[i] = tohtml("li", showvar(hook, depth-1, "[" .. type(k) .. "]", v))
			else
				t[i] = tohtml("span", showvar(hook, depth-1, nil, k) .. ": " .. showvar(hook, depth-1, nil, v))
			end
		end
	end
	if depth > 0 then
		if verbose then
			r0 = tohtml("ul", table.concat(t))
		else
			r0 = tohtml("span", "{" .. table.concat(t, ", ") .. "}")
		end
	else
		r0 = " ..."
	end
	if verbose then
		r = numval(x, true) .. "[" .. tostring(i) .. "]" .. r0
	else
		r = r0
	end
	return r
end

local showfunction = function(hook, depth, x)
	return numval(x) .. tostring(x)
end

local showhook = {}

showhook["nil"] = shownil
showhook["number"] = shownumber
showhook["string"] = showstring
showhook["boolean"] = showboolean
showhook["table"] = showtable
showhook["function"] = showfunction

showhook["verbose"] = false

local diag = {}

local testtr = function(a, b, c)
	local td = {}
	td[1] = tohtml("td", a)
	td[2] = tohtml("td", b)
	td[3] = tohtml("td", c)
	return tohtml("tr", table.concat(td))
end

diag.nuhtml = function(text)
	local row = {}
	local tr
	local cell
	local td
	for j = 1, 2 do
		tr = mw.html.create("tr")
		cell = {}
		for i = 1, 3 do
			td = mw.html.create("td")
			td
				:wikitext(tostring(j*10+i))
			cell[i] = tostring(td)
		end
		tr
			:wikitext(table.concat(cell))
		row[j] = tostring(td)
	end
	return table.concat(row)
end

diag.testhtml = function()
	local tr = {}

	tr[1] = testtr("1", "2", "3")
	tr[2] = testtr("A", "B", "C")

--	local tbody = tohtml("tbody", tostring(table.concat(tr)))
	return tohtml("html", table.concat(tr))
end

diag.diag = function(frame)
	local val = frame.args["diag"]
	if val then
		local level = tonumber(val)
		if level then
			diaglevel = level
		end
	end
	return diaglevel
end

diag.env = function(frame)
	local r
	if frame.args["loaded"] then
		r = "loaded"
--		r = diag.var("modules", package.loaded)
	else
		r = diag.var("frame", frame) -- .. diag.context(frame)
	end
	return r
end

local sysvar = {
	loaded = package.loaded,
	loaders = package.loaders,
	preload = package.preload
}
	
local extdisp = {}

extdisp.env = function(v)
	local var = sysvar[v]
	local r
	if var then
		r = showvar(showhook, 1, v, var)
	else
		r = "unknown variable " .. v
	end
	return r
end

extdisp.global = function(v)
	local var = _G
	local vardef = true
	local k
	for k in mw.text.gsplit(v, "%.") do
		if var then
			var = var[k]
		else
			vardef = false
		end
	end
	local r
	if vardef then
		r = showvar(showhook, 4, v, var)
	else
		r = "unknown variable " .. v
	end
	return r
end

diag.ext = function(frame)
	local k
	local v
	local t = {}
	local i = 0
	for k, v in pairs(frame.args) do
		i = i + 1
		local f = extdisp[k]
		if f then
			t[i] = f(v)
		else
			t[i] = "unknown function " .. k
		end
	end
	return tohtml("div", table.concat(t))
end

diag.global = function(frame)
	local k
	local v
	local t = {}
	local i = 0
	for k, v in pairs(frame.args) do
		i = i + 1
		local vardef
		local varname
		local varvalue
		if type(k) == "string" then
			vardef = _G[k]
			varname = k .. "." .. v
			if vardef then
				varvalue = _G[k][v]
			end
		else
			vardef = true
			varname = v
			varvalue = _G[v]
		end
		if vardef then
			t[i] = showvar(showhook, 4, varname, varvalue)
		else
			t[i] = varname .. " (undefined)"
		end
	end
	return tohtml("div", table.concat(t))
end

diag.lualist = function(x)
	local t = {}
	for k = 1, #x do
		t[k] = showvar(showhook, 16, nil, x[k])
	end
	return "{" .. table.concat(t, ", ") .. "}"
end

diag.list = function(x)
	local k
	local v
	local t = {}
	local i = 0
	for k, v in pairs(x) do
		i = i + 1
		t[i] = tohtml("div", showvar(showhook, 16, k, v))
	end
	return tohtml("div", table.concat(t))
end

diag.htmltable = tohtmltable

diag.htmltable1 = function(hdr, tbl)
	local thead
	local tbody
	local tr
	if hdr then
		thead = {}
		for k, v in pairs(hdr) do
			tr = {}
			for c, w in pairs(v) do
				tr[c] = tohtml("th", w)
			end
			thead[k] = tohtml("tr", table.concat(tr))
		end
		thd = tohtml("thead", thead)
	else
		thd = ""
	end
	tbody = {}
	for k, v in pairs(tbl) do
		tr = {}
		for c, w in pairs(v) do
			tr[c] = tohtml("td", w)
		end
		tbody[k] = tohtml("tr", table.concat(tr))
		tbd = tohtml("tbody", tbody)
	end
	return tohtml("table", thd .. tbd)
end
			
diag.htmltable0 = function(hdr, tbl)
	local k
	local row
	local t = {}
	local i = 0
	local d
	local cell
	local u
	local j
	local h
	local htmlhd
	if hdr then
		h = {}
		j = 0
		for d, cell in pairs(hdr) do
			j = j + 1
			h[j] = tohtml("th", cell)
		end
		htmlhd = tohtml("tr", table.concat(h))
	else
		htmlhd = ""
	end
	for k, row in pairs(tbl) do
		i = i + 1
		u = {}
		j = 0
		for d, cell in pairs(row) do
			j = j + 1
			u[j] = tohtml("td", cell)
		end
		t[i] = tohtml("tr", table.concat(u))
	end
	return tohtml("table", htmlhd .. table.concat(t))
end
			
diag.modtest = function(frame, key, fun)
	local dlevel = diag.diag(frame)
	local par = frame.args[key]
	local r = ""
	if par then
		val = fun(par)
		if dlevel > 0 then
			r0 = diag.var("value", val)
		end
		if dlevel > 1 then
			r = r0
		end
	end
	return r
end

diag.modtest2 = function(frame, key1, key2, fun)
	local dlevel = diag.diag(frame)
	local par1 = frame.args[key1]
	local par2 = frame.args[key2]
	local r = ""
	if par1 and par2 then
		val = fun(par1, par2)
		if dlevel > 0 then
			r0 = diag.var("value", val)
		end
		if dlevel > 1 then
			r = r0
		end
	end
	return r
end

diag.selftest = function(frame)
	local z = nil
	local x = {}
	x[1] = 42
	x[2] = "foo"
	x[3] = true
	x[4] = x
	x[5] = diag.var
    return diag.var("z", z) .. diag.var("x", x)
end

diag.time = function()
	return tohtml("div", showvar(showhook, 10, "time", os.time()))
end

diag.var = function(name, x)
	return tohtml("div", showvar(showhook, 10, name, x))
end

diag.varlim = function(name, depth, x)
	return tohtml("div", showvar(showhook, depth, name, x))
end

return diag