Modul:Sandlådan/SM5POR/Diag
Dokumentation [visa] [redigera] [historik] [rensa sidcachen]
|
This page documents the development version of the Diag module. Since it is intended for an international audience, it is written in English, even as the development currently takes place on Swedish Wikipedia. |
Introduction
Technical reference
Exported functions
diag
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
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.
Copyright © 2022 Anders Andersson |
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 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 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 = {}
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