2
DebugStepper = DebugInstrument:extend
9
onNew = function (self)
10
self.stepIntoButton = self:add(DebugInstrumentButton:new
13
onMouseUp = function (self)
14
debugger._stepPaused = false
15
debugger._stepFilter = nil
19
self.stepOverButton = self:add(DebugInstrumentButton:new
22
onMouseUp = function (self)
23
debugger._stepPaused = false
24
local prevStack = debugger._stepStack()
26
debugger._stepFilter = function (stack)
27
for i = 1, #stack - #prevStack do
30
for j = 1, #prevStack do
31
if stack[i + j] ~= prevStack[j] then
37
-- we are now executing a sub-call;
38
-- temporarily disable our line hook until
39
-- we return to the previous function
42
debug.sethook(function()
43
local state = debug.getinfo(3, 'f')
45
if state.func == prevStack[1] then
46
-- we're at least on our old function, but is
47
-- the stack depth the same?
52
state = debug.getinfo(3 + depth, 'f')
53
if not state then break end
57
if depth == #prevStack then
58
debug.sethook(debugger._stepLine, 'l')
71
self.stepOutButton = self:add(DebugInstrumentButton:new
74
onMouseUp = function (self)
75
debugger._stepPaused = false
76
local prevStack = debugger._stepStack()
78
-- disable our line hook until the current function returns
80
debug.sethook(function()
85
local state = debug.getinfo(depth, 'f')
90
elseif state.func ~= prevStack[depth - 1] then
98
debug.sethook(debugger._stepLine, 'l')
104
self.continueButton = self:add(DebugInstrumentButton:new
107
onMouseUp = function (self)
108
debugger._stepPaused = false
109
debugger.endBreakpt()
113
self.lineHighlight = self:add(Fill:new{ fill = {64, 64, 64}, height = 0, width = 0 })
115
self.sourceLines = self:add(Text:new
123
self.sourceView = self:add(Text:new{ font = self.font, wordWrap = false })
124
self.lineHeight = self.sourceView._fontObj:getHeight()
126
self.title.text = 'Source'
127
self.contentHeight = self.lineHeight * (self.lineContext + 1) * 2 + self.spacing * 3 +
128
DebugInstrumentButton.height
130
debugger.breakpt = function()
131
local print = debugger.unsourcedPrint or print
132
local caller = debug.getinfo(2, 'S')
134
debugger.showConsole()
137
print('\n' .. string.rep('=', 40))
138
print('Breakpoint, ' .. caller.short_src .. ', ' .. caller.linedefined)
139
print(string.rep('=', 40))
140
debug.sethook(debugger._stepLine, 'l')
143
debugger.endBreakpt = function()
145
if debugger.hideStack then debugger.hideStack() end
146
if debugger.hideLocals then debugger.hideLocals() end
147
debugger.hideConsole()
151
-- hook to handle stepping over source
153
debugger._stepLine = function (_, line)
154
local state = debug.getinfo(2, 'Sl')
156
if string.find(state.source, 'zoetrope/debug') or
157
(debugger._stepFilter and not debugger._stepFilter(debugger._stepStack())) then
158
--print('skipping', state.source, state.currentline, #debugger._stepStack())
162
if debugger.showStack then debugger.showStack(4) end
163
if debugger.showLocals then debugger.showLocals(4) end
165
local file = string.match(state.source, '^@(.*)')
166
self:showLine(file, line)
168
debugger._stepPaused = true
171
while debugger._stepPaused and not quit do
172
quit = debugger._miniEventLoop()
181
-- returns a table representing the call stack during a source step
183
debugger._stepStack = function()
187
local afterHook = false
190
info = debug.getinfo(level, 'f')
191
if not info then break end
194
table.insert(result, info.func)
195
elseif info.func == debugger._stepLine then
206
onResize = function (self, x, y, width, height)
207
self.sourceLines.x = x + self.spacing
208
self.sourceLines.y = y + self.spacing
209
self.sourceLines.height = height - self.sourceLines.y - self.spacing
211
self.sourceView.x = self.sourceLines.x + self.sourceLines.width + self.spacing
212
self.sourceView.y = self.sourceLines.y
213
self.sourceView.width = width - self.sourceView.x - self.spacing * 2
214
self.sourceView.height = self.sourceLines.height
216
self.lineHighlight.x = x + self.spacing
217
self.lineHighlight.y = self.sourceLines.y + self.lineHeight * self.lineContext
218
self.lineHighlight.width = width - self.spacing * 2
219
self.lineHighlight.height = self.lineHeight
221
self.stepIntoButton.x = self.sourceLines.x
222
self.stepIntoButton.y = self.sourceView.y + self.sourceView.height + self.spacing
224
self.stepOverButton.x = self.stepIntoButton.x + self.stepIntoButton.width + self.spacing
225
self.stepOverButton.y = self.stepIntoButton.y
227
self.stepOutButton.x = self.stepOverButton.x + self.stepOverButton.width + self.spacing
228
self.stepOutButton.y = self.stepOverButton.y
230
self.continueButton.x = width - self.stepOverButton.width
231
self.continueButton.y = self.stepOverButton.y
234
showLine = function (self, file, line)
236
self.sourceLines.text = ''
237
self.sourceView.text = ''
239
for i = line - self.lineContext, line + self.lineContext + 1 do
240
local source = debugger.sourceLine(file, i)
243
self.sourceLines.text = self.sourceLines.text .. i .. '\n'
244
self.sourceView.text = self.sourceView.text .. string.gsub(debugger.sourceLine(file, i), '\t', string.rep(' ', 4)) .. '\n'
248
self.title.text = file .. ':' .. line
250
self.title.text = 'Source'
251
self.sourceView.text = '(source not available)'