byebug 5.0.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/CONTRIBUTING.md +35 -13
  4. data/GUIDE.md +256 -198
  5. data/README.md +5 -11
  6. data/ext/byebug/byebug.c +5 -43
  7. data/ext/byebug/byebug.h +6 -1
  8. data/ext/byebug/context.c +4 -5
  9. data/lib/byebug/command.rb +64 -64
  10. data/lib/byebug/command_list.rb +32 -0
  11. data/lib/byebug/commands.rb +37 -0
  12. data/lib/byebug/commands/break.rb +45 -37
  13. data/lib/byebug/commands/catch.rb +52 -28
  14. data/lib/byebug/commands/condition.rb +19 -13
  15. data/lib/byebug/commands/continue.rb +15 -11
  16. data/lib/byebug/commands/delete.rb +18 -12
  17. data/lib/byebug/commands/disable.rb +9 -10
  18. data/lib/byebug/commands/disable/breakpoints.rb +13 -11
  19. data/lib/byebug/commands/disable/display.rb +13 -11
  20. data/lib/byebug/commands/display.rb +32 -24
  21. data/lib/byebug/commands/down.rb +18 -14
  22. data/lib/byebug/commands/edit.rb +42 -26
  23. data/lib/byebug/commands/enable.rb +9 -3
  24. data/lib/byebug/commands/enable/breakpoints.rb +13 -11
  25. data/lib/byebug/commands/enable/display.rb +13 -11
  26. data/lib/byebug/commands/finish.rb +23 -14
  27. data/lib/byebug/commands/frame.rb +21 -18
  28. data/lib/byebug/commands/help.rb +39 -16
  29. data/lib/byebug/commands/history.rb +16 -10
  30. data/lib/byebug/commands/info.rb +8 -5
  31. data/lib/byebug/commands/info/breakpoints.rb +16 -14
  32. data/lib/byebug/commands/info/display.rb +18 -18
  33. data/lib/byebug/commands/info/file.rb +22 -22
  34. data/lib/byebug/commands/info/line.rb +13 -11
  35. data/lib/byebug/commands/info/program.rb +13 -17
  36. data/lib/byebug/commands/interrupt.rb +13 -11
  37. data/lib/byebug/commands/irb.rb +16 -10
  38. data/lib/byebug/commands/kill.rb +19 -13
  39. data/lib/byebug/commands/list.rb +35 -24
  40. data/lib/byebug/commands/method.rb +25 -15
  41. data/lib/byebug/commands/next.rb +15 -13
  42. data/lib/byebug/commands/pry.rb +18 -11
  43. data/lib/byebug/commands/ps.rb +21 -23
  44. data/lib/byebug/commands/quit.rb +17 -11
  45. data/lib/byebug/commands/restart.rb +28 -24
  46. data/lib/byebug/commands/save.rb +23 -15
  47. data/lib/byebug/commands/set.rb +26 -19
  48. data/lib/byebug/commands/show.rb +20 -14
  49. data/lib/byebug/commands/source.rb +15 -14
  50. data/lib/byebug/commands/step.rb +15 -13
  51. data/lib/byebug/commands/thread.rb +8 -4
  52. data/lib/byebug/commands/thread/current.rb +11 -11
  53. data/lib/byebug/commands/thread/list.rb +14 -14
  54. data/lib/byebug/commands/thread/resume.rb +14 -14
  55. data/lib/byebug/commands/thread/stop.rb +14 -14
  56. data/lib/byebug/commands/thread/switch.rb +15 -14
  57. data/lib/byebug/commands/tracevar.rb +20 -16
  58. data/lib/byebug/commands/undisplay.rb +22 -18
  59. data/lib/byebug/commands/untracevar.rb +13 -11
  60. data/lib/byebug/commands/up.rb +18 -14
  61. data/lib/byebug/commands/var.rb +10 -3
  62. data/lib/byebug/commands/var/all.rb +15 -13
  63. data/lib/byebug/commands/var/args.rb +37 -0
  64. data/lib/byebug/commands/var/const.rb +25 -14
  65. data/lib/byebug/commands/var/global.rb +13 -11
  66. data/lib/byebug/commands/var/instance.rb +13 -11
  67. data/lib/byebug/commands/var/local.rb +13 -11
  68. data/lib/byebug/commands/where.rb +15 -11
  69. data/lib/byebug/context.rb +71 -73
  70. data/lib/byebug/core.rb +45 -26
  71. data/lib/byebug/errors.rb +27 -0
  72. data/lib/byebug/frame.rb +181 -0
  73. data/lib/byebug/helpers/eval.rb +67 -26
  74. data/lib/byebug/helpers/file.rb +18 -3
  75. data/lib/byebug/helpers/frame.rb +36 -39
  76. data/lib/byebug/helpers/parse.rb +15 -13
  77. data/lib/byebug/helpers/path.rb +21 -0
  78. data/lib/byebug/helpers/reflection.rb +17 -0
  79. data/lib/byebug/helpers/thread.rb +20 -14
  80. data/lib/byebug/helpers/toggle.rb +10 -5
  81. data/lib/byebug/helpers/var.rb +36 -15
  82. data/lib/byebug/interface.rb +27 -9
  83. data/lib/byebug/option_setter.rb +93 -0
  84. data/lib/byebug/printers/base.rb +3 -0
  85. data/lib/byebug/printers/plain.rb +4 -14
  86. data/lib/byebug/printers/texts/base.yml +2 -7
  87. data/lib/byebug/processors/command_processor.rb +101 -102
  88. data/lib/byebug/processors/control_processor.rb +20 -0
  89. data/lib/byebug/processors/post_mortem_processor.rb +16 -0
  90. data/lib/byebug/processors/script_processor.rb +49 -0
  91. data/lib/byebug/remote.rb +13 -7
  92. data/lib/byebug/runner.rb +39 -65
  93. data/lib/byebug/setting.rb +4 -1
  94. data/lib/byebug/settings/post_mortem.rb +0 -16
  95. data/lib/byebug/settings/savefile.rb +1 -4
  96. data/lib/byebug/subcommands.rb +27 -29
  97. data/lib/byebug/version.rb +4 -1
  98. metadata +14 -29
  99. data/lib/byebug/commands/eval.rb +0 -43
  100. data/lib/byebug/commands/info/args.rb +0 -39
  101. data/lib/byebug/commands/info/catch.rb +0 -39
  102. data/lib/byebug/commands/pp.rb +0 -41
  103. data/lib/byebug/commands/putl.rb +0 -43
  104. data/lib/byebug/processor.rb +0 -43
  105. data/lib/byebug/processors/control_command_processor.rb +0 -48
  106. data/lib/byebug/settings/verbose.rb +0 -20
  107. data/lib/byebug/state.rb +0 -12
  108. data/lib/byebug/states/control_state.rb +0 -26
  109. data/lib/byebug/states/regular_state.rb +0 -187
  110. data/lib/byebug/subcommand_list.rb +0 -33
data/README.md CHANGED
@@ -2,19 +2,16 @@
2
2
 
3
3
  [![Ver][gem]][gem_url]
4
4
  [![Gpa][gpa]][gpa_url]
5
- [![Dep][dep]][dep_url]
6
5
  [![Cov][cov]][cov_url]
7
6
  [![Git][tip]][tip_url]
8
7
 
9
8
  [gem]: https://img.shields.io/gem/v/byebug.svg
10
9
  [gpa]: https://img.shields.io/codeclimate/github/deivid-rodriguez/byebug.svg
11
- [dep]: https://img.shields.io/gemnasium/deivid-rodriguez/byebug.svg
12
10
  [cov]: https://img.shields.io/codeclimate/coverage/github/deivid-rodriguez/byebug.svg
13
11
  [tip]: https://img.shields.io/gittip/deivid-rodriguez.svg
14
12
 
15
13
  [gem_url]: https://rubygems.org/gems/byebug
16
14
  [gpa_url]: https://codeclimate.com/github/deivid-rodriguez/byebug
17
- [dep_url]: https://gemnasium.com/deivid-rodriguez/byebug
18
15
  [cov_url]: https://codeclimate.com/github/deivid-rodriguez/byebug
19
16
  [tip_url]: https://www.gittip.com/deivid-rodriguez
20
17
 
@@ -92,7 +89,6 @@ are debugging rails, start the server and once the execution gets to your
92
89
  `down` | |
93
90
  `edit` | |
94
91
  `enable` | | `breakpoints` `display`
95
- `eval` | |
96
92
  `finish` | |
97
93
  `frame` | |
98
94
  `help` | |
@@ -103,15 +99,13 @@ are debugging rails, start the server and once the execution gets to your
103
99
  `list` | |
104
100
  `method` | | `instance`
105
101
  `next` | |
106
- `pp` | |
107
102
  `pry` | |
108
103
  `ps` | |
109
- `putl` | |
110
- `quit` | `exit` |
104
+ `quit` | |
111
105
  `restart` | |
112
106
  `save` | |
113
- `set` | | `autoeval` `autoirb` `autolist` `autosave` `basename` `callstyle` `fullpath` `histfile` `histsize` `linetrace` `listsize` `post_mortem` `savefile` `stack_on_error` `verbose` `width`
114
- `show` | | `autoeval` `autoirb` `autolist` `autosave` `basename` `callstyle` `fullpath` `histfile` `histsize` `linetrace` `listsize` `post_mortem` `savefile` `stack_on_error` `verbose` `width`
107
+ `set` | | `autoirb` `autolist` `autosave` `basename` `callstyle` `fullpath` `histfile` `histsize` `linetrace` `listsize` `post_mortem` `savefile` `stack_on_error` `width`
108
+ `show` | | `autoirb` `autolist` `autosave` `basename` `callstyle` `fullpath` `histfile` `histsize` `linetrace` `listsize` `post_mortem` `savefile` `stack_on_error` `width`
115
109
  `source` | |
116
110
  `step` | |
117
111
  `thread` | | `current` `list` `resume` `stop` `switch`
@@ -154,10 +148,10 @@ See [Getting Started with Development](CONTRIBUTING.md).
154
148
  ## Credits
155
149
 
156
150
  Everybody who has ever contributed to this forked and reforked piece of
157
- software, specially:
151
+ software, especially:
158
152
 
159
153
  * @ko1, author of the awesome TracePoint API for Ruby.
160
- * @cldwalker, [debugger][]'s mantainer.
154
+ * @cldwalker, [debugger][]'s maintainer.
161
155
  * @denofevil, author of [debase][], the starting point of this.
162
156
  * @kevjames3 for testing, bug reports and the interest in the project.
163
157
  * @FooBarWidget for working and helping with remote debugging.
@@ -357,8 +357,7 @@ raw_return_event(VALUE trace_point, void *data)
357
357
  static void
358
358
  raise_event(VALUE trace_point, void *data)
359
359
  {
360
- VALUE expn_class, ancestors;
361
- VALUE path, lineno, binding, post_mortem_context;
360
+ VALUE expn_class, ancestors, path, lineno, pm_context;
362
361
  int i;
363
362
  debug_context_t *new_dc;
364
363
 
@@ -366,19 +365,14 @@ raise_event(VALUE trace_point, void *data)
366
365
 
367
366
  path = rb_tracearg_path(trace_arg);
368
367
  lineno = rb_tracearg_lineno(trace_arg);
369
- binding = rb_tracearg_binding(trace_arg);
370
368
  raised_exception = rb_tracearg_raised_exception(trace_arg);
371
369
 
372
370
  if (post_mortem == Qtrue)
373
371
  {
374
- post_mortem_context = context_dup(dc);
375
- rb_ivar_set(raised_exception, rb_intern("@__bb_file"), path);
376
- rb_ivar_set(raised_exception, rb_intern("@__bb_line"), lineno);
377
- rb_ivar_set(raised_exception, rb_intern("@__bb_binding"), binding);
378
- rb_ivar_set(raised_exception, rb_intern("@__bb_context"),
379
- post_mortem_context);
380
-
381
- Data_Get_Struct(post_mortem_context, debug_context_t, new_dc);
372
+ pm_context = context_dup(dc);
373
+ rb_ivar_set(raised_exception, rb_intern("@__bb_context"), pm_context);
374
+
375
+ Data_Get_Struct(pm_context, debug_context_t, new_dc);
382
376
  rb_debug_inspector_open(context_backtrace_set, (void *)new_dc);
383
377
  }
384
378
 
@@ -655,36 +649,6 @@ Debug_load(int argc, VALUE * argv, VALUE self)
655
649
  return status;
656
650
  }
657
651
 
658
- /*
659
- * call-seq:
660
- * Byebug.verbose? -> bool
661
- *
662
- * Returns +true+ if verbose output of TracePoint API events is enabled.
663
- */
664
- static VALUE
665
- Verbose(VALUE self)
666
- {
667
- UNUSED(self);
668
-
669
- return verbose;
670
- }
671
-
672
- /*
673
- * call-seq:
674
- * Byebug.verbose = bool
675
- *
676
- * Enable verbose output of every TracePoint API events, useful for debugging
677
- * byebug.
678
- */
679
- static VALUE
680
- Set_verbose(VALUE self, VALUE value)
681
- {
682
- UNUSED(self);
683
-
684
- verbose = RTEST(value) ? Qtrue : Qfalse;
685
- return value;
686
- }
687
-
688
652
  /*
689
653
  * call-seq:
690
654
  * Byebug.tracing? -> bool
@@ -789,8 +753,6 @@ Init_byebug()
789
753
  rb_define_module_function(mByebug, "thread_context", Thread_context, 1);
790
754
  rb_define_module_function(mByebug, "tracing?", Tracing, 0);
791
755
  rb_define_module_function(mByebug, "tracing=", Set_tracing, 1);
792
- rb_define_module_function(mByebug, "verbose?", Verbose, 0);
793
- rb_define_module_function(mByebug, "verbose=", Set_verbose, 1);
794
756
 
795
757
  Init_threads_table(mByebug);
796
758
  Init_context(mByebug);
@@ -45,7 +45,12 @@ typedef struct {
45
45
  VALUE backtrace; /* [[loc, self, klass, binding], ...] */
46
46
  } debug_context_t;
47
47
 
48
- enum frame_component { LOCATION, SELF, CLASS, BINDING };
48
+ typedef enum {
49
+ LOCATION,
50
+ SELF,
51
+ CLASS,
52
+ BINDING
53
+ } frame_part;
49
54
 
50
55
  struct call_with_inspection_data {
51
56
  debug_context_t *dc;
@@ -90,8 +90,7 @@ context_dup(debug_context_t * context)
90
90
 
91
91
 
92
92
  static VALUE
93
- dc_frame_get(const debug_context_t * context, int frame_index,
94
- enum frame_component type)
93
+ dc_frame_get(const debug_context_t * context, int frame_index, frame_part type)
95
94
  {
96
95
  VALUE frame;
97
96
 
@@ -257,7 +256,7 @@ Context_frame_file(int argc, VALUE * argv, VALUE self)
257
256
  * call-seq:
258
257
  * context.frame_line(frame_position = 0) -> int
259
258
  *
260
- * Returns the line number in the file.
259
+ * Returns the line number in the file in the frame.
261
260
  */
262
261
  static VALUE
263
262
  Context_frame_line(int argc, VALUE * argv, VALUE self)
@@ -275,7 +274,7 @@ Context_frame_line(int argc, VALUE * argv, VALUE self)
275
274
  * call-seq:
276
275
  * context.frame_method(frame_position = 0) -> sym
277
276
  *
278
- * Returns the sym of the called method.
277
+ * Returns the sym of the method in the frame.
279
278
  */
280
279
  static VALUE
281
280
  Context_frame_method(int argc, VALUE * argv, VALUE self)
@@ -640,7 +639,7 @@ dt_inherited(VALUE klass)
640
639
  *
641
640
  * == Summary
642
641
  *
643
- * Byebug keeps a single instance of this class.
642
+ * Byebug keeps a single instance of this class per thread.
644
643
  */
645
644
  void
646
645
  Init_context(VALUE mByebug)
@@ -1,4 +1,3 @@
1
- require 'columnize'
2
1
  require 'forwardable'
3
2
  require 'byebug/helpers/string'
4
3
 
@@ -6,78 +5,68 @@ module Byebug
6
5
  #
7
6
  # Parent class of all byebug commands.
8
7
  #
9
- # Subclasses need to implement a `regexp` method and an `execute` method.
8
+ # Subclass it and name the subclass ending with the word Command to implement
9
+ # your own custom command.
10
+ #
11
+ # @example
12
+ #
13
+ # class MyCustomCommand < Command
14
+ # def self.regexp
15
+ # /custom_regexp/
16
+ # end
17
+ #
18
+ # def self.description
19
+ # 'Custom long desc'
20
+ # end
21
+ #
22
+ # def.short_description
23
+ # 'Custom short desc'
24
+ # end
25
+ #
26
+ # def execute
27
+ # # My command's implementation
28
+ # end
29
+ # end
10
30
  #
11
31
  class Command
12
32
  extend Forwardable
13
33
 
14
- include Helpers::StringHelper
34
+ attr_reader :processor
15
35
 
16
- def initialize(state)
17
- @match = nil
18
- @state = state
36
+ def initialize(processor, input = self.class.to_s)
37
+ @processor = processor
38
+ @match = match(input)
19
39
  end
20
40
 
21
- def match(input)
22
- @match = regexp.match(input)
41
+ def context
42
+ @context ||= processor.context
23
43
  end
24
44
 
25
- def_delegators :'self.class', :to_name, :description
26
-
27
- #
28
- # Default help text for a command.
29
- #
30
- def help
31
- prettify(description)
45
+ def frame
46
+ @frame ||= context.frame
32
47
  end
33
48
 
34
- def_delegator :"Byebug.printer", :print, :pr
35
- def_delegator :"Byebug.printer", :print_collection, :prc
36
- def_delegator :"Byebug.printer", :print_variables, :prv
37
-
38
- protected
39
-
40
- def_delegators :@state, :errmsg, :puts, :print, :confirm
41
-
42
- #
43
- # Evaluates a string containing Ruby code, using binding +b+. In case of
44
- # error full stack trace and error are printed.
45
- #
46
- def bb_eval(str, b = get_binding)
47
- b.eval(str)
48
- rescue StandardError, ScriptError => e
49
- at = e.backtrace
50
- locations = []
51
- locations << "#{at.shift}: #{e.class} Exception(#{e.message})"
52
- locations += at.map { |path| "\tfrom #{path}" }
53
-
54
- errmsg(pr('eval.exception', text_message: locations.join("\n")))
55
- nil
49
+ def arguments
50
+ @match[0].split(' ').drop(1).join(' ')
56
51
  end
57
52
 
58
- #
59
- # Evaluates a string containing Ruby code, using binding +b+. In case of
60
- # error, an error message with the exception is printed.
61
- #
62
- def bb_warning_eval(str, b = get_binding)
63
- b.eval(str)
64
- rescue StandardError, ScriptError => e
65
- text_message = "#{e.class} Exception: #{e.message}"
66
- errmsg(pr('eval.exception', text_message: text_message))
67
- nil
68
- end
53
+ def_delegators :'self.class', :help, :match
69
54
 
70
- def get_binding(pos = @state.frame)
71
- @state.context ? @state.context.frame_binding(pos) : TOPLEVEL_BINDING
72
- end
55
+ def_delegator :'processor.printer', :print, :pr
56
+ def_delegator :'processor.printer', :print_collection, :prc
57
+ def_delegator :'processor.printer', :print_variables, :prv
58
+
59
+ def_delegators :'processor.interface', :errmsg, :puts, :print, :confirm
73
60
 
74
61
  class << self
75
- attr_accessor :allow_in_control
76
- attr_writer :allow_in_post_mortem, :always_run
62
+ include Helpers::StringHelper
77
63
 
78
- def allow_in_post_mortem
79
- !defined?(@allow_in_post_mortem) ? true : false
80
- end
64
+ #
65
+ # Special methods to allow command filtering in processors
66
+ #
67
+ attr_accessor :allow_in_control, :allow_in_post_mortem
68
+
69
+ attr_writer :always_run
81
70
 
82
71
  def always_run
83
72
  @always_run ||= 0
@@ -86,19 +75,30 @@ module Byebug
86
75
  #
87
76
  # Name of the command, as executed by the user.
88
77
  #
89
- def to_name
90
- name.gsub(/^Byebug::/, '').gsub(/Command$/, '').downcase
78
+ def to_s
79
+ name
80
+ .split('::')
81
+ .map { |n| n.gsub(/Command$/, '').downcase if n =~ /Command$/ }
82
+ .compact
83
+ .join(' ')
84
+ end
85
+
86
+ def columnize(width)
87
+ format(" %-#{width}s -- %s\n", to_s, short_description)
91
88
  end
92
89
 
93
90
  #
94
- # Available subcommands for the current command
95
- #
96
- # A subcommand is any class defined inside the parent's command class
91
+ # Default help text for a command.
97
92
  #
98
- def subcommands
99
- const_list = constants(false).map { |const| const_get(const, false) }
93
+ def help
94
+ prettify(description)
95
+ end
100
96
 
101
- const_list.select { |c| c.is_a?(Class) }
97
+ #
98
+ # Command's regexp match against an input
99
+ #
100
+ def match(input)
101
+ regexp.match(input)
102
102
  end
103
103
  end
104
104
  end
@@ -0,0 +1,32 @@
1
+ require 'byebug/errors'
2
+
3
+ module Byebug
4
+ #
5
+ # Holds an array of subcommands for a command
6
+ #
7
+ class CommandList
8
+ include Enumerable
9
+
10
+ def initialize(commands)
11
+ @commands = commands.sort_by(&:to_s)
12
+ end
13
+
14
+ def match(input)
15
+ find { |cmd| cmd.match(input) }
16
+ end
17
+
18
+ def each
19
+ @commands.each { |cmd| yield(cmd) }
20
+ end
21
+
22
+ def to_s
23
+ "\n" + map { |cmd| cmd.columnize(width) }.join + "\n"
24
+ end
25
+
26
+ private
27
+
28
+ def width
29
+ @width ||= map(&:to_s).max_by(&:size).size
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ require 'byebug/commands/break'
2
+ require 'byebug/commands/catch'
3
+ require 'byebug/commands/condition'
4
+ require 'byebug/commands/continue'
5
+ require 'byebug/commands/delete'
6
+ require 'byebug/commands/disable'
7
+ require 'byebug/commands/display'
8
+ require 'byebug/commands/down'
9
+ require 'byebug/commands/edit'
10
+ require 'byebug/commands/enable'
11
+ require 'byebug/commands/finish'
12
+ require 'byebug/commands/frame'
13
+ require 'byebug/commands/help'
14
+ require 'byebug/commands/history'
15
+ require 'byebug/commands/info'
16
+ require 'byebug/commands/interrupt'
17
+ require 'byebug/commands/irb'
18
+ require 'byebug/commands/kill'
19
+ require 'byebug/commands/list'
20
+ require 'byebug/commands/method'
21
+ require 'byebug/commands/next'
22
+ require 'byebug/commands/pry'
23
+ require 'byebug/commands/ps'
24
+ require 'byebug/commands/quit'
25
+ require 'byebug/commands/restart'
26
+ require 'byebug/commands/save'
27
+ require 'byebug/commands/set'
28
+ require 'byebug/commands/show'
29
+ require 'byebug/commands/source'
30
+ require 'byebug/commands/step'
31
+ require 'byebug/commands/thread'
32
+ require 'byebug/commands/tracevar'
33
+ require 'byebug/commands/undisplay'
34
+ require 'byebug/commands/untracevar'
35
+ require 'byebug/commands/up'
36
+ require 'byebug/commands/var'
37
+ require 'byebug/commands/where'
@@ -1,4 +1,5 @@
1
1
  require 'byebug/command'
2
+ require 'byebug/helpers/eval'
2
3
  require 'byebug/helpers/file'
3
4
  require 'byebug/helpers/parse'
4
5
 
@@ -7,16 +8,32 @@ module Byebug
7
8
  # Implements breakpoint functionality
8
9
  #
9
10
  class BreakCommand < Command
11
+ include Helpers::EvalHelper
10
12
  include Helpers::FileHelper
11
13
  include Helpers::ParseHelper
12
14
 
13
- self.allow_in_post_mortem = false
14
15
  self.allow_in_control = true
15
16
 
16
- def regexp
17
+ def self.regexp
17
18
  /^\s* b(?:reak)? (?:\s+ (\S+))? (?:\s+ if \s+(.+))? \s*$/x
18
19
  end
19
20
 
21
+ def self.description
22
+ <<-EOD
23
+ b[reak] [file:]line [if expr]
24
+ b[reak] [module::...]class(.|#)method [if expr]
25
+
26
+ They can be specified by line or method and an expression can be added
27
+ for conditionally enabled breakpoints.
28
+
29
+ #{short_description}
30
+ EOD
31
+ end
32
+
33
+ def self.short_description
34
+ 'Sets breakpoints in the source code'
35
+ end
36
+
20
37
  def execute
21
38
  return puts(help) unless @match[1]
22
39
 
@@ -28,62 +45,53 @@ module Byebug
28
45
 
29
46
  errmsg(pr('break.errors.expression', expr: @match[2]))
30
47
  b.enabled = false
31
- rescue => e
32
- errmsg(e.message)
33
- end
34
-
35
- def short_description
36
- 'Set breakpoint to some position, (optionally) if expr == true'
37
- end
38
-
39
- def description
40
- <<-EOD
41
- b[reak] [file:]line [if expr]
42
- b[reak] [module::...]class(.|#)method [if expr]
43
-
44
- #{short_description}
45
- EOD
46
48
  end
47
49
 
48
50
  private
49
51
 
50
- def line_breakpoint(loc)
51
- line = loc.match(/^(\d+)$/)
52
- file_line = loc.match(/^([^:]+):(\d+)$/)
53
- return nil unless line || file_line
52
+ def line_breakpoint(location)
53
+ line_match = location.match(/^(\d+)$/)
54
+ file_line_match = location.match(/^([^:]+):(\d+)$/)
55
+ return unless line_match || file_line_match
54
56
 
55
- f, l = line ? [@state.file, line[1]] : [file_line[1], file_line[2]]
57
+ file = line_match ? frame.file : file_line_match[1]
58
+ line = line_match ? line_match[1].to_i : file_line_match[2].to_i
56
59
 
57
- check_errors(f, l.to_i)
58
-
59
- Breakpoint.add(File.expand_path(f), l.to_i, @match[2])
60
+ add_line_breakpoint(file, line)
60
61
  end
61
62
 
62
63
  def method_breakpoint(location)
63
64
  location.match(/([^.#]+)[.#](.+)/) do |match|
64
- k = bb_warning_eval(match[1])
65
- m = match[2]
66
-
67
- klass = k && k.is_a?(Module) ? k.name : match[1]
68
- method = m.intern
65
+ klass = target_object(match[1])
66
+ method = match[2].intern
69
67
 
70
68
  Breakpoint.add(klass, method, @match[2])
71
69
  end
72
70
  end
73
71
 
74
- def check_errors(file, line)
75
- path = File.expand_path(file)
76
- deco_path = normalize(file)
72
+ def target_object(str)
73
+ k = warning_eval(str)
74
+
75
+ k && k.is_a?(Module) ? k.name : str
76
+ rescue
77
+ errmsg('Warning: breakpoint source is not yet defined')
78
+ str
79
+ end
80
+
81
+ def add_line_breakpoint(file, line)
82
+ fail(pr('break.errors.source', file: file)) unless File.exist?(file)
77
83
 
78
- fail(pr('break.errors.source', file: deco_path)) unless File.exist?(path)
84
+ fullpath = File.realpath(file)
79
85
 
80
86
  if line > n_lines(file)
81
- fail(pr('break.errors.far_line', lines: n_lines(file), file: deco_path))
87
+ fail(pr('break.errors.far_line', lines: n_lines(file), file: fullpath))
82
88
  end
83
89
 
84
- return if Breakpoint.potential_line?(path, line)
90
+ unless Breakpoint.potential_line?(fullpath, line)
91
+ fail(pr('break.errors.line', file: fullpath, line: line))
92
+ end
85
93
 
86
- fail(pr('break.errors.line', file: deco_path, line: line))
94
+ Breakpoint.add(fullpath, line, @match[2])
87
95
  end
88
96
  end
89
97
  end