Merge remote-tracking branch 'print_tables/master'
This commit is contained in:
commit
bc4506b3bd
5 changed files with 561 additions and 0 deletions
246
_G.yml
Normal file
246
_G.yml
Normal file
|
@ -0,0 +1,246 @@
|
|||
__root: &__root_t0x4004f960
|
||||
_G: *__root_t0x4004f960
|
||||
_VERSION: Lua 5.1
|
||||
arg: &arg_t0x40055cc8
|
||||
"-1": luajit
|
||||
0: run.lua
|
||||
assert: fbuiltin#2
|
||||
bit: &bit_t0x40054d58
|
||||
arshift: fbuiltin#70
|
||||
band: fbuiltin#73
|
||||
bnot: fbuiltin#66
|
||||
bor: fbuiltin#74
|
||||
bswap: fbuiltin#67
|
||||
bxor: fbuiltin#75
|
||||
lshift: fbuiltin#68
|
||||
rol: fbuiltin#71
|
||||
ror: fbuiltin#72
|
||||
rshift: fbuiltin#69
|
||||
tobit: fbuiltin#65
|
||||
tohex: fbuiltin#76
|
||||
collectgarbage: fbuiltin#27
|
||||
coroutine: &coroutine_t0x40051730
|
||||
create: fbuiltin#32
|
||||
resume: fbuiltin#34
|
||||
running: fbuiltin#31
|
||||
status: fbuiltin#30
|
||||
wrap: fbuiltin#36
|
||||
yield: fbuiltin#33
|
||||
debug: &debug_t0x40054740
|
||||
debug: fbuiltin#145
|
||||
getfenv: fbuiltin#134
|
||||
gethook: fbuiltin#144
|
||||
getinfo: fbuiltin#136
|
||||
getlocal: fbuiltin#137
|
||||
getmetatable: fbuiltin#132
|
||||
getregistry: fbuiltin#131
|
||||
getupvalue: fbuiltin#139
|
||||
setfenv: fbuiltin#135
|
||||
sethook: fbuiltin#143
|
||||
setlocal: fbuiltin#138
|
||||
setmetatable: fbuiltin#133
|
||||
setupvalue: fbuiltin#140
|
||||
traceback: fbuiltin#146
|
||||
upvalueid: fbuiltin#141
|
||||
upvaluejoin: fbuiltin#142
|
||||
dofile: fbuiltin#25
|
||||
dump: f0x4005dd40
|
||||
error: fbuiltin#19
|
||||
gcinfo: fbuiltin#26
|
||||
getfenv: fbuiltin#10
|
||||
getmetatable: fbuiltin#8
|
||||
io: &io_t0x40052a90
|
||||
close: fbuiltin#112
|
||||
flush: fbuiltin#115
|
||||
input: fbuiltin#116
|
||||
lines: fbuiltin#118
|
||||
open: fbuiltin#109
|
||||
output: fbuiltin#117
|
||||
popen: fbuiltin#110
|
||||
read: fbuiltin#113
|
||||
stderr: file (0x7ff9dd21f500)
|
||||
stdin: file (0x7ff9dd21e8a0)
|
||||
stdout: file (0x7ff9dd21f5e0)
|
||||
tmpfile: fbuiltin#111
|
||||
type: fbuiltin#119
|
||||
write: fbuiltin#114
|
||||
ipairs: fbuiltin#7
|
||||
jit: &jit_t0x40055318
|
||||
arch: x64
|
||||
attach: fbuiltin#151
|
||||
flush: fbuiltin#149
|
||||
off: fbuiltin#148
|
||||
on: fbuiltin#147
|
||||
opt: &opt_t0x40055bd8
|
||||
start: fbuiltin#163
|
||||
os: Linux
|
||||
status: fbuiltin#150
|
||||
util: &util_t0x400556a0
|
||||
funcbc: fbuiltin#153
|
||||
funcinfo: fbuiltin#152
|
||||
funck: fbuiltin#154
|
||||
funcuvname: fbuiltin#155
|
||||
ircalladdr: fbuiltin#162
|
||||
traceexitstub: fbuiltin#161
|
||||
traceinfo: fbuiltin#156
|
||||
traceir: fbuiltin#157
|
||||
tracek: fbuiltin#158
|
||||
tracemc: fbuiltin#160
|
||||
tracesnap: fbuiltin#159
|
||||
version: LuaJIT 2.0.4
|
||||
version_num: 20004
|
||||
load: fbuiltin#23
|
||||
loadfile: fbuiltin#22
|
||||
loadstring: fbuiltin#24
|
||||
math: &math_t0x40053b60
|
||||
abs: fbuiltin#37
|
||||
acos: fbuiltin#47
|
||||
asin: fbuiltin#46
|
||||
atan: fbuiltin#48
|
||||
atan2: fbuiltin#57
|
||||
ceil: fbuiltin#39
|
||||
cos: fbuiltin#44
|
||||
cosh: fbuiltin#50
|
||||
deg: fbuiltin#54
|
||||
exp: fbuiltin#42
|
||||
floor: fbuiltin#38
|
||||
fmod: fbuiltin#59
|
||||
frexp: fbuiltin#52
|
||||
huge: inf
|
||||
ldexp: fbuiltin#60
|
||||
log: fbuiltin#56
|
||||
log10: fbuiltin#41
|
||||
max: fbuiltin#62
|
||||
min: fbuiltin#61
|
||||
mod: fbuiltin#59
|
||||
modf: fbuiltin#53
|
||||
pi: 3.1415926535898
|
||||
pow: fbuiltin#58
|
||||
rad: fbuiltin#55
|
||||
random: fbuiltin#63
|
||||
randomseed: fbuiltin#64
|
||||
sin: fbuiltin#43
|
||||
sinh: fbuiltin#49
|
||||
sqrt: fbuiltin#40
|
||||
tan: fbuiltin#45
|
||||
tanh: fbuiltin#51
|
||||
module: f0x40051ee0
|
||||
newproxy: fbuiltin#28
|
||||
next: fbuiltin#4
|
||||
os: &os_t0x40052fd0
|
||||
clock: fbuiltin#126
|
||||
date: fbuiltin#127
|
||||
difftime: fbuiltin#129
|
||||
execute: fbuiltin#120
|
||||
exit: fbuiltin#125
|
||||
getenv: fbuiltin#124
|
||||
remove: fbuiltin#121
|
||||
rename: fbuiltin#122
|
||||
setlocale: fbuiltin#130
|
||||
time: fbuiltin#128
|
||||
tmpname: fbuiltin#123
|
||||
package: &package_t0x40051ac8
|
||||
config:
|
||||
/
|
||||
;
|
||||
?
|
||||
!
|
||||
-
|
||||
cpath: /home/notwa/opt/local/lib/?.so;/home/notwa/.luarocks/lib/lua/5.1/?.so;/home/notwa/opt/local/lib/lua/5.1/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so
|
||||
loaded: &loaded_t0x40050b38
|
||||
_G: *__root_t0x4004f960
|
||||
bit: *bit_t0x40054d58
|
||||
coroutine: *coroutine_t0x40051730
|
||||
debug: *debug_t0x40054740
|
||||
extra: &extra_t0x4005cd30
|
||||
add_zeros: f0x4005db58
|
||||
mixed_sorter: f0x4005db98
|
||||
opairs: f0x4005cca8
|
||||
order_keys: f0x4005b2f8
|
||||
strpad: f0x4004f8b8
|
||||
traverse: f0x4005cce8
|
||||
io: *io_t0x40052a90
|
||||
jit: *jit_t0x40055318
|
||||
"jit.opt": *opt_t0x40055bd8
|
||||
"jit.util": *util_t0x400556a0
|
||||
math: *math_t0x40053b60
|
||||
os: *os_t0x40052fd0
|
||||
package: *package_t0x40051ac8
|
||||
pt: &pt_t0x4005ce20
|
||||
__metatable: *pt_t0x4005ce20
|
||||
__call: f0x4005dc98
|
||||
__index: *pt_t0x4005ce20
|
||||
inner: f0x4005dde0
|
||||
outer: f0x4005dd18
|
||||
outer_old: f0x4005dc00
|
||||
safecanon: f0x4005dd60
|
||||
safekey: f0x4005dd80
|
||||
safeval: f0x4005ddc0
|
||||
write: f0x4005dcd8
|
||||
string: *string_t0x400534b0
|
||||
table: *table_t0x400522f8
|
||||
loaders: &loaders_t0x40051c38
|
||||
1: f0x40051c88
|
||||
2: f0x40051cb0
|
||||
3: f0x40051cd8
|
||||
4: f0x40051d00
|
||||
loadlib: f0x40051b58
|
||||
path: /home/notwa/.luarocks/share/lua/5.1/?.lua;/home/notwa/.luarocks/share/lua/5.1/?/init.lua;/home/notwa/opt/local/share/lua/5.1/?.lua;/home/notwa/opt/local/share/lua/5.1/?/init.lua;./?.lua;/home/notwa/opt/local/share/luajit-2.1.0-beta1/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua
|
||||
preload: &preload_t0x400520c0
|
||||
ffi: f0x40055c80
|
||||
searchpath: f0x40051ba0
|
||||
seeall: f0x40051bf0
|
||||
pairs: fbuiltin#5
|
||||
pcall: fbuiltin#20
|
||||
print: fbuiltin#29
|
||||
rawequal: fbuiltin#14
|
||||
rawget: fbuiltin#12
|
||||
rawset: fbuiltin#13
|
||||
require: f0x40051f28
|
||||
select: fbuiltin#16
|
||||
setfenv: fbuiltin#11
|
||||
setmetatable: fbuiltin#9
|
||||
string: &string_t0x400534b0
|
||||
byte: fbuiltin#78
|
||||
char: fbuiltin#79
|
||||
dump: fbuiltin#85
|
||||
find: fbuiltin#86
|
||||
format: fbuiltin#91
|
||||
gfind: fbuiltin#89
|
||||
gmatch: fbuiltin#89
|
||||
gsub: fbuiltin#90
|
||||
len: fbuiltin#77
|
||||
lower: fbuiltin#83
|
||||
match: fbuiltin#87
|
||||
rep: fbuiltin#81
|
||||
reverse: fbuiltin#82
|
||||
sub: fbuiltin#80
|
||||
upper: fbuiltin#84
|
||||
t: &t_t0x4005e298
|
||||
A: hello
|
||||
B: &B_t0x4005e328
|
||||
a: beep
|
||||
b: boop
|
||||
c: burp
|
||||
d: *d_t0x4005e550
|
||||
C: &d_t0x4005e550
|
||||
a: nude
|
||||
b: dude
|
||||
c: lewd
|
||||
d: *B_t0x4005e328
|
||||
D: goodbye
|
||||
E: *t_t0x4005e298
|
||||
table: &table_t0x400522f8
|
||||
concat: fbuiltin#98
|
||||
foreach: fbuiltin#93
|
||||
foreachi: fbuiltin#92
|
||||
getn: fbuiltin#94
|
||||
insert: fbuiltin#96
|
||||
maxn: fbuiltin#95
|
||||
remove: fbuiltin#97
|
||||
sort: fbuiltin#99
|
||||
tonumber: fbuiltin#17
|
||||
tostring: fbuiltin#18
|
||||
type: fbuiltin#3
|
||||
unpack: fbuiltin#15
|
||||
xpcall: fbuiltin#21
|
69
extra.lua
Executable file
69
extra.lua
Executable file
|
@ -0,0 +1,69 @@
|
|||
local insert = table.insert
|
||||
local pairs = pairs
|
||||
local rawget = rawget
|
||||
local sort = table.sort
|
||||
local tostring = tostring
|
||||
local type = type
|
||||
|
||||
local function strpad(num, count, pad)
|
||||
num = tostring(num)
|
||||
return (pad:rep(count)..num):sub(#num)
|
||||
end
|
||||
|
||||
local function add_zeros(num, count)
|
||||
return strpad(num, count - 1, '0')
|
||||
end
|
||||
|
||||
local function mixed_sorter(a, b)
|
||||
a = type(a) == 'number' and add_zeros(a, 16) or tostring(a)
|
||||
b = type(b) == 'number' and add_zeros(b, 16) or tostring(b)
|
||||
return a < b
|
||||
end
|
||||
|
||||
-- loosely based on http://lua-users.org/wiki/SortedIteration
|
||||
-- the original didn't make use of closures for who knows why
|
||||
local function order_keys(t)
|
||||
local oi = {}
|
||||
for key in pairs(t) do
|
||||
insert(oi, key)
|
||||
end
|
||||
sort(oi, mixed_sorter)
|
||||
return oi
|
||||
end
|
||||
|
||||
local function opairs(t, cache)
|
||||
local oi = cache and cache[t] or order_keys(t)
|
||||
if cache then
|
||||
cache[t] = oi
|
||||
end
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
local key = oi[i]
|
||||
if key ~= nil then return key, t[key] end
|
||||
end
|
||||
end
|
||||
|
||||
local function traverse(path)
|
||||
if not path then return end
|
||||
local parent = _G
|
||||
local key
|
||||
for w in path:gfind("[%w_]+") do
|
||||
if key then
|
||||
parent = rawget(parent, key)
|
||||
if type(parent) ~= 'table' then return end
|
||||
end
|
||||
key = w
|
||||
end
|
||||
if not key then return end
|
||||
return {parent=parent, key=key}
|
||||
end
|
||||
|
||||
return {
|
||||
strpad = strpad,
|
||||
add_zeros = add_zeros,
|
||||
mixed_sorter = mixed_sorter,
|
||||
order_keys = order_keys,
|
||||
opairs = opairs,
|
||||
traverse = traverse,
|
||||
}
|
2
init.lua
Normal file
2
init.lua
Normal file
|
@ -0,0 +1,2 @@
|
|||
local path = string.gsub(..., "[^.]+$", "")
|
||||
return require(path.."pt")
|
203
pt.lua
Executable file
203
pt.lua
Executable file
|
@ -0,0 +1,203 @@
|
|||
local path = string.gsub(..., "[^.]+$", "")
|
||||
local extra = require(path.."extra")
|
||||
local opairs = extra.opairs
|
||||
|
||||
local pt = {}
|
||||
pt.__index = pt
|
||||
setmetatable(pt, pt)
|
||||
|
||||
local function rawstr(v)
|
||||
if v == nil then return 'nil' end
|
||||
local mt = getmetatable(v)
|
||||
local ts = mt and rawget(mt, '__tostring')
|
||||
if not ts then return tostring(v) end
|
||||
mt.__tostring = nil
|
||||
local s = tostring(v)
|
||||
mt.__tostring = ts
|
||||
return s
|
||||
end
|
||||
|
||||
local function getaddr(t)
|
||||
return rawstr(t):sub(#type(t) + 3)
|
||||
end
|
||||
|
||||
local function copy(t)
|
||||
-- shallow copy
|
||||
if type(t) ~= 'table' then return end
|
||||
local new = {}
|
||||
for k,v in pairs(t) do
|
||||
new[k] = v
|
||||
end
|
||||
return new
|
||||
end
|
||||
|
||||
function pt.__call(pt, args)
|
||||
-- print a table as semi-valid YAML
|
||||
-- with references to prevent recursion/duplication
|
||||
local t = args.table or args[1]
|
||||
local self = {}
|
||||
setmetatable(self, pt)
|
||||
self.seen = copy(args.seen) or {}
|
||||
self.skipped = copy(args.skipped) or {}
|
||||
self.seen_elsewhere = args.seen or {}
|
||||
self.depth = args.depth or 16
|
||||
self.writer = args.writer or io.write
|
||||
self.skeleton = args.skeleton or false
|
||||
self.outer = args.alt_order and self.outer_old or self.outer
|
||||
self.noncanon = args.noncanon or false
|
||||
self.indent = args.indent or ' '
|
||||
self.queued = {}
|
||||
self.cache = {}
|
||||
self.canonicalized = {}
|
||||
self:inner('__root', t, '')
|
||||
return self.seen
|
||||
end
|
||||
|
||||
function pt:write(...)
|
||||
self.writer(...)
|
||||
end
|
||||
|
||||
function pt:safecanon(k)
|
||||
local s = tostring(k)
|
||||
return s:gsub('[^%w_]', '_')
|
||||
end
|
||||
|
||||
function pt:safekey(k)
|
||||
if type(k) == 'table' then
|
||||
return 't'..getaddr(k)
|
||||
end
|
||||
local s = tostring(k)
|
||||
s = s:gsub('[\r\n]', '')
|
||||
return s:find('[^%w_]') and ('%q'):format(s) or s
|
||||
end
|
||||
|
||||
function pt:safeval(v, indentation)
|
||||
if type(v) == 'function' then
|
||||
return 'f'..getaddr(v)
|
||||
end
|
||||
local s = tostring(v)
|
||||
if type(v) == 'number' then
|
||||
return s
|
||||
end
|
||||
-- TODO: move newline/indentation handling to another function?
|
||||
if s:find('[\r\n]') then
|
||||
s = ('\n'..s):gsub('[\r\n]', '\n'..indentation..self.indent)
|
||||
end
|
||||
--local safe = ('%q'):format(s)
|
||||
--return s == safe:sub(2, -2) and s or safe
|
||||
-- TODO: finish matching valid characters
|
||||
return s:find('[^%w_()[]{}.]') and ('%q'):format(s) or s
|
||||
end
|
||||
|
||||
function pt:inner(k, v, indentation)
|
||||
if type(v) ~= 'table' then
|
||||
if self.skeleton then return end
|
||||
self:write(indentation, self:safekey(k), ': ')
|
||||
self:write(self:safeval(v, indentation), '\n')
|
||||
return
|
||||
end
|
||||
|
||||
local addr = getaddr(v)
|
||||
self:write(indentation, self:safekey(k))
|
||||
|
||||
local canon
|
||||
if not self.noncanon and type(k) ~= 'table' then
|
||||
canon = self.canonicalized[addr]
|
||||
if canon == nil then
|
||||
canon = self:safecanon(k)..'_t'..addr
|
||||
self.canonicalized[addr] = canon
|
||||
end
|
||||
else
|
||||
canon = 't'..addr
|
||||
end
|
||||
|
||||
if #indentation > self.depth or self.skipped[addr] then
|
||||
--self.skipped[addr] = true -- TODO: extra logics
|
||||
self:write(': #', canon, '\n')
|
||||
return
|
||||
end
|
||||
|
||||
if self.seen[addr] or self.queued[addr] then
|
||||
self:write(': *', canon, self.seen_elsewhere[addr] and ' #\n' or '\n')
|
||||
return
|
||||
end
|
||||
|
||||
self.seen[addr] = true
|
||||
|
||||
self:write(': &', canon, '\n')
|
||||
self:outer(v, indentation..self.indent)
|
||||
end
|
||||
|
||||
function pt:outer_old(t, indentation)
|
||||
if type(t) ~= "table" then
|
||||
local s = self:safeval(t, indentation)
|
||||
self:write(indentation, s, '\n')
|
||||
return
|
||||
end
|
||||
|
||||
local ours = {}
|
||||
local not_ours = {}
|
||||
|
||||
for k,v in opairs(t) do
|
||||
if type(v) == 'table' then
|
||||
local addr = getaddr(v)
|
||||
if not (self.queued[addr] or self.seen[addr] or self.skipped[addr]) then
|
||||
self.queued[addr] = true
|
||||
ours[k] = v
|
||||
else
|
||||
not_ours[k] = v
|
||||
end
|
||||
else
|
||||
self:inner(k, v, indentation)
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in opairs(not_ours) do
|
||||
self:inner(k, v, indentation)
|
||||
end
|
||||
|
||||
for k,v in opairs(ours) do
|
||||
self.queued[getaddr(v)] = nil
|
||||
self:inner(k, v, indentation)
|
||||
end
|
||||
|
||||
local mt = getmetatable(t)
|
||||
if mt ~= nil then
|
||||
self:inner('__metatable', mt, indentation)
|
||||
end
|
||||
end
|
||||
|
||||
function pt:outer(t, indentation)
|
||||
if type(t) ~= "table" then
|
||||
local s = self:safeval(t, indentation)
|
||||
self:write(indentation, s, '\n')
|
||||
return
|
||||
end
|
||||
|
||||
local ours = {}
|
||||
|
||||
for k,v in opairs(t, self.cache) do
|
||||
if type(v) == 'table' then
|
||||
local addr = getaddr(v)
|
||||
if not (self.queued[addr] or self.seen[addr] or self.skipped[addr]) then
|
||||
self.queued[addr] = true
|
||||
ours[k] = addr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local mt = getmetatable(t)
|
||||
if mt ~= nil then
|
||||
self:inner('__metatable', mt, indentation)
|
||||
end
|
||||
|
||||
for k,v in opairs(t, self.cache) do
|
||||
local addr = ours[k]
|
||||
if addr then
|
||||
self.queued[addr] = nil
|
||||
end
|
||||
self:inner(k, v, indentation)
|
||||
end
|
||||
end
|
||||
|
||||
return pt
|
41
run.lua
Executable file
41
run.lua
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/lua
|
||||
local pt = require('pt')
|
||||
|
||||
t = {
|
||||
A = 'hello',
|
||||
B = {
|
||||
a = 'beep',
|
||||
b = 'boop',
|
||||
c = 'burp',
|
||||
},
|
||||
C = {
|
||||
a = 'nude',
|
||||
b = 'dude',
|
||||
c = 'lewd',
|
||||
},
|
||||
D = 'goodbye',
|
||||
}
|
||||
t.B.d = t.C
|
||||
t.C.d = t.B
|
||||
t.E = t
|
||||
|
||||
function dump(t, fn, seen)
|
||||
if t == nil then return end
|
||||
|
||||
local file = io.open(fn, "w")
|
||||
if not file then
|
||||
io.write("Failed opening ", fn, "\n")
|
||||
return
|
||||
end
|
||||
|
||||
local writer = function(...)
|
||||
file:write(...)
|
||||
end
|
||||
seen = pt{t, writer=writer, seen=seen}
|
||||
|
||||
file:close()
|
||||
return seen
|
||||
end
|
||||
|
||||
pt{t}
|
||||
dump(_G, '_G.yml')
|
Loading…
Reference in a new issue