1.1 --- a/cgi-bin/tek/lib/debug.lua Fri Sep 12 22:00:42 2008 +0200
1.2 +++ b/cgi-bin/tek/lib/debug.lua Fri Oct 24 01:35:27 2008 +0200
1.3 @@ -50,7 +50,7 @@
1.4 local unpack = unpack
1.5
1.6 module "tek.lib.debug"
1.7 -_VERSION = "Debug 4.0"
1.8 +_VERSION = "Debug 4.1"
1.9
1.10 -- symbolic:
1.11
1.12 @@ -62,7 +62,7 @@
1.13
1.14 -- global defaults:
1.15
1.16 -level = ERROR
1.17 +level = INFO
1.18 out = stderr
1.19 wrout = function(...) out:write(...) end
1.20
1.21 @@ -140,40 +140,58 @@
1.22 stderr:write('To redirect the output, e.g.:\n')
1.23 stderr:write(' tek.lib.debug.out = io.open("logfile", "w")\n')
1.24 stderr:write('To dump a table, e.g.:\n')
1.25 - stderr:write(' tek.lib.debug.dump("app", app)\n')
1.26 + stderr:write(' tek.lib.debug.dump(app)\n')
1.27 stderr:write('Use "cont" to continue.\n')
1.28 debug.debug()
1.29 end
1.30
1.31 -------------------------------------------------------------------------------
1.32 --- dump(name, table): Dump a table
1.33 +-- dump(table): Dump a table as Lua source using {{out}} as the output
1.34 +-- stream. Cyclic references are silently dropped.
1.35 -------------------------------------------------------------------------------
1.36
1.37 -local function basicSerialize(o)
1.38 - if type(o) == "string" then
1.39 - return ("%q"):format(o)
1.40 - elseif type(o) == "userdata" then
1.41 - return "<userdata>"
1.42 - end
1.43 - return tostring(o)
1.44 +local function encodenonascii(c)
1.45 + return ("\\%03d"):format(c:byte())
1.46 end
1.47
1.48 -function dump(name, value, saved)
1.49 - saved = saved or {} -- initial value
1.50 - wrout(name, " = ")
1.51 - local t = type(value)
1.52 - if t == "table" then
1.53 - if saved[value] then -- value already saved?
1.54 - wrout(saved[value], "\n")
1.55 - else
1.56 - saved[value] = name -- save name for next time
1.57 - wrout("{}\n")
1.58 - for k,v in pairs(value) do -- save its fields
1.59 - local fieldname = ("%s[%s]"):format(name, basicSerialize(k))
1.60 - dump(fieldname, v, saved)
1.61 +local function encode(s)
1.62 + return s:gsub('([%z\001-\031\092"])', encodenonascii)
1.63 +end
1.64 +
1.65 +local function dumpr(tab, indent, outfunc, saved)
1.66 + saved[tab] = tab
1.67 + local is = ("\t"):rep(indent)
1.68 + for key, val in pairs(tab) do
1.69 + if not saved[val] then
1.70 + outfunc(is)
1.71 + local t = type(key)
1.72 + if t == "number" or t == "boolean" then
1.73 + outfunc('[' .. tostring(key) .. '] = ')
1.74 + elseif t == "string" then
1.75 + if key:match("[^%a_]") then
1.76 + outfunc('["' .. encode(key) .. '"] = ')
1.77 + else
1.78 + outfunc(key .. ' = ')
1.79 + end
1.80 + else
1.81 + outfunc('["' .. tostring(key) .. '"] = ')
1.82 + end
1.83 + t = type(val)
1.84 + if t == "table" then
1.85 + outfunc('{\n')
1.86 + dumpr(val, indent + 1, outfunc, saved)
1.87 + outfunc(is .. '},\n')
1.88 + elseif t == "string" then
1.89 + outfunc('"' .. encode(val) .. '",\n')
1.90 + elseif t == "number" or t == "boolean" then
1.91 + outfunc(tostring(val) .. ',\n')
1.92 + else
1.93 + outfunc('"' .. tostring(val) .. '",\n')
1.94 end
1.95 end
1.96 - else
1.97 - wrout(basicSerialize(value), "\n")
1.98 end
1.99 end
1.100 +
1.101 +function dump(tab, outf)
1.102 + dumpr(tab, 0, outf or wrout, { })
1.103 +end