@@ -180,6 +180,25 @@ function next_line!(@nospecialize(recurse), frame::Frame, istoplevel::Bool=false
180
180
end
181
181
next_line! (frame:: Frame , istoplevel:: Bool = false ) = next_line! (finish_and_return!, frame, istoplevel)
182
182
183
+ """
184
+ pc = until_line!(recurse, frame, line=nothing istoplevel=false)
185
+ pc = until_line!(frame, line=nothing, istoplevel=false)
186
+
187
+ Execute until the current frame reaches a line greater than `line`. If `line == nothing`
188
+ execute until the current frame reaches any line greater than the current line.
189
+ """
190
+ function until_line! (@nospecialize (recurse), frame:: Frame , line:: Union{Nothing, Integer} = nothing , istoplevel:: Bool = false )
191
+ pc = frame. pc
192
+ initialline, initialfile = linenumber (frame, pc), getfile (frame, pc)
193
+ line === nothing && (line = initialline + 1 )
194
+ predicate (frame) = isexpr (pc_expr (frame), :return ) || (linenumber (frame) >= line && getfile (frame) == initialfile)
195
+ pc = next_until! (predicate, frame, istoplevel)
196
+ (pc === nothing || isa (pc, BreakpointRef)) && return pc
197
+ maybe_step_through_kwprep! (recurse, frame, istoplevel)
198
+ maybe_next_call! (recurse, frame, istoplevel)
199
+ end
200
+ until_line! (frame:: Frame , line:: Union{Nothing, Integer} = nothing , istoplevel:: Bool = false ) = until_line! (finish_and_return!, frame, line, istoplevel)
201
+
183
202
"""
184
203
cframe = maybe_step_through_wrapper!(recurse, frame)
185
204
cframe = maybe_step_through_wrapper!(frame)
@@ -343,13 +362,15 @@ function unwind_exception(frame::Frame, exc)
343
362
end
344
363
345
364
"""
346
- ret = debug_command(recurse, frame, cmd, rootistoplevel=false)
347
- ret = debug_command(frame, cmd, rootistoplevel=false)
365
+ ret = debug_command(recurse, frame, cmd, rootistoplevel=false; line=nothing )
366
+ ret = debug_command(frame, cmd, rootistoplevel=false; line=nothing )
348
367
349
- Perform one "debugger" command. `cmd` should be one of:
368
+ Perform one "debugger" command. The keyword arguments are not used for all debug commands.
369
+ `cmd` should be one of:
350
370
351
371
- `:n`: advance to the next line
352
372
- `:s`: step into the next call
373
+ - `:until`: advance the frame to line `line` if given, otherwise advance to the line after the current line
353
374
- `:c`: continue execution until termination or reaching a breakpoint
354
375
- `:finish`: finish the current frame and return to the parent
355
376
@@ -362,7 +383,7 @@ or one of the 'advanced' commands
362
383
363
384
`rootistoplevel` and `ret` are as described for [`JuliaInterpreter.maybe_reset_frame!`](@ref).
364
385
"""
365
- function debug_command (@nospecialize (recurse), frame:: Frame , cmd:: Symbol , rootistoplevel:: Bool = false )
386
+ function debug_command (@nospecialize (recurse), frame:: Frame , cmd:: Symbol , rootistoplevel:: Bool = false ; line = nothing )
366
387
function nicereturn! (@nospecialize (recurse), frame, pc, rootistoplevel)
367
388
if pc === nothing || isa (pc, BreakpointRef)
368
389
return maybe_reset_frame! (recurse, frame, pc, rootistoplevel)
@@ -383,6 +404,7 @@ function debug_command(@nospecialize(recurse), frame::Frame, cmd::Symbol, rootis
383
404
cmd == :nc && return nicereturn! (recurse, frame, next_call! (recurse, frame, istoplevel), rootistoplevel)
384
405
cmd == :n && return maybe_reset_frame! (recurse, frame, next_line! (recurse, frame, istoplevel), rootistoplevel)
385
406
cmd == :se && return maybe_reset_frame! (recurse, frame, step_expr! (recurse, frame, istoplevel), rootistoplevel)
407
+ cmd == :until && return maybe_reset_frame! (recurse, frame, until_line! (recurse, frame, line, istoplevel), rootistoplevel)
386
408
387
409
enter_generated = false
388
410
if cmd == :sg
@@ -434,5 +456,5 @@ function debug_command(@nospecialize(recurse), frame::Frame, cmd::Symbol, rootis
434
456
end
435
457
throw (ArgumentError (" command $cmd not recognized" ))
436
458
end
437
- debug_command (frame:: Frame , cmd:: Symbol , rootistoplevel:: Bool = false ) =
438
- debug_command (finish_and_return!, frame, cmd, rootistoplevel)
459
+ debug_command (frame:: Frame , cmd:: Symbol , rootistoplevel:: Bool = false ; kwargs ... ) =
460
+ debug_command (finish_and_return!, frame, cmd, rootistoplevel; kwargs ... )
0 commit comments