byebug 9.0.5 → 11.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +399 -264
  3. data/CONTRIBUTING.md +12 -19
  4. data/GUIDE.md +40 -26
  5. data/LICENSE +18 -18
  6. data/README.md +103 -74
  7. data/exe/byebug +6 -0
  8. data/ext/byebug/breakpoint.c +2 -2
  9. data/ext/byebug/byebug.c +26 -31
  10. data/ext/byebug/byebug.h +44 -28
  11. data/ext/byebug/context.c +45 -32
  12. data/ext/byebug/extconf.rb +7 -5
  13. data/ext/byebug/locker.c +4 -4
  14. data/ext/byebug/threads.c +12 -12
  15. data/lib/byebug/attacher.rb +18 -4
  16. data/lib/byebug/breakpoint.rb +26 -6
  17. data/lib/byebug/command.rb +20 -14
  18. data/lib/byebug/command_list.rb +3 -1
  19. data/lib/byebug/commands/break.rb +36 -22
  20. data/lib/byebug/commands/catch.rb +16 -18
  21. data/lib/byebug/commands/condition.rb +11 -11
  22. data/lib/byebug/commands/continue.rb +32 -12
  23. data/lib/byebug/commands/debug.rb +7 -5
  24. data/lib/byebug/commands/delete.rb +13 -11
  25. data/lib/byebug/commands/disable/breakpoints.rb +7 -5
  26. data/lib/byebug/commands/disable/display.rb +7 -5
  27. data/lib/byebug/commands/disable.rb +8 -6
  28. data/lib/byebug/commands/display.rb +11 -9
  29. data/lib/byebug/commands/down.rb +10 -8
  30. data/lib/byebug/commands/edit.rb +11 -8
  31. data/lib/byebug/commands/enable/breakpoints.rb +7 -5
  32. data/lib/byebug/commands/enable/display.rb +7 -5
  33. data/lib/byebug/commands/enable.rb +8 -6
  34. data/lib/byebug/commands/finish.rb +9 -7
  35. data/lib/byebug/commands/frame.rb +11 -9
  36. data/lib/byebug/commands/help.rb +7 -5
  37. data/lib/byebug/commands/history.rb +7 -5
  38. data/lib/byebug/commands/info/breakpoints.rb +18 -14
  39. data/lib/byebug/commands/info/display.rb +16 -9
  40. data/lib/byebug/commands/info/file.rb +13 -14
  41. data/lib/byebug/commands/info/line.rb +5 -3
  42. data/lib/byebug/commands/info/program.rb +8 -6
  43. data/lib/byebug/commands/info.rb +11 -9
  44. data/lib/byebug/commands/interrupt.rb +8 -4
  45. data/lib/byebug/commands/irb.rb +13 -12
  46. data/lib/byebug/commands/kill.rb +11 -11
  47. data/lib/byebug/commands/list.rb +41 -46
  48. data/lib/byebug/commands/method.rb +10 -8
  49. data/lib/byebug/commands/next.rb +8 -6
  50. data/lib/byebug/commands/pry.rb +10 -10
  51. data/lib/byebug/commands/quit.rb +10 -8
  52. data/lib/byebug/commands/restart.rb +30 -11
  53. data/lib/byebug/commands/save.rb +10 -8
  54. data/lib/byebug/commands/set.rb +13 -11
  55. data/lib/byebug/commands/show.rb +7 -5
  56. data/lib/byebug/commands/skip.rb +85 -0
  57. data/lib/byebug/commands/source.rb +7 -7
  58. data/lib/byebug/commands/step.rb +8 -6
  59. data/lib/byebug/commands/thread/current.rb +6 -4
  60. data/lib/byebug/commands/thread/list.rb +7 -5
  61. data/lib/byebug/commands/thread/resume.rb +7 -7
  62. data/lib/byebug/commands/thread/stop.rb +6 -4
  63. data/lib/byebug/commands/thread/switch.rb +6 -4
  64. data/lib/byebug/commands/thread.rb +11 -9
  65. data/lib/byebug/commands/tracevar.rb +10 -11
  66. data/lib/byebug/commands/undisplay.rb +12 -11
  67. data/lib/byebug/commands/untracevar.rb +8 -6
  68. data/lib/byebug/commands/up.rb +10 -8
  69. data/lib/byebug/commands/var/all.rb +7 -5
  70. data/lib/byebug/commands/var/args.rb +6 -4
  71. data/lib/byebug/commands/var/const.rb +9 -9
  72. data/lib/byebug/commands/var/global.rb +5 -3
  73. data/lib/byebug/commands/var/instance.rb +6 -4
  74. data/lib/byebug/commands/var/local.rb +6 -4
  75. data/lib/byebug/commands/var.rb +12 -10
  76. data/lib/byebug/commands/where.rb +9 -7
  77. data/lib/byebug/commands.rb +40 -37
  78. data/lib/byebug/context.rb +7 -5
  79. data/lib/byebug/core.rb +26 -25
  80. data/lib/byebug/errors.rb +4 -2
  81. data/lib/byebug/frame.rb +19 -22
  82. data/lib/byebug/helpers/bin.rb +47 -0
  83. data/lib/byebug/helpers/eval.rb +15 -13
  84. data/lib/byebug/helpers/file.rb +6 -4
  85. data/lib/byebug/helpers/frame.rb +7 -5
  86. data/lib/byebug/helpers/parse.rb +5 -5
  87. data/lib/byebug/helpers/path.rb +9 -11
  88. data/lib/byebug/helpers/reflection.rb +2 -0
  89. data/lib/byebug/helpers/string.rb +11 -2
  90. data/lib/byebug/helpers/thread.rb +10 -8
  91. data/lib/byebug/helpers/toggle.rb +28 -27
  92. data/lib/byebug/helpers/var.rb +9 -7
  93. data/lib/byebug/history.rb +20 -11
  94. data/lib/byebug/interface.rb +13 -11
  95. data/lib/byebug/interfaces/local_interface.rb +25 -7
  96. data/lib/byebug/interfaces/remote_interface.rb +21 -9
  97. data/lib/byebug/interfaces/script_interface.rb +4 -1
  98. data/lib/byebug/interfaces/test_interface.rb +5 -3
  99. data/lib/byebug/option_setter.rb +14 -12
  100. data/lib/byebug/printers/base.rb +10 -10
  101. data/lib/byebug/printers/plain.rb +9 -8
  102. data/lib/byebug/printers/texts/base.yml +7 -3
  103. data/lib/byebug/printers/texts/plain.yml +1 -1
  104. data/lib/byebug/processors/command_processor.rb +11 -12
  105. data/lib/byebug/processors/control_processor.rb +4 -6
  106. data/lib/byebug/processors/post_mortem_processor.rb +4 -2
  107. data/lib/byebug/processors/script_processor.rb +7 -3
  108. data/lib/byebug/remote/client.rb +57 -0
  109. data/lib/byebug/remote/server.rb +47 -0
  110. data/lib/byebug/remote.rb +46 -66
  111. data/lib/byebug/runner.rb +43 -49
  112. data/lib/byebug/setting.rb +11 -5
  113. data/lib/byebug/settings/autoirb.rb +7 -5
  114. data/lib/byebug/settings/autolist.rb +7 -5
  115. data/lib/byebug/settings/autopry.rb +7 -5
  116. data/lib/byebug/settings/autosave.rb +4 -2
  117. data/lib/byebug/settings/basename.rb +4 -2
  118. data/lib/byebug/settings/callstyle.rb +4 -3
  119. data/lib/byebug/settings/fullpath.rb +4 -2
  120. data/lib/byebug/settings/histfile.rb +5 -3
  121. data/lib/byebug/settings/histsize.rb +4 -2
  122. data/lib/byebug/settings/linetrace.rb +6 -4
  123. data/lib/byebug/settings/listsize.rb +4 -2
  124. data/lib/byebug/settings/post_mortem.rb +6 -4
  125. data/lib/byebug/settings/savefile.rb +4 -2
  126. data/lib/byebug/settings/stack_on_error.rb +4 -2
  127. data/lib/byebug/settings/width.rb +3 -1
  128. data/lib/byebug/source_file_formatter.rb +71 -0
  129. data/lib/byebug/subcommands.rb +6 -4
  130. data/lib/byebug/version.rb +2 -1
  131. data/lib/byebug.rb +3 -1
  132. metadata +22 -20
  133. data/bin/byebug +0 -7
data/ext/byebug/threads.c CHANGED
@@ -14,12 +14,12 @@ t_tbl_mark_keyvalue(st_data_t key, st_data_t value, st_data_t tbl)
14
14
  {
15
15
  UNUSED(tbl);
16
16
 
17
- rb_gc_mark((VALUE) key);
17
+ rb_gc_mark((VALUE)key);
18
18
 
19
19
  if (!value)
20
20
  return ST_CONTINUE;
21
21
 
22
- rb_gc_mark((VALUE) value);
22
+ rb_gc_mark((VALUE)value);
23
23
 
24
24
  return ST_CONTINUE;
25
25
  }
@@ -27,16 +27,16 @@ t_tbl_mark_keyvalue(st_data_t key, st_data_t value, st_data_t tbl)
27
27
  static void
28
28
  t_tbl_mark(void *data)
29
29
  {
30
- threads_table_t *t_tbl = (threads_table_t *) data;
30
+ threads_table_t *t_tbl = (threads_table_t *)data;
31
31
  st_table *tbl = t_tbl->tbl;
32
32
 
33
- st_foreach(tbl, t_tbl_mark_keyvalue, (st_data_t) tbl);
33
+ st_foreach(tbl, t_tbl_mark_keyvalue, (st_data_t)tbl);
34
34
  }
35
35
 
36
36
  static void
37
37
  t_tbl_free(void *data)
38
38
  {
39
- threads_table_t *t_tbl = (threads_table_t *) data;
39
+ threads_table_t *t_tbl = (threads_table_t *)data;
40
40
 
41
41
  st_free_table(t_tbl->tbl);
42
42
  xfree(t_tbl);
@@ -70,7 +70,7 @@ check_thread_i(st_data_t key, st_data_t value, st_data_t data)
70
70
  if (!value)
71
71
  return ST_DELETE;
72
72
 
73
- if (!is_living_thread((VALUE) key))
73
+ if (!is_living_thread((VALUE)key))
74
74
  return ST_DELETE;
75
75
 
76
76
  return ST_CONTINUE;
@@ -110,7 +110,7 @@ cleanup_dead_threads(void)
110
110
  * Looks up a context in the threads table. If not present, it creates it.
111
111
  */
112
112
  void
113
- thread_context_lookup(VALUE thread, VALUE * context)
113
+ thread_context_lookup(VALUE thread, VALUE *context)
114
114
  {
115
115
  threads_table_t *t_tbl;
116
116
 
@@ -118,7 +118,7 @@ thread_context_lookup(VALUE thread, VALUE * context)
118
118
 
119
119
  if (!st_lookup(t_tbl->tbl, thread, context) || !*context)
120
120
  {
121
- *context = context_create(thread);
121
+ *context = byebug_context_create(thread);
122
122
  st_insert(t_tbl->tbl, thread, *context);
123
123
  }
124
124
  }
@@ -129,12 +129,12 @@ thread_context_lookup(VALUE thread, VALUE * context)
129
129
  * Thanks to this, all threads are "frozen" while the user is typing commands.
130
130
  */
131
131
  void
132
- acquire_lock(debug_context_t * dc)
132
+ acquire_lock(debug_context_t *dc)
133
133
  {
134
134
  while ((!NIL_P(locker) && locker != rb_thread_current())
135
135
  || CTX_FL_TEST(dc, CTX_FL_SUSPEND))
136
136
  {
137
- add_to_locked(rb_thread_current());
137
+ byebug_add_to_locked(rb_thread_current());
138
138
  rb_thread_stop();
139
139
 
140
140
  if (CTX_FL_TEST(dc, CTX_FL_SUSPEND))
@@ -159,10 +159,10 @@ release_lock(void)
159
159
  locker = Qnil;
160
160
 
161
161
  if (NIL_P(next_thread))
162
- thread = pop_from_locked();
162
+ thread = byebug_pop_from_locked();
163
163
  else
164
164
  {
165
- remove_from_locked(next_thread);
165
+ byebug_remove_from_locked(next_thread);
166
166
  thread = next_thread;
167
167
  next_thread = Qnil;
168
168
  }
@@ -1,14 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Main Container for all of Byebug's code
3
5
  #
4
6
  module Byebug
5
7
  #
6
- # Enters byebug right before (or right after if _before_ is false) return
7
- # events occur. Before entering byebug the init script is read.
8
+ # Starts byebug, and stops at the first line of user's code.
8
9
  #
9
10
  def self.attach
10
- require 'byebug/core'
11
-
12
11
  unless started?
13
12
  self.mode = :attached
14
13
 
@@ -18,6 +17,13 @@ module Byebug
18
17
 
19
18
  current_context.step_out(3, true)
20
19
  end
20
+
21
+ def self.spawn(host = "localhost", port = nil)
22
+ require_relative "core"
23
+
24
+ self.wait_connection = true
25
+ start_server(host, port || PORT)
26
+ end
21
27
  end
22
28
 
23
29
  #
@@ -27,6 +33,14 @@ end
27
33
  #
28
34
  module Kernel
29
35
  def byebug
36
+ require_relative "core"
37
+
38
+ Byebug.attach unless Byebug.mode == :off
39
+ end
40
+
41
+ def remote_byebug(host = "localhost", port = nil)
42
+ Byebug.spawn(host, port)
43
+
30
44
  Byebug.attach
31
45
  end
32
46
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Implements breakpoints
@@ -49,12 +51,30 @@ module Byebug
49
51
  #
50
52
  def self.potential_lines(filename)
51
53
  name = "#{Time.new.to_i}_#{rand(2**31)}"
52
- lines = {}
53
54
  iseq = RubyVM::InstructionSequence.compile(File.read(filename), name)
54
55
 
56
+ if iseq.respond_to?(:each_child)
57
+ potential_lines_with_trace_points(iseq, {})
58
+ else
59
+ potential_lines_without_trace_points(iseq, {})
60
+ end
61
+ end
62
+
63
+ def self.potential_lines_with_trace_points(iseq, lines)
64
+ iseq.trace_points.each { |(line, _)| lines[line] = true }
65
+ iseq.each_child do |child|
66
+ potential_lines_with_trace_points(child, lines)
67
+ end
68
+
69
+ lines.keys.sort
70
+ end
71
+
72
+ private_class_method :potential_lines_with_trace_points
73
+
74
+ def self.potential_lines_without_trace_points(iseq, lines)
55
75
  iseq.disasm.each_line do |line|
56
76
  res = /^\d+ (?<insn>\w+)\s+.+\(\s*(?<lineno>\d+)\)$/.match(line)
57
- next unless res && res[:insn] == 'trace'
77
+ next unless res && res[:insn] == "trace"
58
78
 
59
79
  lines[res[:lineno].to_i] = true
60
80
  end
@@ -62,6 +82,8 @@ module Byebug
62
82
  lines.keys
63
83
  end
64
84
 
85
+ private_class_method :potential_lines_without_trace_points
86
+
65
87
  #
66
88
  # Returns true if a breakpoint could be set in line number +lineno+ in file
67
89
  # name +filename.
@@ -81,10 +103,8 @@ module Byebug
81
103
  # Prints all information associated to the breakpoint
82
104
  #
83
105
  def inspect
84
- meths = %w(id pos source expr hit_condition hit_count hit_value enabled?)
85
- values = meths.map do |field|
86
- "#{field}: #{send(field)}"
87
- end.join(', ')
106
+ meths = %w[id pos source expr hit_condition hit_count hit_value enabled?]
107
+ values = meths.map { |field| "#{field}: #{send(field)}" }.join(", ")
88
108
  "#<Byebug::Breakpoint #{values}>"
89
109
  end
90
110
  end
@@ -1,5 +1,7 @@
1
- require 'forwardable'
2
- require 'byebug/helpers/string'
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+ require_relative "helpers/string"
3
5
 
4
6
  module Byebug
5
7
  #
@@ -16,11 +18,11 @@ module Byebug
16
18
  # end
17
19
  #
18
20
  # def self.description
19
- # 'Custom long desc'
21
+ # "Custom long desc"
20
22
  # end
21
23
  #
22
24
  # def.short_description
23
- # 'Custom short desc'
25
+ # "Custom short desc"
24
26
  # end
25
27
  #
26
28
  # def execute
@@ -47,16 +49,16 @@ module Byebug
47
49
  end
48
50
 
49
51
  def arguments
50
- @match[0].split(' ').drop(1).join(' ')
52
+ @match[0].split(" ").drop(1).join(" ")
51
53
  end
52
54
 
53
- def_delegators :'self.class', :help, :match
55
+ def_delegators "self.class", :help, :match
54
56
 
55
- def_delegator :'processor.printer', :print, :pr
56
- def_delegator :'processor.printer', :print_collection, :prc
57
- def_delegator :'processor.printer', :print_variables, :prv
57
+ def_delegator "processor.printer", :print, :pr
58
+ def_delegator "processor.printer", :print_collection, :prc
59
+ def_delegator "processor.printer", :print_variables, :prv
58
60
 
59
- def_delegators :'processor.interface', :errmsg, :puts, :print, :confirm
61
+ def_delegators "processor.interface", :errmsg, :puts, :print, :confirm
60
62
 
61
63
  class << self
62
64
  include Helpers::StringHelper
@@ -77,14 +79,18 @@ module Byebug
77
79
  #
78
80
  def to_s
79
81
  name
80
- .split('::')
81
- .map { |n| n.gsub(/Command$/, '').downcase if n =~ /Command$/ }
82
+ .split("::")
83
+ .map { |n| n.gsub(/Command$/, "").downcase if /Command$/.match?(n) }
82
84
  .compact
83
- .join(' ')
85
+ .join(" ")
84
86
  end
85
87
 
86
88
  def columnize(width)
87
- format(" %-#{width}s -- %s\n", to_s, short_description)
89
+ format(
90
+ " %-<name>#{width}s -- %<description>s\n",
91
+ name: to_s,
92
+ description: short_description
93
+ )
88
94
  end
89
95
 
90
96
  #
@@ -1,4 +1,6 @@
1
- require 'byebug/errors'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "errors"
2
4
 
3
5
  module Byebug
4
6
  #
@@ -1,7 +1,10 @@
1
- require 'byebug/command'
2
- require 'byebug/helpers/eval'
3
- require 'byebug/helpers/file'
4
- require 'byebug/helpers/parse'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/eval"
5
+ require_relative "../helpers/file"
6
+ require_relative "../helpers/parse"
7
+ require_relative "../source_file_formatter"
5
8
 
6
9
  module Byebug
7
10
  #
@@ -19,32 +22,30 @@ module Byebug
19
22
  end
20
23
 
21
24
  def self.description
22
- <<-EOD
23
- b[reak] [file:]line [if expr]
24
- b[reak] [module::...]class(.|#)method [if expr]
25
+ <<-DESCRIPTION
26
+ b[reak] [<file>:]<line> [if <expr>]
27
+ b[reak] [<module>::...]<class>(.|#)<method> [if <expr>]
25
28
 
26
29
  They can be specified by line or method and an expression can be added
27
30
  for conditionally enabled breakpoints.
28
31
 
29
32
  #{short_description}
30
- EOD
33
+ DESCRIPTION
31
34
  end
32
35
 
33
36
  def self.short_description
34
- 'Sets breakpoints in the source code'
37
+ "Sets breakpoints in the source code"
35
38
  end
36
39
 
37
40
  def execute
38
41
  return puts(help) unless @match[1]
39
42
 
40
43
  b = line_breakpoint(@match[1]) || method_breakpoint(@match[1])
41
- return errmsg(pr('break.errors.location')) unless b
44
+ return errmsg(pr("break.errors.location")) unless b
42
45
 
43
- if syntax_valid?(@match[2])
44
- return puts(pr('break.created', id: b.id, file: b.source, line: b.pos))
45
- end
46
+ return puts(pr("break.created", id: b.id, file: b.source, line: b.pos)) if syntax_valid?(@match[2])
46
47
 
47
- errmsg(pr('break.errors.expression', expr: @match[2]))
48
+ errmsg(pr("break.errors.expression", expr: @match[2]))
48
49
  b.enabled = false
49
50
  end
50
51
 
@@ -73,26 +74,39 @@ module Byebug
73
74
  def target_object(str)
74
75
  k = error_eval(str)
75
76
 
76
- k && k.is_a?(Module) ? k.name : str
77
- rescue
78
- errmsg('Warning: breakpoint source is not yet defined')
77
+ k&.is_a?(Module) ? k.name : str
78
+ rescue StandardError
79
+ errmsg("Warning: breakpoint source is not yet defined")
79
80
  str
80
81
  end
81
82
 
82
83
  def add_line_breakpoint(file, line)
83
- raise(pr('break.errors.source', file: file)) unless File.exist?(file)
84
+ raise(pr("break.errors.source", file: file)) unless File.exist?(file)
84
85
 
85
86
  fullpath = File.realpath(file)
86
87
 
87
- if line > n_lines(file)
88
- raise(pr('break.errors.far_line', lines: n_lines(file), file: fullpath))
89
- end
88
+ raise(pr("break.errors.far_line", lines: n_lines(file), file: fullpath)) if line > n_lines(file)
90
89
 
91
90
  unless Breakpoint.potential_line?(fullpath, line)
92
- raise(pr('break.errors.line', file: fullpath, line: line))
91
+ msg = pr(
92
+ "break.errors.line",
93
+ file: fullpath,
94
+ line: line,
95
+ valid_breakpoints: valid_breakpoints_for(fullpath, line)
96
+ )
97
+
98
+ raise(msg)
93
99
  end
94
100
 
95
101
  Breakpoint.add(fullpath, line, @match[2])
96
102
  end
103
+
104
+ def valid_breakpoints_for(path, line)
105
+ potential_lines = Breakpoint.potential_lines(path)
106
+ annotator = ->(n) { potential_lines.include?(n) ? "[B]" : " " }
107
+ source_file_formatter = SourceFileFormatter.new(path, annotator)
108
+
109
+ source_file_formatter.lines_around(line).join.chomp
110
+ end
97
111
  end
98
112
  end
@@ -1,5 +1,7 @@
1
- require 'byebug/command'
2
- require 'byebug/helpers/eval'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/eval"
3
5
 
4
6
  module Byebug
5
7
  #
@@ -17,7 +19,7 @@ module Byebug
17
19
  end
18
20
 
19
21
  def self.description
20
- <<-EOD
22
+ <<-DESCRIPTION
21
23
  cat[ch][ (off|<exception>[ off])]
22
24
 
23
25
  #{short_description}
@@ -26,19 +28,19 @@ module Byebug
26
28
  catch off -- deletes all catchpoints
27
29
  catch <exception> -- enables handling <exception>
28
30
  catch <exception> off -- disables handling <exception>
29
- EOD
31
+ DESCRIPTION
30
32
  end
31
33
 
32
34
  def self.short_description
33
- 'Handles exception catchpoints'
35
+ "Handles exception catchpoints"
34
36
  end
35
37
 
36
38
  def execute
37
39
  return info unless @match[1]
38
40
 
39
- return 'off' == @match[1] ? clear : add(@match[1]) unless @match[2]
41
+ return @match[1] == "off" ? clear : add(@match[1]) unless @match[2]
40
42
 
41
- return errmsg pr('catch.errors.off', off: cmd) unless @match[2] == 'off'
43
+ return errmsg pr("catch.errors.off", off: cmd) unless @match[2] == "off"
42
44
 
43
45
  remove(@match[1])
44
46
  end
@@ -46,34 +48,30 @@ module Byebug
46
48
  private
47
49
 
48
50
  def remove(exception)
49
- unless Byebug.catchpoints.member?(exception)
50
- return errmsg pr('catch.errors.not_found', exception: exception)
51
- end
51
+ return errmsg pr("catch.errors.not_found", exception: exception) unless Byebug.catchpoints.member?(exception)
52
52
 
53
- puts pr('catch.removed', exception: exception)
53
+ puts pr("catch.removed", exception: exception)
54
54
  Byebug.catchpoints.delete(exception)
55
55
  end
56
56
 
57
57
  def add(exception)
58
- if warning_eval(exception.is_a?(Class).to_s)
59
- errmsg pr('catch.errors.not_class', class: exception)
60
- end
58
+ errmsg pr("catch.errors.not_class", class: exception) if warning_eval(exception.is_a?(Class).to_s)
61
59
 
62
- puts pr('catch.added', exception: exception)
60
+ puts pr("catch.added", exception: exception)
63
61
  Byebug.add_catchpoint(exception)
64
62
  end
65
63
 
66
64
  def clear
67
- Byebug.catchpoints.clear if confirm(pr('catch.confirmations.delete_all'))
65
+ Byebug.catchpoints.clear if confirm(pr("catch.confirmations.delete_all"))
68
66
  end
69
67
 
70
68
  def info
71
69
  if Byebug.catchpoints && !Byebug.catchpoints.empty?
72
- Byebug.catchpoints.each do |exception, _hits|
70
+ Byebug.catchpoints.each_key do |exception|
73
71
  puts("#{exception}: #{exception.is_a?(Class)}")
74
72
  end
75
73
  else
76
- puts 'No exceptions set to be caught.'
74
+ puts "No exceptions set to be caught."
77
75
  end
78
76
  end
79
77
  end
@@ -1,5 +1,7 @@
1
- require 'byebug/command'
2
- require 'byebug/helpers/parse'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/parse"
3
5
 
4
6
  module Byebug
5
7
  #
@@ -17,7 +19,7 @@ module Byebug
17
19
  end
18
20
 
19
21
  def self.description
20
- <<-EOD
22
+ <<-DESCRIPTION
21
23
  cond[ition] <n>[ expr]
22
24
 
23
25
  #{short_description}
@@ -26,28 +28,26 @@ module Byebug
26
28
  an integer and <expr> is an expression to be evaluated whenever
27
29
  breakpoint <n> is reached. If no expression is specified, the condition
28
30
  is removed.
29
- EOD
31
+ DESCRIPTION
30
32
  end
31
33
 
32
34
  def self.short_description
33
- 'Sets conditions on breakpoints'
35
+ "Sets conditions on breakpoints"
34
36
  end
35
37
 
36
38
  def execute
37
39
  return puts(help) unless @match[1]
38
40
 
39
41
  breakpoints = Byebug.breakpoints.sort_by(&:id)
40
- return errmsg(pr('condition.errors.no_breakpoints')) if breakpoints.empty?
42
+ return errmsg(pr("condition.errors.no_breakpoints")) if breakpoints.empty?
41
43
 
42
- pos, err = get_int(@match[1], 'Condition', 1)
44
+ pos, err = get_int(@match[1], "Condition", 1)
43
45
  return errmsg(err) if err
44
46
 
45
47
  breakpoint = breakpoints.find { |b| b.id == pos }
46
- return errmsg(pr('break.errors.no_breakpoint')) unless breakpoint
48
+ return errmsg(pr("break.errors.no_breakpoint")) unless breakpoint
47
49
 
48
- unless syntax_valid?(@match[2])
49
- return errmsg(pr('break.errors.not_changed', expr: @match[2]))
50
- end
50
+ return errmsg(pr("break.errors.not_changed", expr: @match[2])) unless syntax_valid?(@match[2])
51
51
 
52
52
  breakpoint.expr = @match[2]
53
53
  end
@@ -1,5 +1,7 @@
1
- require 'byebug/command'
2
- require 'byebug/helpers/parse'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/parse"
3
5
 
4
6
  module Byebug
5
7
  #
@@ -12,37 +14,55 @@ module Byebug
12
14
  include Helpers::ParseHelper
13
15
 
14
16
  def self.regexp
15
- /^\s* c(?:ont(?:inue)?)? (?:\s+(\S+))? \s*$/x
17
+ /^\s* c(?:ont(?:inue)?)? (?:(!|\s+unconditionally|\s+\S+))? \s*$/x
16
18
  end
17
19
 
18
20
  def self.description
19
- <<-EOD
21
+ <<-DESCRIPTION
20
22
  c[ont[inue]][ <line_number>]
21
23
 
22
24
  #{short_description}
23
- EOD
25
+
26
+ Normally the program stops at the next breakpoint. However, if the
27
+ parameter "unconditionally" is given or the command is suffixed with
28
+ "!", the program will run until the end regardless of any enabled
29
+ breakpoints.
30
+ DESCRIPTION
24
31
  end
25
32
 
26
33
  def self.short_description
27
- 'Runs until program ends, hits a breakpoint or reaches a line'
34
+ "Runs until program ends, hits a breakpoint or reaches a line"
28
35
  end
29
36
 
30
37
  def execute
31
- if @match[1]
32
- num, err = get_int(@match[1], 'Continue', 0, nil)
38
+ if until_line?
39
+ num, err = get_int(modifier, "Continue", 0, nil)
33
40
  return errmsg(err) unless num
34
41
 
35
42
  filename = File.expand_path(frame.file)
36
- unless Breakpoint.potential_line?(filename, num)
37
- return errmsg(pr('continue.errors.unstopped_line', line: num))
38
- end
43
+ return errmsg(pr("continue.errors.unstopped_line", line: num)) unless Breakpoint.potential_line?(filename, num)
39
44
 
40
45
  Breakpoint.add(filename, num)
41
46
  end
42
47
 
43
48
  processor.proceed!
44
49
 
45
- Byebug.stop if Byebug.stoppable?
50
+ Byebug.mode = :off if unconditionally?
51
+ Byebug.stop if unconditionally? || Byebug.stoppable?
52
+ end
53
+
54
+ private
55
+
56
+ def until_line?
57
+ @match[1] && !["!", "unconditionally"].include?(modifier)
58
+ end
59
+
60
+ def unconditionally?
61
+ @match[1] && ["!", "unconditionally"].include?(modifier)
62
+ end
63
+
64
+ def modifier
65
+ @match[1].lstrip
46
66
  end
47
67
  end
48
68
  end
@@ -1,5 +1,7 @@
1
- require 'byebug/command'
2
- require 'byebug/helpers/eval'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/eval"
3
5
 
4
6
  module Byebug
5
7
  #
@@ -13,18 +15,18 @@ module Byebug
13
15
  end
14
16
 
15
17
  def self.description
16
- <<-EOD
18
+ <<-DESCRIPTION
17
19
  debug <expression>
18
20
 
19
21
  #{short_description}
20
22
 
21
23
  Allows, for example, setting breakpoints on expressions evaluated from
22
24
  the debugger's prompt.
23
- EOD
25
+ DESCRIPTION
24
26
  end
25
27
 
26
28
  def self.short_description
27
- 'Spawns a subdebugger'
29
+ "Spawns a subdebugger"
28
30
  end
29
31
 
30
32
  def execute
@@ -1,5 +1,7 @@
1
- require 'byebug/command'
2
- require 'byebug/helpers/parse'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/parse"
3
5
 
4
6
  module Byebug
5
7
  #
@@ -16,36 +18,36 @@ module Byebug
16
18
  end
17
19
 
18
20
  def self.description
19
- <<-EOD
21
+ <<-DESCRIPTION
20
22
  del[ete][ nnn...]
21
23
 
22
24
  #{short_description}
23
25
 
24
26
  Without and argument, deletes all breakpoints. With integer arguments,
25
27
  it deletes specific breakpoints.
26
- EOD
28
+ DESCRIPTION
27
29
  end
28
30
 
29
31
  def self.short_description
30
- 'Deletes breakpoints'
32
+ "Deletes breakpoints"
31
33
  end
32
34
 
33
35
  def execute
34
36
  unless @match[1]
35
- if confirm(pr('break.confirmations.delete_all'))
36
- Byebug.breakpoints.clear
37
- end
37
+ Byebug.breakpoints.clear if confirm(pr("break.confirmations.delete_all"))
38
38
 
39
39
  return
40
40
  end
41
41
 
42
42
  @match[1].split(/ +/).each do |number|
43
- pos, err = get_int(number, 'Delete', 1)
43
+ pos, err = get_int(number, "Delete", 1)
44
44
 
45
45
  return errmsg(err) unless pos
46
46
 
47
- unless Breakpoint.remove(pos)
48
- return errmsg(pr('break.errors.no_breakpoint_delete', pos: pos))
47
+ if Breakpoint.remove(pos)
48
+ puts(pr("break.messages.breakpoint_deleted", pos: pos))
49
+ else
50
+ errmsg(pr("break.errors.no_breakpoint_delete", pos: pos))
49
51
  end
50
52
  end
51
53
  end