Dump.lua

   1  ------------------------------------------------------------------------------
   2  -- Dump.lua
   3  ------------------------------------------------------------------------------
   4  
   5  local P = {}
   6  
   7  function P.indented(level, ...)
   8    write(strrep('  ', level), call(format, arg), '\n')
   9  end
  10  
  11  function P.sortpairs(t)
  12    local size = getn(t)
  13    local names = {}
  14    for name,_ in t do
  15      if type(name)~='number'
  16      or name<1 or name>size or name~=floor(name) then
  17        tinsert(names, name)
  18      end
  19    end
  20    sort(names, function(a,b) return tostring(a) < tostring(b) end)
  21    return names
  22  end
  23  
  24  function P.objectname(reverse, value)
  25    local name = reverse[value] or ''
  26    return tostring(value) ..' -- '.. name
  27  end
  28  
  29  function P.dumpval(level, visited, reverse, name, value)
  30    if type(name)=='number' then
  31      name = format('[%s]', tostring(name))
  32    elseif type(name)=='string' and strfind(name, '^[_%a][_%w]*$') then
  33      -- name is okay
  34    else
  35      name = format('[%q]', tostring(name))
  36    end
  37  
  38    local tv = type(value)
  39    if tv=='table' and not visited[value] then
  40      visited[value] = 1
  41      %P.indented(level, "%s = { -- %s", name, %P.objectname(reverse, value))
  42      local sorted = %P.sortpairs(value)
  43      for i = 1,getn(sorted) do
  44        %P.dumpval(level+1, visited, reverse, sorted[i], rawget(value, sorted[i]))
  45      end
  46      for index = 1,getn(value) do
  47        %P.dumpval(level+1, visited, reverse, index, rawget(value,index))
  48      end
  49      %P.indented(level, '};')
  50    elseif tv=='string' then
  51      if strlen(value) > 50 then
  52        %P.indented(level, "%-12s = [[\n%s]];", name, value)
  53      else
  54        %P.indented(level, "%-12s = %q;", name, value)
  55      end
  56    elseif tv=='number' then
  57      %P.indented(level, "%-12s = %0.16g;", name, value)
  58    elseif tv=='boolean' then
  59      %P.indented(level, "%-12s = %s;", name, tostring(value))
  60    else
  61      %P.indented(level, "%-12s = %q;", name, tostring(value))
  62    end
  63  end
  64  
  65  local dump
  66  function dump(name, value)
  67    local g = globals()
  68    local reverse = {}
  69    for n,v in g do
  70      if type(n)=='string' then reverse[v] = n end
  71    end
  72    assert(type(name)=='string', 'expecting string')
  73    %P.dumpval(0, {}, reverse, name, value)
  74  end
  75  
  76  local eg = [[
  77  t = { 3,22,111 ; a = 'one', b = 'two' }
  78  t.back = t
  79  cat = { 'the', 'junk' }
  80  t.junk = cat
  81  
  82  dump('globals', globals())
  83  --]]
  84  
  85  return dump