Skip to content

Commit 1f99707

Browse files
committed
introduce break pre: to specify pre-command
`break LOC do: CMD` runs CMD and continue at LOC. `break LOC pre: CMD` runs CMD at LOC but keeps suspend. `binding.bp()` also has `do:` and `pre:` keywords like break command. `command:` and `nonstop:` keywords are removed from `binding.bp()`.
1 parent 20fcce3 commit 1f99707

File tree

5 files changed

+42
-48
lines changed

5 files changed

+42
-48
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,10 +387,10 @@ The `<...>` notation means the argument.
387387
* Set breakpoint on the method `<expr>.<name>`.
388388
* `b[reak] ... if: <expr>`
389389
* break if `<expr>` is true at specified location.
390+
* `b[reak] ... pre: <command>`
391+
* break and run `<command>` before stopping.
390392
* `b[reak] ... do: <command>`
391393
* break and run `<command>`, and continue.
392-
* `b[reak] ... if: <cond_expr> do: <command>`
393-
* combination of `if:` and `do:`.
394394
* `b[reak] if: <expr>`
395395
* break if: `<expr>` is true at any lines.
396396
* Note that this feature is super slow.

lib/debug/breakpoint.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ def deleted?
5050

5151
def suspend
5252
if @command
53-
provider, cmds, nonstop = @command
54-
nonstop = true if nonstop.nil?
53+
provider, pre_cmds, do_cmds = @command
54+
nonstop = true if do_cmds
55+
cmds = [*pre_cmds&.split(';;'), *do_cmds&.split(';;')]
5556
SESSION.add_preset_commands provider, cmds, kick: false, continue: nonstop
5657
end
5758

@@ -60,8 +61,9 @@ def suspend
6061

6162
def to_s
6263
s = ''.dup
63-
s << " if: #{@cond}" if defined?(@cond) && @cond
64-
s << " do: #{@command[1].join(';; ')}" if defined?(@command) && @command
64+
s << " if: #{@cond}" if defined?(@cond) && @cond
65+
s << " pre: #{@command[1]}" if defined?(@command) && @command && @command[1]
66+
s << " do: #{@command[2]}" if defined?(@command) && @command && @command[2]
6567
s
6668
end
6769

@@ -83,7 +85,7 @@ def generate_label(name)
8385
class LineBreakpoint < Breakpoint
8486
attr_reader :path, :line, :iseq
8587

86-
def initialize path, line, cond: nil, oneshot: false, hook_call: true, command: nil, nonstop: nil
88+
def initialize path, line, cond: nil, oneshot: false, hook_call: true, command: nil
8789
@path = path
8890
@line = line
8991
@cond = cond

lib/debug/session.rb

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -346,10 +346,10 @@ def process_command line
346346
# * Set breakpoint on the method `<expr>.<name>`.
347347
# * `b[reak] ... if: <expr>`
348348
# * break if `<expr>` is true at specified location.
349+
# * `b[reak] ... pre: <command>`
350+
# * break and run `<command>` before stopping.
349351
# * `b[reak] ... do: <command>`
350352
# * break and run `<command>`, and continue.
351-
# * `b[reak] ... if: <cond_expr> do: <command>`
352-
# * combination of `if:` and `do:`.
353353
# * `b[reak] if: <expr>`
354354
# * break if: `<expr>` is true at any lines.
355355
# * Note that this feature is super slow.
@@ -872,42 +872,37 @@ def delete_breakpoint arg = nil
872872
end
873873
end
874874

875-
def repl_add_breakpoint arg
876-
arg.strip!
877-
make_command = -> cmd do
878-
['break do', cmd.split(';;').map{|e| e.strip}]
879-
end
875+
BREAK_KEYWORDS = %w(if: do: pre:).freeze
880876

881-
case arg
882-
when /\Aif:\s*(.+)do:\s*(.+)\z/
883-
cond = $1
884-
cmd = make_command.call($2)
885-
when /\Aif:\s*(.+)\z/
886-
cond = $1
887-
when /\A(.+?)\s+if:\s+(.+)\s+do:\s*(.+)e\z/
888-
sig = $1
889-
cond = $2
890-
cmd = make_command.call $3
891-
when /\A(.+?)\s+if:\s+(.+)\z/
892-
sig = $1
893-
cond = $2
894-
when /\A(.+?)\s+do:(.+)\z/
895-
sig = $1
896-
cmd = make_command.call $2
897-
else
898-
sig = arg
899-
end
877+
def parse_break arg
878+
mode = :sig
879+
expr = Hash.new{|h, k| h[k] = []}
880+
arg.split(' ').each{|w|
881+
if BREAK_KEYWORDS.any?{|pat| w == pat}
882+
mode = w[0..-2].to_sym
883+
else
884+
expr[mode] << w
885+
end
886+
}
887+
expr.default_proc = nil
888+
expr.transform_values{|v| v.join(' ')}
889+
end
900890

901-
case sig
891+
def repl_add_breakpoint arg
892+
expr = parse_break arg.strip
893+
cond = expr[:if]
894+
cmd = ['break', expr[:pre], expr[:do]] if expr[:pre] || expr[:do]
895+
896+
case expr[:sig]
902897
when /\A(\d+)\z/
903-
add_line_breakpoint @tc.location.path, $1.to_i, cond: cond, command: cmd
898+
add_line_breakpoint @tc.location.path, $1.to_i, cond: expr[:if], command: cmd
904899
when /\A(.+)[:\s+](\d+)\z/
905-
add_line_breakpoint $1, $2.to_i, cond: cond, command: cmd
900+
add_line_breakpoint $1, $2.to_i, cond: expr[:if], command: cmd
906901
when /\A(.+)([\.\#])(.+)\z/
907-
@tc << [:breakpoint, :method, $1, $2, $3, cond, cmd]
902+
@tc << [:breakpoint, :method, $1, $2, $3, expr[:if], cmd]
908903
return :noretry
909904
when nil
910-
add_check_breakpoint cond
905+
add_check_breakpoint expr[:if]
911906
else
912907
@ui.puts "Unknown breakpoint format: #{arg}"
913908
@ui.puts
@@ -1263,18 +1258,15 @@ class << self
12631258
# ::DEBUGGER__.add_catch_breakpoint 'RuntimeError'
12641259

12651260
Binding.module_eval do
1266-
def bp command: nil, nonstop: nil
1261+
def bp pre: nil, do: nil
12671262
return unless SESSION.active?
1268-
cmds = ['binding.bp', command.split(";;")] if command && !command.strip.empty?
12691263

1270-
# nonstop
1271-
# nil: auto_continue if command is given
1272-
nonstop = true if cmds if nonstop == nil
1264+
if pre || (do_expr = binding.local_variable_get(:do))
1265+
cmds = ['binding.bp', pre, do_expr]
1266+
end
12731267

1274-
# maybe it is the end of the file
1275-
::DEBUGGER__.add_line_breakpoint __FILE__, __LINE__ + 1, oneshot: true, command: cmds, nonstop: nonstop
1268+
::DEBUGGER__.add_line_breakpoint __FILE__, __LINE__ + 1, oneshot: true, command: cmds
12761269
true
1277-
12781270
end
12791271
alias debug bp
12801272
end

test/debug/bp_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def program
3030
<<~RUBY
3131
1| class Foo
3232
2| def bar
33-
3| binding.bp(command: "continue")
33+
3| binding.bp(do: "continue")
3434
4| baz
3535
5| end
3636
6|

test/debug/watch_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def program
1111
3|
1212
4| def initialize(name)
1313
5| @name = name
14-
6| binding.bp(command: "watch @name")
14+
6| binding.bp(do: "watch @name")
1515
7| end
1616
8| end
1717
9|

0 commit comments

Comments
 (0)