Fixed order of elements in the array part with sortkeys=true (fixes #13).

This commit is contained in:
Paul Kulchenko 2014-01-10 10:27:26 -08:00
parent 06873d12cd
commit 7d56d50a9c
2 changed files with 15 additions and 5 deletions

View File

@ -1,4 +1,4 @@
local n, v = "serpent", 0.26 -- (C) 2012-13 Paul Kulchenko; MIT License
local n, v = "serpent", 0.261 -- (C) 2012-13 Paul Kulchenko; MIT License
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 badtype = {thread = true, userdata = true, cdata = true}
@ -30,13 +30,13 @@ local function s(t, opts)
local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n]
local safe = plain and n or '['..safestr(n)..']'
return (path or '')..(plain and path and '.' or '')..safe, safe end
local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding
local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding
local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'}
local function padnum(d) return ("%0"..maxn.."d"):format(d) end
table.sort(k, function(a,b)
-- sort numeric keys first: k[key] is non-nil for numeric keys
return (k[a] and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
< (k[b] and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
-- sort numeric keys first: `o[key] == key and type(key) == 'number'` is true for numeric keys
return (o[a] == a and type(a) == 'number' and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
< (o[b] == b and type(b) == 'number' and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
local function val2str(t, name, indent, insref, path, plainindex, level)
local ttype, level, mt = type(t), (level or 0), getmetatable(t)
local spath, sname = safename(path, name)

View File

@ -285,6 +285,16 @@ do
"deserialization of unsafe values disabled: failed")
end
do
local a = {1, 2, 3, 4, [false] = 0, [true] = 0}
local f = assert(loadstring('return '..serpent.line(a)),
"serializing table with numerical and boolean keys: failed")
local _a = f()
assert(#_a == #a, "table with array and hash part has the right number of elements: failed")
assert(_a[3] == a[3], "table with array and hash parts has the right order of elements 1/2: failed")
assert(_a[4] == a[4], "table with array and hash parts has the right order of elements 2/2: failed")
end
print("All tests passed.")
do