|
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: