Code: Select all
-- require '_STD_SYS'
-- require '_STD_HDR'
-- require '##_STD_HEX' -- still debugging
--[[
scan all tables in _G for functions
try to build a reverse mapping of all functions pointers
string.sub() should not just be sub(), but the full name
]]
local _oblt = {} -- object built
local _Gtbl = {} -- enumeration of _G
local _gid = 1 -- index of _Gtbl table
local _elvl = {} -- table depth, i.e. iup.callback.
local _etbl = 0
local _dft = {addr = '*NULL', dec = 0}
function rslv_G(_tbl, __nam)
function get_addr(_gatyp)
local _ga = _dft
if type(_gatyp) == 'function'
or type(_gatyp) == 'table' then
_gatyp = (tostring(_gatyp))
_gatyp = _gatyp:sub(_gatyp:find(' ') + 1):match('(%x*)')
_ga.addr = _gatyp
-- _ga.dec = hex_to_dec(_gatyp):gsub('%.0', '') or 0
end
return _ga
end
function wrt_obj(_wtyp, _wnam, _wpkg, _wga)
for _, _dbgID in pairs({16, 189, 248, 255, 405}) do
if _gid == _dbgID then
_BREAKPOINT = true
break
end
end
wrt_type[(type(_wtyp))](_wtyp, _wnam, _wpkg, _wga)
end
wrt_type =
{
['boolean'] = function(_otyp, _onam, _opkg, _oga)
print('in boolean')
local bool
if _otyp then
bool = 'true'
else
bool = 'false'
end
_Gtbl[_gid] =
{
id = _gid,
addr = _oga.addr,
dec = _oga.dec,
typ = type(_otyp),
_cl = string.format('%s%s', _opkg, _onam),
pkg = _opkg,
name = _onam,
}
_gid = _gid + 1
end, -- fn boolean
['thread'] = function(_otyp, _onam, _opkg, _oga)
print('in thread')
local _a, _b = pcall(string.dump, _otyp)
_Gtbl[_gid] =
{
id = _gid,
addr = _oga.addr,
dec = _oga.dec,
typ = type(_otyp),
_cl = string.format('%s%s', _opkg, _onam),
pkg = _opkg,
name = _onam,
}
_gid = _gid + 1
end, -- fn thread
['userdata'] = function(_otyp, _onam, _opkg, _oga)
print('in userdata')
local _a, _b = pcall(string.dump, _otyp)
_Gtbl[_gid] =
{
id = _gid,
addr = _oga.addr,
dec = _oga.dec,
typ = type(_otyp),
_cl = string.format('%s%s', _opkg, _onam),
pkg = _opkg,
name = _onam,
}
_gid = _gid + 1
end, -- userdata (generally fhptr)
['nil'] = function(_otyp, _onam, _opkg, _oga)
print('in nil')
_Gtbl[_gid] =
{
id = _gid,
addr = _oga.addr,
dec = _oga.dec,
typ = type(_otyp),
_cl = string.format('%s%s', _opkg, _onam),
pkg = _opkg,
name = _onam,
}
_gid = _gid + 1
end, -- fn nil
['string'] = function(_otyp, _onam, _opkg, _oga)
_Gtbl[_gid] =
{
id = _gid,
addr = _oga.addr,
dec = _oga.dec,
typ = type(_otyp),
_cl = string.format('%s%s', _opkg, _onam),
pkg = _opkg,
name = _onam,
val = _otyp
}
_gid = _gid + 1
end, -- fn string
['number'] = function(_otyp, _onam, _opkg, _oga)
local _val = ('%.1f'):format(_otyp)
_Gtbl[_gid] =
{
id = _gid,
addr = _oga.addr,
dec = _oga.dec,
typ = type(_otyp),
_cl = string.format('%s%s', _opkg, _onam),
pkg = _opkg,
name = _onam,
val = _val:gsub('%.0', ''),
}
_gid = _gid + 1
end, -- fn number
['function'] = function(_otyp, _onam, _opkg, _oga)
local _opkg = _opkg
local _fh = string.sub(_onam, 1, 2)
if _fh == 'fh' then
_opkg = ('%s%s.'):format(_opkg, _fh)
end
_Gtbl[_gid] =
{
id = _gid,
addr = _oga.addr,
dec = _oga.dec,
typ = type(_otyp),
_cl = string.format('%s%s', _opkg, _onam),
pkg = _opkg,
name = _onam,
}
_gid = _gid + 1
end, -- fn function
['table'] = function(_ityp, _inam, _ipkg, _iga)
local ityp = type(_ityp)
local inam = _inam
local ipkg = _ipkg
if _oblt[_iga.addr] then
return -- this prevents rereading recursive tables (but it dont)
end
_oblt[_iga.addr] = true
for _, _ign in pairs({'_G.', '_G._G.', '_Gtbl.', 'iup._M.', 'package.loaded'}) do
if _wpkg == _ign then
_epkg = ''
_ityp = ''
return
end
end
for _enam, _etyp in pairs(_ityp) do
local etyp = type(_etyp)
if etyp == 'table' then
_epkg = '' --
_elvl[#_elvl + 1] = ('%s.'):format(_enam)
for _ix, _ in ipairs(_elvl) do
-- glue level
_epkg = ('%s%s'):format(_epkg or '', _elvl[_ix])
end
_etbl = _etbl + 1
-- type(_etyp) == 'table'
local _ega = get_addr(_etyp)
if next(_etyp) then
wrt_obj(_etyp, _enam, _epkg or '', _ega)
else
_Gtbl[_gid] =
{
id = _gid,
addr = _ega.addr,
dec = _ega.dec,
typ = type(_etyp),
_cl = string.format('%s%s', _epkg, _enam),
pkg = _epkg,
name = _enam,
}
_gid = _gid + 1
end
elseif etyp == 'function' then
-- type(_etyp) == 'function'
local _ega = get_addr(_etyp)
local _enam = _enam
if type(_enam) == 'number' then
_enam = (('[%s]%s'):format(_enam, _inam))
end
wrt_obj(_etyp, _enam, _epkg or '', _ega)
-- expansion later
-- elseif _etyp == 'userdata' then io. has them i.e. stdin
-- elseif _etyp == 'string' then 'global constant'
-- elseif _etyp == 'number' then 'global constant'
-- elseif _etyp == 'boolean' then
-- elseif _etyp == 'thread' then
-- elseif _etyp == 'nil' then
end
-- type(_etyp) == 'table' 'function'
end
-- out of table
-- how to manage nested tables correctly ??
_epkg = '' -- clear for non tables
_enam = '' -- clear for non tables
_etbl = _etbl - 1 -- see 207
if _etbl <=0 then
_elvl = {}
else
_elvl[#_elvl] = nil
end
-- for _e = _etbl, #_elvl do
-- _elvl[_etbl] = nil
-- _elvl[_e] = nil
-- end
-- fn table
end,
}
-- strdbg()
local _t = tostring(_tbl)
_t = _t:sub(_t:find(' ') + 1):match('(%x*)')
_t = _t:match('(%x*)')
local _st = _dft
_st.addr = _t
wrt_obj(_tbl, _t, '', _st) -- get name and addr put in _Gtbl 1 or ?
-- fn rslv_G
end
function main()
-- *NULL: landmark only
end
rslv_G(_G._G, '')
local tblnbr = {}
local tbllib = {}
local tblnam = {}
local tbltyp = {}
local tblhex = {}
local tbldec = {}
for k, _ in pairs(_Gtbl) do
local g = _Gtbl[k]
table.insert(tblnbr, g.id)
table.insert(tbllib, g._cl)
table.insert(tblnam, g.name)
table.insert(tbltyp, g.typ)
table.insert(tblhex, g.addr)
table.insert(tbldec, g.dec)
end
fhOutputResultSetColumn('id ', 'integer', tblnbr, #tblnbr, 24, 'align_right', 1)
fhOutputResultSetColumn('lib', 'text' , tbllib, #tbllib, 256, 'align_left')
fhOutputResultSetColumn('nam', 'text' , tblnam, #tblnam, 128, 'align_left')
fhOutputResultSetColumn('typ', 'text' , tbltyp, #tbltyp, 48, 'align_left')
fhOutputResultSetColumn('adr', 'text' , tblhex, #tblhex, 48, 'align_mid')
fhOutputResultSetColumn('dec', 'text' , tbldec, #tbldec, 12, 'align_right')
return