mirror of
https://github.com/pkulchenko/serpent.git
synced 2024-11-21 23:24:24 +00:00
Improved handling of failures in __tostring
(pkulchenko/ZeroBraneStudio#446).
This commit is contained in:
parent
d625641f65
commit
664b6eebea
@ -1,4 +1,4 @@
|
|||||||
local n, v = "serpent", 0.28 -- (C) 2012-15 Paul Kulchenko; MIT License
|
local n, v = "serpent", 0.281 -- (C) 2012-15 Paul Kulchenko; MIT License
|
||||||
local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
|
local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
|
||||||
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
|
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
|
||||||
local badtype = {thread = true, userdata = true, cdata = true}
|
local badtype = {thread = true, userdata = true, cdata = true}
|
||||||
@ -22,7 +22,7 @@ local function s(t, opts)
|
|||||||
local function safestr(s) return type(s) == "number" and tostring(huge and snum[tostring(s)] or s)
|
local function safestr(s) return type(s) == "number" and tostring(huge and snum[tostring(s)] or s)
|
||||||
or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026
|
or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026
|
||||||
or ("%q"):format(s):gsub("\010","n"):gsub("\026","\\026") end
|
or ("%q"):format(s):gsub("\010","n"):gsub("\026","\\026") end
|
||||||
local function comment(s,l) return comm and (l or 0) < comm and ' --[['..tostring(s)..']]' or '' end
|
local function comment(s,l) return comm and (l or 0) < comm and ' --[['..select(2, pcall(tostring, s))..']]' or '' end
|
||||||
local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal
|
local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal
|
||||||
and safestr(select(2, pcall(tostring, s))) or error("Can't serialize "..tostring(s)) end
|
and safestr(select(2, pcall(tostring, s))) or error("Can't serialize "..tostring(s)) end
|
||||||
local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r']
|
local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r']
|
||||||
@ -46,7 +46,9 @@ local function s(t, opts)
|
|||||||
if seen[t] then -- already seen this element
|
if seen[t] then -- already seen this element
|
||||||
sref[#sref+1] = spath..space..'='..space..seen[t]
|
sref[#sref+1] = spath..space..'='..space..seen[t]
|
||||||
return tag..'nil'..comment('ref', level) end
|
return tag..'nil'..comment('ref', level) end
|
||||||
if type(mt) == 'table' and (mt.__serialize or mt.__tostring) then -- knows how to serialize itself
|
-- protect from those cases where __tostring may fail
|
||||||
|
if type(mt) == 'table' and pcall(function() return mt.__tostring and mt.__tostring(t) end)
|
||||||
|
and (mt.__serialize or mt.__tostring) then -- knows how to serialize itself
|
||||||
seen[t] = insref or spath
|
seen[t] = insref or spath
|
||||||
if mt.__serialize then t = mt.__serialize(t) else t = tostring(t) end
|
if mt.__serialize then t = mt.__serialize(t) else t = tostring(t) end
|
||||||
ttype = type(t) end -- new value falls through to be serialized
|
ttype = type(t) end -- new value falls through to be serialized
|
||||||
|
@ -303,6 +303,11 @@ do
|
|||||||
assert(_a[0] == 0, "table with array and hash parts has the right order of elements 4/4: failed")
|
assert(_a[0] == 0, "table with array and hash parts has the right order of elements 4/4: failed")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local a = {setmetatable({abc = 123}, {__tostring = function() error("meta!") end})}
|
||||||
|
assert(pcall(serpent.line, a) == true, "`__tostring` method that returns an error is still serialized correctly.")
|
||||||
|
end
|
||||||
|
|
||||||
-- based on https://gist.github.com/mpeterv/8360307
|
-- based on https://gist.github.com/mpeterv/8360307
|
||||||
local function random_var(is_key, deep)
|
local function random_var(is_key, deep)
|
||||||
local key = math.random(1000)
|
local key = math.random(1000)
|
||||||
|
Loading…
Reference in New Issue
Block a user