debugger 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/CHANGELOG.md +4 -0
  2. data/README.md +9 -3
  3. data/debugger.gemspec +1 -1
  4. data/ext/ruby_debug/192/ruby_debug.c +21 -9
  5. data/ext/ruby_debug/193/ruby_debug.c +15 -5
  6. data/lib/debugger/test.rb +6 -0
  7. data/{test/support → lib/debugger/test}/breakpoint.rb +0 -0
  8. data/{test/support → lib/debugger/test}/context.rb +0 -0
  9. data/{test/support → lib/debugger/test}/matchers.rb +0 -0
  10. data/{test/support → lib/debugger/test}/mocha_extensions.rb +1 -1
  11. data/lib/debugger/test/printer_helpers.rb +8 -0
  12. data/{test/support → lib/debugger/test}/processor.rb +0 -0
  13. data/{test/support → lib/debugger/test}/test_dsl.rb +22 -2
  14. data/{test/support → lib/debugger/test}/test_interface.rb +4 -0
  15. data/lib/debugger/version.rb +1 -1
  16. data/lib/ruby-debug.rb +4 -1
  17. data/lib/ruby-debug/command.rb +18 -6
  18. data/lib/ruby-debug/commands/breakpoints.rb +27 -29
  19. data/lib/ruby-debug/commands/condition.rb +7 -2
  20. data/lib/ruby-debug/commands/continue.rb +1 -2
  21. data/lib/ruby-debug/commands/control.rb +8 -9
  22. data/lib/ruby-debug/commands/display.rb +7 -15
  23. data/lib/ruby-debug/commands/edit.rb +6 -6
  24. data/lib/ruby-debug/commands/enable.rb +6 -7
  25. data/lib/ruby-debug/commands/eval.rb +1 -3
  26. data/lib/ruby-debug/commands/frame.rb +72 -101
  27. data/lib/ruby-debug/commands/info.rb +8 -14
  28. data/lib/ruby-debug/commands/irb.rb +1 -1
  29. data/lib/ruby-debug/commands/jump.rb +6 -6
  30. data/lib/ruby-debug/commands/kill.rb +0 -1
  31. data/lib/ruby-debug/commands/list.rb +4 -4
  32. data/lib/ruby-debug/commands/method.rb +8 -11
  33. data/lib/ruby-debug/commands/quit.rb +1 -1
  34. data/lib/ruby-debug/commands/reload.rb +1 -1
  35. data/lib/ruby-debug/commands/save.rb +1 -1
  36. data/lib/ruby-debug/commands/set.rb +10 -15
  37. data/lib/ruby-debug/commands/show.rb +28 -42
  38. data/lib/ruby-debug/commands/skip.rb +1 -1
  39. data/lib/ruby-debug/commands/source.rb +1 -1
  40. data/lib/ruby-debug/commands/start.rb +26 -0
  41. data/lib/ruby-debug/commands/threads.rb +29 -18
  42. data/lib/ruby-debug/commands/tmate.rb +1 -1
  43. data/lib/ruby-debug/commands/trace.rb +6 -7
  44. data/lib/ruby-debug/commands/variables.rb +36 -19
  45. data/lib/ruby-debug/helper.rb +5 -5
  46. data/lib/ruby-debug/interface.rb +15 -3
  47. data/lib/ruby-debug/printers/base.rb +58 -0
  48. data/lib/ruby-debug/printers/plain.rb +41 -0
  49. data/lib/ruby-debug/printers/texts/base.yml +146 -0
  50. data/lib/ruby-debug/printers/texts/plain.yml +60 -0
  51. data/lib/ruby-debug/processor.rb +56 -47
  52. data/test/breakpoints_test.rb +43 -54
  53. data/test/conditions_test.rb +18 -6
  54. data/test/continue_test.rb +1 -1
  55. data/test/display_test.rb +11 -11
  56. data/test/edit_test.rb +1 -2
  57. data/test/eval_test.rb +5 -6
  58. data/test/finish_test.rb +1 -1
  59. data/test/frame_test.rb +29 -27
  60. data/test/help_test.rb +0 -1
  61. data/test/info_test.rb +10 -14
  62. data/test/irb_test.rb +0 -1
  63. data/test/jump_test.rb +21 -2
  64. data/test/method_test.rb +3 -3
  65. data/test/new/printers/plain_test.rb +84 -0
  66. data/test/reload_test.rb +2 -2
  67. data/test/restart_test.rb +1 -2
  68. data/test/set_test.rb +8 -7
  69. data/test/show_test.rb +22 -22
  70. data/test/source_test.rb +1 -1
  71. data/test/test_helper.rb +2 -1
  72. data/test/thread_test.rb +11 -13
  73. data/test/trace_test.rb +7 -7
  74. data/test/variables_test.rb +33 -15
  75. metadata +20 -12
@@ -254,7 +254,7 @@ item. If \'verbose\' is given then the entire stack frame is shown.'],
254
254
  return
255
255
  end
256
256
  obj = debug_eval('self')
257
- var_list(obj.instance_variables)
257
+ var_list(obj.instance_variables.map(&:to_s))
258
258
  end
259
259
 
260
260
  def info_line(*args)
@@ -319,14 +319,10 @@ item. If \'verbose\' is given then the entire stack frame is shown.'],
319
319
  errmsg "info stack not available here.\n"
320
320
  return
321
321
  end
322
- (0...@state.context.stack_size).each do |idx|
323
- if idx == @state.frame_pos
324
- print "--> "
325
- else
326
- print " "
327
- end
328
- print_frame(idx)
329
- end
322
+ print(prc("frame.line", (0...@state.context.stack_size)) do |item, _|
323
+ mark = item == @state.frame_pos ? "--> " : " "
324
+ get_pr_arguments(mark, item, @state.context)
325
+ end)
330
326
  end
331
327
 
332
328
  def info_thread_preamble(arg)
@@ -355,8 +351,7 @@ item. If \'verbose\' is given then the entire stack frame is shown.'],
355
351
  display_context(c, !verbose)
356
352
  if verbose and not c.ignored?
357
353
  (0...c.stack_size).each do |idx|
358
- print "\t"
359
- print_frame(idx, false, c)
354
+ print_frame("\t", idx, false, c)
360
355
  end
361
356
  end
362
357
  end
@@ -374,8 +369,7 @@ item. If \'verbose\' is given then the entire stack frame is shown.'],
374
369
  display_context(c, !verbose)
375
370
  if verbose and not c.ignored?
376
371
  (0...c.stack_size).each do |idx|
377
- print "\t"
378
- print_frame(idx, false, c)
372
+ print_frame("\t", idx, false, c)
379
373
  end
380
374
  end
381
375
  end
@@ -385,7 +379,7 @@ item. If \'verbose\' is given then the entire stack frame is shown.'],
385
379
  errmsg "info global_variables not available here.\n"
386
380
  return
387
381
  end
388
- var_list(global_variables)
382
+ var_global
389
383
  end
390
384
 
391
385
  def info_variables(*args)
@@ -90,7 +90,7 @@ module Debugger
90
90
  else
91
91
  file = @state.context.frame_file(0)
92
92
  line = @state.context.frame_line(0)
93
- CommandProcessor.print_location_and_text(file, line)
93
+ CommandProcessor.print_location_and_text(file, line, @state.context)
94
94
  @state.previous_line = nil
95
95
  end
96
96
 
@@ -19,17 +19,17 @@ module Debugger
19
19
 
20
20
  def execute
21
21
  if !@match[1]
22
- errmsg "\"jump\" must be followed by a line number\n"
22
+ errmsg pr("jump.errors.no_line_number")
23
23
  return
24
24
  end
25
25
  if !numeric?(@match[1])
26
- errmsg "Bad line number: " + @match[1]
26
+ errmsg pr("jump.errors.bad_line_number", line: @match[1])
27
27
  return
28
28
  end
29
29
  line = @match[1].to_i
30
30
  line = @state.context.frame_line(0) + line if @match[1][0] == '+' or @match[1][0] == '-'
31
31
  if line == @state.context.frame_line(0)
32
- CommandProcessor.print_location_and_text(@state.context.frame_file(0), line)
32
+ CommandProcessor.print_location_and_text(@state.context.frame_file(0), line, @state.context)
33
33
  return
34
34
  end
35
35
  file = @match[2]
@@ -39,11 +39,11 @@ module Debugger
39
39
  when 0
40
40
  @state.proceed
41
41
  when 1
42
- errmsg "Not possible to jump from here\n"
42
+ errmsg pr("jump.errors.not_possible")
43
43
  when 2
44
- errmsg "Couldn't find debugged frame\n"
44
+ errmsg pr("jump.errors.no_frame")
45
45
  when 3
46
- errmsg "Couldn't find active code at " + file + ":" + line.to_s + "\n"
46
+ errmsg pr("jump.errors.no_active_code", file: file, line: line)
47
47
  end
48
48
  end
49
49
 
@@ -13,7 +13,6 @@ module Debugger
13
13
  end
14
14
 
15
15
  def execute
16
- puts @match[1]
17
16
  if @match[1]
18
17
  signame = @match[1]
19
18
  unless Signal.list.member?(signame)
@@ -69,7 +69,7 @@ module Debugger
69
69
  # If we can show from B to E then we return B, otherwise we return the
70
70
  # previous line @state.previous_line.
71
71
  def display_list(b, e, file, current)
72
- print "[%d, %d] in %s\n", b, e, file
72
+ print("[%d, %d] in %s\n" % [b, e, file])
73
73
  lines = LineCache::getlines(file,
74
74
  Command.settings[:reload_source_on_change])
75
75
  if lines
@@ -78,14 +78,14 @@ module Debugger
78
78
  [b, 1].max.upto(e) do |n|
79
79
  if n > 0 && lines[n-1]
80
80
  if n == current
81
- print "=> %d %s\n", n, lines[n-1].chomp
81
+ print("=> %d %s\n" % [n, lines[n-1].chomp])
82
82
  else
83
- print " %d %s\n", n, lines[n-1].chomp
83
+ print(" %d %s\n" % [n, lines[n-1].chomp])
84
84
  end
85
85
  end
86
86
  end
87
87
  else
88
- errmsg "No sourcefile available for %s\n", file
88
+ errmsg("No sourcefile available for %s\n" % [file])
89
89
  return @state.previous_line
90
90
  end
91
91
  return e == lines.size ? @state.previous_line : b
@@ -46,24 +46,21 @@ module Debugger
46
46
  end
47
47
 
48
48
  def execute
49
- if @match[1] == "iv"
49
+ result = if @match[1] == "iv"
50
50
  obj = debug_eval(@match.post_match)
51
- obj.instance_variables.sort.each do |v|
52
- print "%s = %s\n", v, obj.instance_variable_get(v).inspect
53
- end
51
+ variables = obj.instance_variables.sort.map { |var_name| [var_name, obj.instance_variable_get(var_name)] }
52
+ prv(variables, 'instance')
54
53
  elsif @match[1]
55
- obj = debug_eval(@match.post_match)
56
- print "%s\n", columnize(obj.methods.sort(),
57
- self.class.settings[:width])
54
+ prc("method.methods", debug_eval(@match.post_match).methods.sort) { |item, _| {name: item} }
58
55
  else
59
56
  obj = debug_eval(@match.post_match)
60
- unless obj.kind_of? Module
61
- print "Should be Class/Module: %s\n", @match.post_match
57
+ if obj.kind_of?(Module)
58
+ prc("method.methods", obj.instance_methods(false).sort) { |item, _| {name: item} }
62
59
  else
63
- print "%s\n", columnize(obj.instance_methods(false).sort(),
64
- self.class.settings[:width])
60
+ errmsg(pr("variable.errors.not_class_module", object: @match.post_match)) && return
65
61
  end
66
62
  end
63
+ print result
67
64
  end
68
65
 
69
66
  class << self
@@ -13,7 +13,7 @@ module Debugger
13
13
  end
14
14
 
15
15
  def execute
16
- if @match[1] or confirm("Really quit? (y/n) ")
16
+ if @match[1] or confirm(pr("quit.confirmations.really"))
17
17
  @state.interface.finalize
18
18
  exit! # exit -> exit!: No graceful way to stop threads...
19
19
  end
@@ -16,7 +16,7 @@ module Debugger
16
16
 
17
17
  def execute
18
18
  Debugger.source_reload
19
- print "Source code is reloaded. Automatic reloading is #{source_reloading}.\n"
19
+ print pr("reload.messages.done", source_reloading: source_reloading)
20
20
  end
21
21
 
22
22
  private
@@ -64,7 +64,7 @@ module Debugger
64
64
  save_catchpoints(file)
65
65
  # save_displays(file)
66
66
  save_settings(file)
67
- print "Saved to '#{file.path}'\n"
67
+ print pr("save.messages.done", path: file.path)
68
68
  if @state and @state.interface
69
69
  @state.interface.restart_file = file.path
70
70
  end
@@ -58,11 +58,8 @@ set history size -- Set the size of the command history"],
58
58
 
59
59
  def execute
60
60
  if not @match[1]
61
- print "\"set\" must be followed by the name of an set command:\n"
62
- print "List of set subcommands:\n\n"
63
- for subcmd in Subcommands do
64
- print "set #{subcmd.name} -- #{subcmd.short_help}\n"
65
- end
61
+ subcommands = subcmd.map { |s| "set #{s.name} -- #{s.short_help}" }.join("\n")
62
+ print pr("set.errors.no_subcommand", subcommands: subcommands)
66
63
  else
67
64
  args = @match[1].split(/[ \t]+/)
68
65
  subcmd = args.shift
@@ -115,8 +112,7 @@ set history size -- Set the size of the command history"],
115
112
  return
116
113
  end
117
114
  end
118
- print "Invalid call style #{arg}. Should be one of: " +
119
- "'short' or 'last'.\n"
115
+ print pr("set.errors.invalid_call_style", style: arg)
120
116
  when /^trace$/
121
117
  Command.settings[:stack_trace_on_error] = set_on
122
118
  when /^fullpath$/
@@ -139,15 +135,14 @@ set history size -- Set the size of the command history"],
139
135
  when /^save$/
140
136
  interface.history_save = get_onoff(args[1])
141
137
  when /^size$/
142
- interface.history_length = get_int(args[1],
143
- "Set history size")
138
+ interface.history_length = get_int(args[1], "Set history size")
144
139
  when /^filename$/
145
- interface.histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", args[1])
140
+ interface.histfile = File.join(ENV["HOME"] || ENV["HOMEPATH"] || ".", args[1])
146
141
  else
147
- print "Invalid history parameter #{args[0]}. Should be 'filename', 'save' or 'size'.\n"
142
+ print pr("set.errors.wrong_history_arg", arg: args[0])
148
143
  end
149
144
  else
150
- print "Need two parameters for 'set history'; got #{args.size}.\n"
145
+ print pr("set.errors.wrong_history_args_number", size: args.size)
151
146
  return
152
147
  end
153
148
  when /^linetrace\+$/
@@ -170,17 +165,17 @@ set history size -- Set the size of the command history"],
170
165
  return
171
166
  end
172
167
  else
173
- print "Unknown setting #{@match[1]}.\n"
168
+ print pr("set.errors.unknown_setting", setting: @match[1])
174
169
  return
175
170
  end
176
- print "%s\n" % show_setting(try_subcmd.name)
171
+ print show_setting(try_subcmd.name)
177
172
  return
178
173
  rescue RuntimeError
179
174
  return
180
175
  end
181
176
  end
182
177
  end
183
- print "Unknown set command #{subcmd}\n"
178
+ print pr("set.errors.unknown_subcommand", subcmd: subcmd)
184
179
  end
185
180
  end
186
181
 
@@ -5,7 +5,7 @@ module Debugger
5
5
  case setting_name
6
6
  when /^annotate$/
7
7
  Debugger.annotate ||= 0
8
- return ("Annotation level is #{Debugger.annotate}")
8
+ return pr("show.messages.annotation", level: Debugger.annotate)
9
9
  when /^args$/
10
10
  if Command.settings[:argv] and Command.settings[:argv].size > 0
11
11
  if defined?(Debugger::RDEBUG_SCRIPT)
@@ -18,25 +18,25 @@ module Debugger
18
18
  else
19
19
  args = ''
20
20
  end
21
- return "Argument list to give program being debugged when it is started is \"#{args}\"."
21
+ return pr("show.messages.args", args: args)
22
22
  when /^autolist$/
23
23
  on_off = Command.settings[:autolist] > 0
24
- return "autolist is #{show_onoff(on_off)}."
24
+ return pr("show.messages.general", setting: "autolist", status: show_onoff(on_off))
25
25
  when /^autoeval$/
26
26
  on_off = Command.settings[:autoeval]
27
- return "autoeval is #{show_onoff(on_off)}."
27
+ return pr("show.messages.general", setting: "autoeval", status: show_onoff(on_off))
28
28
  when /^autoreload$/
29
29
  on_off = Command.settings[:reload_source_on_change]
30
- return "autoreload is #{show_onoff(on_off)}."
30
+ return pr("show.messages.general", setting: "autoreload", status: show_onoff(on_off))
31
31
  when /^autoirb$/
32
32
  on_off = Command.settings[:autoirb] > 0
33
- return "autoirb is #{show_onoff(on_off)}."
33
+ return pr("show.messages.general", setting: "autoirb", status: show_onoff(on_off))
34
34
  when /^basename$/
35
35
  on_off = Command.settings[:basename]
36
- return "basename is #{show_onoff(on_off)}."
36
+ return pr("show.messages.general", setting: "basename", status: show_onoff(on_off))
37
37
  when /^callstyle$/
38
38
  style = Command.settings[:callstyle]
39
- return "Frame call-display style is #{style}."
39
+ return pr("show.messages.call_style", style: style)
40
40
  when /^commands(:?\s+(\d+))?$/
41
41
  if @state.interface.readline_support?
42
42
  s = '';
@@ -68,18 +68,18 @@ module Debugger
68
68
  i += 1
69
69
  end
70
70
  else
71
- s='No readline support'
71
+ s = pr("show.errors.no_readline")
72
72
  end
73
73
  return s
74
74
  when /^debuggertesting$/
75
75
  on_off = Command.settings[:debuggertesting]
76
- return "Currently testing the debugger is #{show_onoff(on_off)}."
76
+ return pr("show.messages.debuggertesting", status: show_onoff(on_off))
77
77
  when /^forcestep$/
78
78
  on_off = self.class.settings[:force_stepping]
79
- return "force-stepping is #{show_onoff(on_off)}."
79
+ return pr("show.messages.general", setting: "force-stepping", status: show_onoff(on_off))
80
80
  when /^fullpath$/
81
81
  on_off = Command.settings[:full_path]
82
- return "Displaying frame's full file names is #{show_onoff(on_off)}."
82
+ return pr("show.messages.fullpath", status: show_onoff(on_off))
83
83
  when /^history(:?\s+(filename|save|size))?$/
84
84
  args = @match[1].split
85
85
  interface = @state.interface
@@ -99,46 +99,35 @@ module Debugger
99
99
  end
100
100
  s = []
101
101
  if show_filename
102
- msg = (prefix ? "filename: " : "") +
103
- "The filename in which to record the command history is " +
104
- "#{interface.histfile.inspect}"
105
- s << msg
102
+ s << pr("show.messages.history.filename", prefix: ("filename: " if prefix), filename: interface.histfile)
106
103
  end
107
104
  if show_save
108
- msg = (prefix ? "save: " : "") +
109
- "Saving of history save is #{show_onoff(interface.history_save)}."
110
- s << msg
105
+ s << pr("show.messages.history.save", prefix: ("save: " if prefix), status: show_onoff(interface.history_save))
111
106
  end
112
107
  if show_size
113
- msg = (prefix ? "size: " : "") +
114
- "Debugger history size is #{interface.history_length}"
115
- s << msg
108
+ s << pr("show.messages.history.size", prefix: ("size: " if prefix), size: interface.history_length)
116
109
  end
117
- return s.join("\n")
110
+ return s.join("")
118
111
  when /^linetrace$/
119
112
  on_off = Debugger.tracing
120
- return "line tracing is #{show_onoff(on_off)}."
113
+ return pr("show.messages.general", setting: "line tracing", status: show_onoff(on_off))
121
114
  when /^linetrace\+$/
122
115
  on_off = Command.settings[:tracing_plus]
123
- if on_off
124
- return "line tracing style is different consecutive lines."
125
- else
126
- return "line tracing style is every line."
127
- end
116
+ return pr("show.messages.tracing_plus.#{on_off ? "on" : "off"}")
128
117
  when /^listsize$/
129
118
  listlines = Command.settings[:listsize]
130
- return "Number of source lines to list by default is #{listlines}."
119
+ return pr("show.messages.listsize", size: listlines)
131
120
  when /^port$/
132
- return "server port is #{Debugger::PORT}."
121
+ return pr("show.messages.port", port: Debugger::PORT)
133
122
  when /^trace$/
134
123
  on_off = Command.settings[:stack_trace_on_error]
135
- return "Displaying stack trace is #{show_onoff(on_off)}."
124
+ return pr("show.messages.general", setting: "Displaying stack trace", status: show_onoff(on_off))
136
125
  when /^version$/
137
- return "ruby-debug #{Debugger::VERSION}"
126
+ return pr("show.messages.version", version: Debugger::VERSION)
138
127
  when /^width$/
139
- return "width is #{self.class.settings[:width]}."
128
+ return pr("show.messages.general", setting: "width", status: self.class.settings[:width])
140
129
  else
141
- return "Unknown show subcommand #{setting_name}."
130
+ return pr("show.errors.unknown_subcommand", name: setting_name)
142
131
  end
143
132
  end
144
133
  end
@@ -193,19 +182,16 @@ show history size -- Show the size of the command history"],
193
182
 
194
183
  def execute
195
184
  if not @match[1]
196
- print "\"show\" must be followed by the name of an show command:\n"
197
- print "List of show subcommands:\n\n"
198
- for subcmd in Subcommands do
199
- print "show #{subcmd.name} -- #{subcmd.short_help}\n"
200
- end
185
+ subcommands = subcmd.map { |s| "show #{s.name} -- #{s.short_help}" }.join("\n")
186
+ print pr("show.errors.no_subcommand", subcommands: subcommands)
201
187
  else
202
188
  args = @match[1].split(/[ \t]+/)
203
189
  param = args.shift
204
190
  subcmd = find(Subcommands, param)
205
191
  if subcmd
206
- print "%s\n" % show_setting(subcmd.name)
192
+ print show_setting(subcmd.name)
207
193
  else
208
- print "Unknown show command #{param}\n"
194
+ print pr("show.errors.unknown", name: param)
209
195
  end
210
196
  end
211
197
  end
@@ -13,7 +13,7 @@ module Debugger
13
13
 
14
14
  def execute
15
15
  Debugger::skip_next_exception
16
- print "ok\n"
16
+ print pr("skip.messages.ok")
17
17
  end
18
18
 
19
19
  class << self
@@ -10,7 +10,7 @@ module Debugger
10
10
  def execute
11
11
  file = File.expand_path(@match[1]).strip
12
12
  unless File.exist?(file)
13
- errmsg "Command file '#{file}' is not found\n"
13
+ errmsg pr("source.errors.not_found", file: file)
14
14
  return
15
15
  end
16
16
  if @state and @state.interface
@@ -0,0 +1,26 @@
1
+ module Debugger
2
+ class StartCommand < Command # :nodoc:
3
+ self.allow_in_control = true
4
+
5
+ def regexp
6
+ /^\s*(start)\s*$/ix
7
+ end
8
+
9
+ def execute
10
+ #print_debug "Starting: running program script"
11
+ Debugger.proceed
12
+ end
13
+
14
+ class << self
15
+ def help_command
16
+ 'start'
17
+ end
18
+
19
+ def help(cmd)
20
+ %{
21
+ run prog script
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end