Beginning work on more advanced cdata inspection.
This commit is contained in:
parent
ae73cc9b64
commit
ffbbfef499
83
cdata.lua
Normal file
83
cdata.lua
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
|
||||||
|
-- Import
|
||||||
|
|
||||||
|
local ffi = require 'ffi'
|
||||||
|
|
||||||
|
-- Constants
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Util
|
||||||
|
|
||||||
|
local NUMBER_TO_HEX = {
|
||||||
|
[00] = '0', [01] = '1', [02] = '2', [03] = '3', [04] = '4', [05] = '5',
|
||||||
|
[06] = '6', [07] = '7', [08] = '8', [09] = '9', [10] = 'A', [11] = 'B',
|
||||||
|
[12] = 'C', [13] = 'D', [14] = 'E', [15] = 'F',
|
||||||
|
}
|
||||||
|
|
||||||
|
local function to_hex (str)
|
||||||
|
local l = {}
|
||||||
|
for i = 1, #str do
|
||||||
|
local v = str:byte(i)
|
||||||
|
l[#l+1] = NUMBER_TO_HEX[math.floor(v / 16)]
|
||||||
|
l[#l+1] = NUMBER_TO_HEX[v % 16]
|
||||||
|
l[#l+1] = ' '
|
||||||
|
end
|
||||||
|
l[#l] = nil
|
||||||
|
return table.concat(l, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_nice_ascii_string (str)
|
||||||
|
for i = 1, #str do
|
||||||
|
local byte = str:byte(i)
|
||||||
|
if not (32 <= byte and byte <= 126) then return false end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_type_and_size_of_singular ( ctype )
|
||||||
|
local nr_elements = 1
|
||||||
|
while true do
|
||||||
|
local etype, elements = ctype:match('(.+)%[(%d*)%]$')
|
||||||
|
if not elements then break end
|
||||||
|
ctype, nr_elements = etype, nr_elements * elements
|
||||||
|
end
|
||||||
|
return ctype, nr_elements
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local CDATA_REPR_MATCHER = 'cdata<(.+)>: (0x%w+)'
|
||||||
|
|
||||||
|
return function (value, options, depth, l)
|
||||||
|
local native_repr = tostring(value)
|
||||||
|
local data_length = ffi.sizeof(value)
|
||||||
|
local ctype, addr = native_repr:match(CDATA_REPR_MATCHER)
|
||||||
|
|
||||||
|
l[#l+1] = 'cdata {'
|
||||||
|
--l[#l+1] = '\n\tnative = \'' .. native_repr .. '\','
|
||||||
|
l[#l+1] = '\n\ttype = ' .. ctype .. ','
|
||||||
|
l[#l+1] = '\n\taddr = ' .. addr .. ','
|
||||||
|
if data_length then
|
||||||
|
-- Size
|
||||||
|
local str = ffi.string(value, data_length)
|
||||||
|
l[#l+1] = '\n\tsize = ' .. data_length .. ','
|
||||||
|
|
||||||
|
-- Element size and type
|
||||||
|
local element_type, nr_elements = get_type_and_size_of_singular(ctype)
|
||||||
|
local element_size = data_length / nr_elements
|
||||||
|
l[#l+1] = '\n\tnr_e = ' .. nr_elements .. ','
|
||||||
|
l[#l+1] = '\n\ttype_e = ' .. element_type .. ','
|
||||||
|
l[#l+1] = '\n\tsize_e = ' .. element_size .. ','
|
||||||
|
|
||||||
|
--
|
||||||
|
if is_nice_ascii_string(str) then
|
||||||
|
l[#l+1] = '\n\tstr = ' .. str .. ','
|
||||||
|
end
|
||||||
|
l[#l+1] = '\n\tbin = ' .. to_hex(str) .. ','
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
l[#l+1] = '\n}'
|
||||||
|
end
|
|
@ -9,6 +9,7 @@ do
|
||||||
-- Load number and function formatting
|
-- Load number and function formatting
|
||||||
format_number = select(2, pcall(require, thispath..'number'))
|
format_number = select(2, pcall(require, thispath..'number'))
|
||||||
format_function = select(2, pcall(require, thispath..'function'))
|
format_function = select(2, pcall(require, thispath..'function'))
|
||||||
|
format_cdata = select(2, pcall(require, thispath..'cdata'))
|
||||||
|
|
||||||
-- Load other stuff
|
-- Load other stuff
|
||||||
local was_loaded
|
local was_loaded
|
||||||
|
@ -480,6 +481,11 @@ if not format_function then
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not format_cdata then
|
||||||
|
-- Very simple cdata formatting, if cdata.lua is not available.
|
||||||
|
format_cdata = format_primitive
|
||||||
|
end
|
||||||
|
|
||||||
local TYPE_TO_FORMAT_FUNC = {
|
local TYPE_TO_FORMAT_FUNC = {
|
||||||
['nil'] = format_primitive,
|
['nil'] = format_primitive,
|
||||||
['boolean'] = format_primitive,
|
['boolean'] = format_primitive,
|
||||||
|
@ -491,7 +497,7 @@ local TYPE_TO_FORMAT_FUNC = {
|
||||||
-- TODO
|
-- TODO
|
||||||
['function'] = format_function,
|
['function'] = format_function,
|
||||||
['userdata'] = format_primitive,
|
['userdata'] = format_primitive,
|
||||||
['cdata'] = format_primitive, -- Luajit exclusive ?
|
['cdata'] = format_cdata, -- Luajit exclusive ?
|
||||||
}
|
}
|
||||||
|
|
||||||
function format_value (value, _, depth, l)
|
function format_value (value, _, depth, l)
|
||||||
|
|
|
@ -377,15 +377,35 @@ if type(jit) == 'table' then
|
||||||
|
|
||||||
format_test {
|
format_test {
|
||||||
input = ffi.C.poll,
|
input = ffi.C.poll,
|
||||||
approx = true,
|
|
||||||
expect = 'cdata<.+>: 0x%x+',
|
expect = 'cdata<.+>: 0x%x+',
|
||||||
}
|
}
|
||||||
|
|
||||||
format_test {
|
do
|
||||||
input = ffi.new('int[10]'),
|
local list = ffi.new('char [17]')
|
||||||
approx = true,
|
for i = 0, 16 do list[i] = i end
|
||||||
expect = 'cdata<.+>: 0x%x+',
|
format_test {
|
||||||
}
|
input = list,
|
||||||
|
expect = 'cdata<.+>: 0x%x+',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local list = ffi.new('char [10]')
|
||||||
|
for i = 0, 10-1 do list[i] = i + 65 end
|
||||||
|
format_test {
|
||||||
|
input = list,
|
||||||
|
expect = 'cdata<.+>: 0x%x+',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local mat = ffi.new('char [3][3]')
|
||||||
|
for x = 0, 2 do for y = 0, 2 do mat[x][y] = x * 16 + y end end
|
||||||
|
format_test {
|
||||||
|
input = mat,
|
||||||
|
expect = 'cdata<.+>: 0x%x+',
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue
Block a user