Advertisement
throwawayrobot

inspect-fenv.lua

Feb 28th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.54 KB | None | 0 0
  1. --[[ inspect-fenv
  2. returns a list of getfenv variables with PAGE_UP / PAGE_DOWN enabled by opening `edit` and removing the temp file after you exit `edit`.
  3. test
  4. Usage: pastebin run <id> [expand_key [expand_key [...] ]
  5.   e.g: pastebin run X66qGPN6 _G _ENV
  6. ]]
  7. function __INSPECT_FENV__()
  8. end
  9. local function dump(node, depth_start)
  10.     -- to make output beautiful
  11.     local function tab(amt)
  12.         local str = ""
  13.         for i=1,amt do
  14.             str = str .. "\t"
  15.         end
  16.         return str
  17.     end
  18.  
  19.     local cache, stack, output = {},{},{}
  20.     local depth = depth_start
  21.     local output_str = "{\n"
  22.  
  23.     while true do
  24.         local size = 0
  25.         for k,v in pairs(node) do
  26.             size = size + 1
  27.         end
  28.  
  29.         local cur_index = 1
  30.         for k,v in pairs(node) do
  31.             if (cache[node] == nil) or (cur_index >= cache[node]) then
  32.  
  33.                 if (string.find(output_str,"}",output_str:len())) then
  34.                     output_str = output_str .. ",\n"
  35.                 elseif not (string.find(output_str,"\n",output_str:len())) then
  36.                     output_str = output_str .. "\n"
  37.                 end
  38.  
  39.                 -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
  40.                 table.insert(output,output_str)
  41.                 output_str = ""
  42.  
  43.                 local key = "["..tostring(k).."]"
  44.                 if (type(v) == "number" or type(v) == "boolean") then
  45.                     output_str = output_str .. tab(depth) .. key .. " = "..tostring(v)
  46.                 elseif (type(v) == "table") then
  47.                     output_str = output_str .. tab(depth) .. key .. " = {\n"
  48.                     table.insert(stack,node)
  49.                     table.insert(stack,v)
  50.                     cache[node] = cur_index+1
  51.                     break
  52.                 else
  53.                     output_str = output_str .. tab(depth) .. key .. " = "..tostring(v)..""
  54.                 end
  55.  
  56.                 if (cur_index == size) then
  57.                     output_str = output_str .. "\n" .. tab(depth-1) .. "}"
  58.                 else
  59.                     output_str = output_str .. ","
  60.                 end
  61.             else
  62.                 -- close the table
  63.                 if (cur_index == size) then
  64.                     if depth < depth_start then depth = depth_start end
  65.                     output_str = output_str .. "\n" .. tab(depth-1) .. "}"
  66.                 end
  67.             end
  68.  
  69.             cur_index = cur_index + 1
  70.         end
  71.  
  72.         if (size == 0) then
  73.             output_str = output_str .. "\n" .. tab(depth-1) .. "}"
  74.         end
  75.  
  76.         if (#stack > 0) then
  77.             node = stack[#stack]
  78.             stack[#stack] = nil
  79.             depth = cache[node] == nil and depth + 1 or depth - 1
  80.             if depth < depth_start then depth = depth_start end
  81.         else
  82.             break
  83.         end
  84.     end
  85.  
  86.     -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
  87.     table.insert(output,output_str)
  88.     output_str = table.concat(output)
  89.  
  90.     return output_str
  91. end
  92.  
  93.  
  94. local function flush(file)
  95.     local h = fs.open(file, "w")
  96.     h.write("")
  97.     h.close()
  98.     return ""
  99. end
  100. local function append(file, text)
  101.     local h = fs.open(file, "a")
  102.     h.write(text)
  103.     h.close()
  104. end
  105.  
  106. local function display(log)
  107.     shell.run("edit " .. log)
  108. end
  109.  
  110. local function inspect_env(callback)
  111.     for depth=-100,100 do
  112.         _, env = pcall(getfenv, depth)
  113.         if _ then
  114.             callback(env, depth)
  115.         end
  116.     end
  117. end
  118.  
  119.  
  120.  
  121. local function cli(...)
  122.     local logfile = '/inspect-tmp-' .. os.time() .. '.log'
  123.     local args = {...}
  124.     function args:has(key)
  125.         for _, value in pairs(self) do if value == key then return true end end
  126.         return false
  127.     end
  128.     local function log(message)
  129.         append(logfile, tostring(message))
  130.     end
  131.  
  132.     flush(logfile)
  133.     inspect_env(function(env, depth)
  134.         function env:has(marker)
  135.             for x, y in pairs(self) do
  136.                 if x == marker then return true end
  137.             end
  138.             return false
  139.         end
  140.         if env:has("__INSPECT_FENV__") then
  141.             log(("[depth: %s] \n"):format(depth))
  142.         else
  143.             log(("depth: %s \n"):format(depth))
  144.         end
  145.  
  146.         for key, value in pairs(env) do
  147.             if env:has("__INSPECT_FENV__") then log("*") end
  148.             if args:has(key) then log(">") end
  149.  
  150.             log(("%s %s %s \n"):format(string.rep(" ", depth), tostring(key), tostring(value)))
  151.             if args:has(key) then
  152.                 log(("%s %s \n"):format(string.rep(" ", depth), tostring(dump(value, depth))))
  153.             end
  154.         end
  155.     end)
  156.  
  157.     display(logfile)
  158.     fs.delete(logfile)
  159. end
  160.  
  161. cli(...)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement