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 |