@@ -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 /\A if:\s *(.+)do:\s *(.+)\z /
883- cond = $1
884- cmd = make_command . call ( $2)
885- when /\A if:\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
0 commit comments