-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdebug
229 lines (204 loc) · 5.01 KB
/
debug
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
--debug
debug={}
local error=_G._error or _G.error
local function wrap(text, limit) --from Kingdaroo
local lines = {''}
for word, space in text:gmatch('(%S+)(%s*)') do
local temp = lines[#lines] .. word .. space:gsub('\n','')
if #temp > limit then
table.insert(lines, '')
end
if space:find('\n') then
lines[#lines] = lines[#lines] .. word
space = space:gsub('\n', function()
table.insert(lines, '')
return ''
end)
else
lines[#lines] = lines[#lines] .. word .. space
end
end
return lines
end
function step_print(s,_term)
local term=_term or term
local x,y=term.getSize()
y=y-1
local t=wrap(s,x)
local r=#t%y
local n=(#t-r)/y
for i=0,n-1 do
if i~=0 then write'\n' end
write(table.concat(t,'\n',i*y+1,(i+1)*y))
write('\nPress any key to continue')
os.pullEvent('key')
end
write('\n')
write(table.concat(t,'\n',n*y+1,n*y+r))
write('\n')
end
function printError( ... )
if term.isColour() then
term.setTextColour( colours.red )
end
local t={...}
for i=1,#t do t[i]=tostring(t[i]) end
step_print(table.concat(t,''),term)
term.setTextColour( colours.white )
end
--[[ Notes:
getfenv(1)=getfenv()~=getfenv(0)~~_G
error('',1)~=error('',0)
]]
rawset(_G,'loadfile',
function( _sFile )
local file = fs.open( _sFile, "r" )
if file then
local func, err = loadstring( file.readAll(),_sFile)
file.close()
return func, err
end
return nil, "File not found"
end)
local ttraceback=function(level,terr)
local terr=terr or {}
local passed={}
local err,ok=terr,last
local j=level or 0
repeat
j=j+1
passed[err]=true
ok,err=pcall(error,'',j)
if err:match('^[^:]+')=='bios' then break end
table.insert(terr,err)
if j > 32 or last == err then break end
last = err
until (false)--(passed[err])
return terr
end
local function classify(t,f)
local bins={}
local c
for i,v in ipairs(t) do
local fi,r=f(v)
if fi~=nil then
if c==nil or c.n~=fi then
table.insert(bins,c)
c={n=fi}
end
table.insert(c,r)
end
end
table.insert(bins,c)
return bins
end
local function get_chunks(terr)
return classify(terr,function(v) return v:match('^([^:]+):(.*)') end)
end
local function get_lines(terr)
return classify(terr,function(v) return v:match('^(%d+):(.*)') end)
end
local function put_lines(path,diameter,ts,l,short,name)
local line,f0,f1
local functionName = "no function"
local ok,f=pcall(fs.open,path,'r')
local lines = {}
if not ok or not f then table.insert(ts,' (could not open file)')
else
repeat
line = f:readLine()
table.insert(lines, line)
until not line
for i=1,l-diameter-1 do
line = lines[i]
f0 = line:find("--")
f1 = line:find("function")
if f1 ~= nil and (f0 == nil or f0 >= f1) then
functionName = line:match('^.*function (.*)')
end
end
for i=l-diameter,l-1 do
line = lines[i]
if line ~= nil then
f0 = line:find("--")
f1 = line:find("function")
if f1 ~= nil and (f0 == nil or f0 >= f1) then
functionName = line:match('^.*function (.*)')
end
table.insert(ts," ["..functionName.."] "..line)
end
end
line = lines[l]
if not short then
table.insert(ts,"-> ["..functionName.."] "..line)
else
table.insert(ts,name..":"..l..":"..functionName..": "..line)
end
for i=l+1,l+diameter do
line = lines[i]
if line then
table.insert(ts," ["..functionName.."] "..line)
else
break
end
end
end
end
local function format_traceback(terr,numExtraLines,short)
numExtraLines = numExtraLines or 1
short = short or false
local ts={}
for i,v in ipairs(get_chunks(terr)) do
local name=v.n or '(no name)'
local path
if fs.exists(name) then
name,dir,path=fs.getName(name),name:match('^(.*)/') or '/',name
if not short then
name=name..' ('..(dir or 'unknown')..')'
end
elseif false then
--shell has input string; modify to behave as file?
end
if not short then
table.insert(ts,name)
end
for j,line in ipairs(get_lines(v)) do
if not short then
table.insert(ts,' line '..(line.n or '(no line)')..', *'..(#line))
end
local n=line.n and tonumber(line.n) or 1
if path and n then
put_lines(path,numExtraLines,ts,n,short,name)
end
end
end
return ts
end
function currentFunction()
local path,dir,name
local r = format_traceback(ttraceback(0,{}),0,true)
r[#r] = nil
r = r[#r]
return r
end
function depth()
local r = ttraceback(0,{})
return #r-5
end
function traceback(msg,level)
local level=level or 0
msg= msg or 'traceback'
local ts=format_traceback(ttraceback(level+1,{}),1,false)
table.insert(ts,1,msg)
msg = table.concat(ts,'\n')
msg = string.gsub(msg, "\n\n", "\n")
return msg
end
function printTraceback(msg,level)
printError(traceback(msg,(level or 0)+1))
end
function override()
rawset(_G,'_error',error)
rawset(_G,'error',traceback)
rawset(_G,'printError',printError)
end