From 79b036e51eb7926e874a950f6484caafab62f90f Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Sat, 21 Oct 2017 13:24:33 +0200 Subject: [PATCH] Fixed bugs relating to weird __tostring metamethods. --- analyze_structure.lua | 21 +++++++++++++++++++-- test/test_sorting.lua | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/analyze_structure.lua b/analyze_structure.lua index 65cf62e..3799b9a 100644 --- a/analyze_structure.lua +++ b/analyze_structure.lua @@ -217,13 +217,31 @@ local function is_leaf_node (t) return true end +local function super_tostring (t) + -- Normally taking `tostring` of a value returns a string, but Lua does not + -- enforce that __tostring must return a string, so this function attempts + -- to find a definitive `tostring` representation, even if metatable + -- shenanigans has occurred. + -- Is guaranteed to either return a string or a nil. Nil only occurs if the + -- function cannot find a string. + + local seen = { [t] = true } + while true do + local nt = tostring(t) + if type(nt) == 'string' or nt == nil then return tostring(nt) end + if seen[nt] then return nil end + seen[nt], t = true, nt + end +end + -------------------------------------------------------------------------------- local function get_table_info (t) local key_types = get_key_types(t) local info = {} - info.address = tostring(t):sub(8) + info.string_repr = super_tostring(t) + info.address = info.string_repr and info.string_repr:match '^table: 0x(%x+)$' or nil info.nr_elems = nr_elements_in_table(t) info.seq_elems, info.has_holes = nr_elements_in_seq(t) info.map_elems = info.nr_elems - info.seq_elems @@ -288,7 +306,6 @@ local function analyze_structure (root, max_depth, info) -- Use depth collected for node in pairs(depth) do info[node].depth = depth[node] - info[node].address = info[node].address .. ': ' .. info[node].depth end assert(type(info) == 'table') diff --git a/test/test_sorting.lua b/test/test_sorting.lua index 625288e..b39346a 100644 --- a/test/test_sorting.lua +++ b/test/test_sorting.lua @@ -87,7 +87,7 @@ format_test { format_test { name = 'Proper sorting of number strings keys', - input = { ['-100'] = 'b', ['-1'] = 'c', ['0'] = 'd', ['1'] = 'e', ['100'] = 'f' }, + input = { ['-100'] = 'a', ['-1'] = 'b', ['0'] = 'c', ['1'] = 'd', ['100'] = 'e' }, expect = '{\n [\'-100\'] = \'b\', [\'-1\'] = \'c\',\n [\'0\'] = \'d\', [\'1\'] = \'e\',\n [\'100\'] = \'f\'\n}', }