Fixed an issue with string keys with numeric values ['3'] getting mixed with real numeric keys

This commit is contained in:
Paul Kulchenko 2012-06-13 11:07:59 -07:00
parent 428061f498
commit 82a4aee176
3 changed files with 13 additions and 7 deletions

View File

@ -127,6 +127,10 @@ See LICENSE file.
## History
Jun 13 2012 v0.14
- Fixed an issue with string keys with numeric values `['3']` getting mixed
with real numeric keys (only with `sortkeys` option set to `true`).
Jun 13 2012 v0.13
- Added maxlevel option.
- Fixed key sorting such that `true` and `'true'` are always sorted in

View File

@ -1,4 +1,4 @@
local n, v = "serpent", 0.13 -- (C) 2012 Paul Kulchenko; MIT License
local n, v = "serpent", 0.14 -- (C) 2012 Paul Kulchenko; MIT License
local c, d = "Paul Kulchenko", "Serializer and pretty printer of Lua data types"
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}
@ -29,11 +29,11 @@ local function s(t, opts)
local safe = plain and n or '['..safestr(n)..']'
return (path or '')..(plain and path and '.' or '')..safe, safe end
local function alphanumsort(o, n)
local maxn = tonumber(n) or 12
local maxn, torder = tonumber(n) or 12, {number = 'a', string = 'b'}
local function padnum(d) return ("%0"..maxn.."d"):format(d) end
table.sort(o, function(a,b)
return tostring(a):gsub("%d+",padnum)..type(a)
< tostring(b):gsub("%d+",padnum)..type(b) end) end
return (torder[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
< (torder[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end
local function val2str(t, name, indent, path, plainindex, level)
local ttype, level = type(t), (level or 0)
local spath, sname = safename(path, name)

View File

@ -16,7 +16,7 @@ local a = {
['true'] = 'some value', -- keyword as a key
z = c, -- function as value
list={'a',nil,nil, -- embedded nils
[9]='i','f',[5]='g',[7]={}}, -- empty table
[9]='i','f',[5]='g',[7]={}, ['3'] = 33}, -- empty table
[c] = print, -- function as key, global as value
[io.stdin] = 3, -- global userdata as key
['label 2'] = b, -- shared reference
@ -31,8 +31,10 @@ print("line: " .. serpent.line(a) .. "\n")
local str = serpent.dump(a)
print("full: " .. str .. "\n")
local fun, err = loadstring(str)
if err then error(err) end
local fun, err = assert(loadstring(str))
assert(loadstring(serpent.line(a, {name = '_'})), "line() method produces deserializable output: failed")
assert(loadstring(serpent.block(a, {name = '_'})), "block() method produces deserializable output: failed")
local _a = fun()
local _b = _a['label 2'] -- shared reference