Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file: -- http://angg.twu.net/LUA/GetInfo2.lua.html -- http://angg.twu.net/LUA/GetInfo2.lua -- (find-angg "LUA/GetInfo2.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- -- (defun e () (interactive) (find-angg "LUA/GetInfo2.lua")) -- (defun o () (interactive) (find-angg "LUA/GetInfo.lua")) -- (defun p () (interactive) (find-angg "LUA/Prosody1.lua")) -- (find-angg "LUA/lua50init.lua" "DGetInfo") -- «.DGetInfo» (to "DGetInfo") -- «.DGetInfos» (to "DGetInfos") -- «DGetInfo» (to ".DGetInfo") DGetInfo = Class { type = "DGetInfo", what = "nSluf", atlevel = function (lvl, getvalues) local dgi = debug.getinfo(lvl, DGetInfo.what) if not dgi then return end if getvalues then dgi.values = {} end for i=1,1000 do local name,value = debug.getlocal(lvl, i) if not name then break end dgi[i] = name if getvalues then dgi.values[i] = value end end dgi.vars = table.concat(dgi, " ") return DGetInfo(dgi) end, -- __tostring = function (dgi) return dgi:tb() end, __index = { method = "tblua", setmethod = function (dgi,m) DGetInfo.__index.method = method end, tbi = function (dgi,m,i) return format("%2d -> %s", i, dgi:tb(m)) end, tb = function (dgi,m) return dgi[m or dgi.method](dgi) end, tbfv = function (dgi) return dgi:funname().." :: "..dgi.vars end, tbprosody = function (dgi) return Prosody.traceback1(dgi) end, -- -- See: (find-angg ".emacs" "find-luatb") tblua = function (dgi) if dgi.short_src == "[C]" then return dgi:tblua_C() end if dgi.what == "main" then return dgi:tblua_main() end if dgi.short_src == "(tail call)" then return dgi:tblua_tailcall() end return dgi:tblua_other() end, tblua_C = function (dgi) return "[ C ]" .." "..dgi.namewhat .." C function" .." "..(dgi.name and format("%q", dgi.name) or "(unknown name)") end, tblua_main = function (dgi) return "[Lua] " ..dgi.short_src .." line " ..dgi.currentline end, tblua_tailcall = function (dgi) return "[Lua] tail call" end, tblua_other = function (dgi) return -- "[Lua]".. " (find-luatb " ..'"'..(dgi.short_src or "") .." "..(dgi.linedefined or "") .." "..(dgi.currentline or "") .." "..(dgi.namewhat or "") .." "..(dgi.name or "") ..'")' end, -- funname = function (dgi) return dgi.name or "(noname)" end, -- vars = function (dgi) return table.concat(dgi, " ") end, -- convert = function (dgi) local i = VTable {} local name = VTable {} for j,nm in ipairs(dgi) do local value = dgi.values and dgi.values[j] or "(no values)" i[j] = {name=nm, value=value} name[nm] = {i=j, value=value} end return {name=name, i=i} end, v0 = function (dgi, varname) return dgi:convert().name[varname] end, v = function (dgi, varname) return dgi:v0(varname).value end, -- names = function (dgi) return dgi:convert().name end, -- is = function (dgi) return dgi:convert().i end, is = function (dgi, tos) tos = tos or mytostring local ci = dgi:convert().i local f = function (i) return format("%2s: %s = %s", i, ci[i].name, tos(ci[i].value)) end return mapconcat(f, seq(1, #ci), "\n") end, }, } --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "GetInfo2.lua" dofile "Prosody1.lua" dgis = DGetInfos.new() dgis = DGetInfos.newv() f = function (a,b,...) local c,d = "cc"; dgis = DGetInfos.newv() end f("aa","bb","oo","pp") = dgis[1] = dgis[1].tbfv = dgis[1].method = dgis[1]:tb() = dgis[1]:tb("tbfv") = dgis[5]:tb("tbfv") = dgis[5]:tbprosody() = dgis[5]:tblua() = dgis[5]:tbfv() = dgis[5]:tbi("tbfv", 42) = dgis[5]:is() = dgis:tb("tbfv") = dgis:tb("tbprosody") = dgis:tb("tblua") = dgis = dgis:setmethod("tbfv") = dgis = dgis:setmethod("tbprosody") = dgis = dgis:setmethod("tblua") = dgis = dgis[1] = dgis[1].vars = dgis[1]:vars() = dgis[1]:v"i" = dgis[1]:v"lvl" = dgis[1]:v"foo" = dgis[1]:convert() = dgis[5] = PPV(dgis[5]) --]] -- «DGetInfos» (to ".DGetInfos") -- Idea: running something like -- -- dgis = DGetInfos.newv() -- -- runs lots of "debug.getinfo()"s and "debug.getlocal"s via DGetInfo, -- and returns a static structure that can be inspected in a repl -- (both inside an error handler and post-mortem). -- DGetInfos = Class { type = "DGetInfos", new = function (getvalues) return DGetInfos({}):getinfos(getvalues) end, newv = function () return DGetInfos.new("getvalues") end, __tostring = function (dgis) return dgis:tostring() end, __index = { setmethod = function (dgis, method) DGetInfo.__index.method = method end, getinfos = function (dgis, getvalues) for i=0,1000 do dgis[i] = DGetInfo.atlevel(i, getvalues) if not dgis[i] then return dgis end end end, seq = function (dgis, a, b, dir) a,b = (a or #dgis),(b or 0) dir = dir or (a <= b and 1 or -1) return seq(a, b, dir) end, tostring = function (dgis, method, a, b, dir) local f = function (i) return dgis[i]:tbi(method, i) end return mapconcat(f, dgis:seq(a, b, dir), "\n") end, tb = function (dgis, method, a, b, dir) return dgis:tostring(method, a, b, dir) end, }, } -- Local Variables: -- coding: utf-8-unix -- indent-tabs-mode: nil -- End: