apemanzilla

trace

Oct 21st, 2016
610
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local args = {...}
  2.  
  3. if not args[1] then
  4.     print("Usage:")
  5.     print(shell.getRunningProgram() .. " <program> [program arguments, ...]")
  6.     return
  7. end
  8.  
  9. local path = shell.resolveProgram(args[1]) or shell.resolve(args[1])
  10.  
  11. -- here be dragons
  12. local function buildStackTrace(rootErr)
  13.     local trace = {}
  14.     local i, hitEnd, _, e = 4, false
  15.  
  16.     repeat
  17.         _, e = pcall(function() error("<tracemarker>", i) end)
  18.         i = i + 1
  19.         if e == "xpcall: <tracemarker>" or e == "pcall: <tracemarker>" then
  20.             hitEnd = true
  21.             break
  22.         end
  23.         table.insert(trace, e)
  24.     until i > 10
  25.  
  26.     table.remove(trace)
  27.     table.remove(trace, 1)
  28.  
  29.     if rootErr:match("^" .. trace[1]:match("^(.-:%d+)")) then table.remove(trace, 1) end
  30.  
  31.     local out = {}
  32.  
  33.     table.insert(out, rootErr)
  34.    
  35.     for i, v in ipairs(trace) do
  36.         table.insert(out, "  at " .. v:match("^(.-:%d+)"))
  37.     end
  38.  
  39.     if not hitEnd then
  40.         table.insert(out, "  ...")
  41.     end
  42.  
  43.     return table.concat(out, "\n")
  44. end
  45.  
  46. if fs.exists(path) then
  47.     local eshell = setmetatable({getRunningProgram=function() return path end}, {__index = shell})
  48.     local env = setmetatable({shell=eshell}, {__index=_ENV})
  49.    
  50.     env.pcall = function(f, ...)
  51.         local args = { ... }
  52.         return xpcall(function() f(unpack(args)) end, buildStackTrace)
  53.     end
  54.  
  55.     env.xpcall = function(f, e)
  56.         return xpcall(function() f() end, function(err) e(buildStackTrace(err)) end)
  57.     end
  58.  
  59.     local f = fs.open(path, "r")
  60.     local d = f.readAll()
  61.     f.close()
  62.    
  63.     local func, e = load(d, fs.getName(path), nil, env)
  64.     if not func then
  65.         printError("Syntax error:")
  66.         printError("  " .. e)
  67.     else
  68.         table.remove(args, 1)
  69.         xpcall(function() func(unpack(args)) end, function(err)
  70.             local stack = buildStackTrace(err)
  71.             printError("\nProgram has crashed! Stack trace:")
  72.             printError(stack)
  73.         end)
  74.     end
  75. else
  76.     printError("program not found")
  77. end
RAW Paste Data