View difference between Paste ID: nf3ZrxYV and CYQp63kb
SHOW: | | - or go back to the newest paste.
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