-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.lua
110 lines (83 loc) · 2.28 KB
/
run.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
local cf = require "cf"
local sys = require "sys"
local now = sys.now
local type = type
local pcall = pcall
local loadfile = loadfile
local srep = string.rep
local fmt = string.format
local debug_getinfo = debug.getinfo
local debug_sethook = debug.sethook
local USAGE = [[
Run [command] :
[filename] - Execute lua script file.(e.g: script/test.lua)
]]
local cmd = {}
cmd.runerr = [[
error: %s
]]
cmd.loaderr = [[
error: %s
]]
return function (filename, trace)
if not filename then
return USAGE
end
local f, err = loadfile(filename)
if type(f) ~= "function" then
return string.format(cmd.loaderr, err)
end
local co = cf.self()
cf.fork(function ()
local list = {}
local space = 0
local back = nil
local function hook(action)
local info = debug_getinfo(2, 'Snulf')
if info.what ~= 'C' then
if action == 'line' then
list[#list+1] = info
info.action = action
info.space = space
elseif action == 'call' then
space = space + 1
elseif action == 'tail call' then
space = space + 1
back = (back or 0) + 1
elseif action == 'return' then
list[#list+1] = info
info.action = action
info.space = space
space = space - 1
if back then
space = space - back
back = nil
end
end
end
end
local s = now()
if trace then
debug_sethook(hook, 'crl')
end
local ok, errinfo = pcall(f)
if trace then
debug_sethook(nil)
end
local e = now()
if trace then
for index = 1, #list do
local current = list[index]
list[index] = fmt(" %s [OK] [%s] [%s:%d]", '└' .. srep('--', ((current.space and current.space > 0 and current.space or 1 ) or 1) * 2) .. ">", current.action == "line" and "NEXT LINE" or "GOTO BACK", current.short_src, current.currentline)
end
list[1] = fmt("callstack traceback:")
if not ok then
list[#list-1] = fmt(' %s [ERR] %s', '└' .. srep('--', 2) .. ">", errinfo)
end
end
-- 计算运行耗时.
list[#list == 0 and 1 or #list + 1] = fmt("\r\nTotal Running Time: %.3f\r\nDone.", e - s)
cf.wakeup(co, table.concat(list, "\r\n"))
end)
return cf.wait()
end