@ -180,6 +180,116 @@ function printall_ipairs(table)
end
end
end
end
local do_print_recurse
local function print_string ( printfn , v , seen , indent )
local str = tostring ( v )
printfn ( str )
return # str ;
end
local fill_chars = {
__index = function ( table , key , value )
local rv = string.rep ( ' ' , 23 - key ) .. ' = '
rawset ( table , key , rv )
return rv
end ,
}
setmetatable ( fill_chars , fill_chars )
local function print_fields ( value , seen , indent , prefix )
local ok , f , t , k = pcall ( pairs , value )
if not ok then
dfhack.print ( prefix )
dfhack.println ( ' <Type doesn \' t support iteration with pairs> ' )
return 0
end
local prev_value = " not a value "
local repeated = 0
for k , v in f , t , k do
-- Only show set values of bitfields
if value._kind ~= " bitfield " or v then
local continue = false
if type ( k ) == " number " then
if prev_value == v then
repeated = repeated + 1
continue = true
else
prev_value = v
end
else
prev_value = " not a value "
end
if not continue then
if repeated > 0 then
dfhack.println ( prefix .. " <Repeated " .. repeated .. " times> " )
repeated = 0
end
dfhack.print ( prefix )
local len = do_print_recurse ( dfhack.print , k , seen , indent + 1 )
dfhack.print ( fill_chars [ len <= 23 and len or 23 ] )
do_print_recurse ( dfhack.println , v , seen , indent + 1 )
end
end
end
if repeated > 0 then
dfhack.println ( prefix .. " <Repeated " .. repeated .. " times> " )
end
return 0
end
-- This should be same as print_array but userdata doesn't compare equal even if
-- they hold same pointer.
local function print_userdata ( printfn , value , seen , indent )
local prefix = string.rep ( ' ' , indent )
local strvalue = tostring ( value )
dfhack.println ( strvalue )
if seen [ strvalue ] then
dfhack.print ( prefix )
dfhack.println ( ' <Cyclic reference! Skipping fields> \n ' )
return 0
end
seen [ strvalue ] = true
return print_fields ( value , seen , indent , prefix )
end
local function print_array ( printfn , value , seen , indent )
local prefix = string.rep ( ' ' , indent )
dfhack.println ( tostring ( value ) )
if seen [ value ] then
dfhack.print ( prefix )
dfhack.println ( ' <Cyclic reference! skipping fields> \n ' )
return 0
end
seen [ value ] = true
return print_fields ( value , seen , indent , prefix )
end
local recurse_type_map = {
number = print_string ,
string = print_string ,
boolean = print_string ,
[ ' function ' ] = print_string ,
[ ' nil ' ] = print_string ,
userdata = print_userdata ,
table = print_array ,
}
do_print_recurse = function ( printfn , value , seen , indent )
local t = type ( value )
if not recurse_type_map [ t ] then
printfn ( " Unknown type " .. t .. " " .. tostring ( value ) )
return
end
return recurse_type_map [ t ] ( printfn , value , seen , indent )
end
function printall_recurse ( value )
local seen = { }
do_print_recurse ( dfhack.println , value , seen , 0 )
end
function copyall ( table )
function copyall ( table )
local rv = { }
local rv = { }
for k , v in pairs ( table ) do rv [ k ] = v end
for k , v in pairs ( table ) do rv [ k ] = v end
@ -334,6 +444,7 @@ function dfhack.interpreter(prompt,hfile,env)
" '= foo' => '_1,_2,... = foo' \n " ..
" '= foo' => '_1,_2,... = foo' \n " ..
" '! foo' => 'print(foo)' \n " ..
" '! foo' => 'print(foo)' \n " ..
" '~ foo' => 'printall(foo)' \n " ..
" '~ foo' => 'printall(foo)' \n " ..
" '^ foo' => 'printall_recurse(foo)' \n " ..
" '@ foo' => 'printall_ipairs(foo)' \n " ..
" '@ foo' => 'printall_ipairs(foo)' \n " ..
" All of these save the first result as '_'. " )
" All of these save the first result as '_'. " )
print_banner = false
print_banner = false
@ -358,6 +469,9 @@ function dfhack.interpreter(prompt,hfile,env)
print ( table.unpack ( data , 2 , data.n ) )
print ( table.unpack ( data , 2 , data.n ) )
printall_ipairs ( data [ 2 ] )
printall_ipairs ( data [ 2 ] )
end ,
end ,
[ ' ^ ' ] = function ( data )
printall_recurse ( data [ 2 ] )
end ,
[ ' = ' ] = function ( data )
[ ' = ' ] = function ( data )
for i = 2 , data.n do
for i = 2 , data.n do
local varname = ' _ ' .. vcnt
local varname = ' _ ' .. vcnt