byebug 1.0.3 → 1.1.0

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +13 -11
  4. data/Rakefile +0 -6
  5. data/bin/byebug +83 -136
  6. data/ext/byebug/byebug.c +182 -96
  7. data/ext/byebug/byebug.h +5 -7
  8. data/ext/byebug/context.c +52 -40
  9. data/lib/byebug.rb +81 -81
  10. data/lib/byebug/command.rb +18 -35
  11. data/lib/byebug/commands/control.rb +1 -1
  12. data/lib/byebug/commands/display.rb +0 -2
  13. data/lib/byebug/commands/enable.rb +4 -16
  14. data/lib/byebug/commands/eval.rb +5 -3
  15. data/lib/byebug/commands/frame.rb +68 -69
  16. data/lib/byebug/commands/help.rb +2 -1
  17. data/lib/byebug/commands/info.rb +43 -42
  18. data/lib/byebug/commands/method.rb +4 -3
  19. data/lib/byebug/commands/set.rb +10 -19
  20. data/lib/byebug/commands/show.rb +6 -13
  21. data/lib/byebug/interface.rb +1 -1
  22. data/lib/byebug/processor.rb +14 -17
  23. data/lib/byebug/version.rb +1 -2
  24. data/old_doc/byebug.texi +576 -847
  25. data/test/breakpoints_test.rb +0 -1
  26. data/test/conditions_test.rb +35 -33
  27. data/test/display_test.rb +14 -13
  28. data/test/edit_test.rb +28 -25
  29. data/test/eval_test.rb +0 -2
  30. data/test/finish_test.rb +4 -3
  31. data/test/frame_test.rb +20 -21
  32. data/test/help_test.rb +26 -23
  33. data/test/info_test.rb +105 -108
  34. data/test/irb_test.rb +26 -25
  35. data/test/kill_test.rb +19 -19
  36. data/test/list_test.rb +140 -156
  37. data/test/method_test.rb +21 -22
  38. data/test/post_mortem_test.rb +2 -5
  39. data/test/quit_test.rb +16 -17
  40. data/test/reload_test.rb +2 -2
  41. data/test/restart_test.rb +0 -1
  42. data/test/save_test.rb +31 -32
  43. data/test/set_test.rb +50 -47
  44. data/test/show_test.rb +67 -66
  45. data/test/source_test.rb +31 -34
  46. data/test/stepping_test.rb +32 -34
  47. data/test/support/test_dsl.rb +1 -1
  48. data/test/trace_test.rb +1 -2
  49. data/test/variables_test.rb +36 -34
  50. metadata +2 -4
  51. data/lib/byebug/commands/tmate.rb +0 -36
  52. data/test/tmate_test.rb +0 -44
@@ -69,7 +69,7 @@ module Byebug
69
69
  end
70
70
  end
71
71
 
72
- class InterruptCommand < Command # :nodoc:
72
+ class InterruptCommand < Command
73
73
  self.allow_in_control = true
74
74
  self.allow_in_post_mortem = false
75
75
  self.event = false
@@ -1,7 +1,6 @@
1
1
  module Byebug
2
2
 
3
3
  module DisplayFunctions
4
-
5
4
  def display_expression(exp)
6
5
  print "%s = %s\n", exp, debug_silent_eval(exp).to_s
7
6
  end
@@ -79,7 +78,6 @@ module Byebug
79
78
  end
80
79
 
81
80
  class DeleteDisplayCommand < Command
82
-
83
81
  def regexp
84
82
  /^\s* undisp(?:lay)? \s* (?:(\S+))?$/x
85
83
  end
@@ -105,17 +105,11 @@ module Byebug
105
105
  end
106
106
 
107
107
  # general help
108
- s = %{
108
+ str = %{
109
109
  Enable some things.
110
110
  This is used to cancel the effect of the "disable" command.
111
- --
112
- List of enable subcommands:
113
- --
114
111
  }
115
- for subcmd in Subcommands do
116
- s += "enable #{subcmd.name} -- #{subcmd.short_help}\n"
117
- end
118
- return s
112
+ str += format_subcmds(Subcommands)
119
113
  end
120
114
  end
121
115
  end
@@ -179,19 +173,13 @@ module Byebug
179
173
  end
180
174
 
181
175
  # general help
182
- s = %{
176
+ str = %{
183
177
  Disable some things.
184
178
 
185
179
  A disabled item is not forgotten, but has no effect until reenabled.
186
180
  Use the "enable" command to have it take effect again.
187
- --
188
- List of disable subcommands:
189
- --
190
181
  }
191
- for subcmd in Subcommands do
192
- s += "disable #{subcmd.name} -- #{subcmd.short_help}\n"
193
- end
194
- return s
182
+ str += format_subcmds(Subcommads)
195
183
  end
196
184
  end
197
185
  end
@@ -34,7 +34,7 @@ module Byebug
34
34
  end
35
35
 
36
36
  # Set default value
37
- Command.settings[:autoeval] = 1
37
+ Command.settings[:autoeval] = true
38
38
 
39
39
  def match(input)
40
40
  @input = input
@@ -104,6 +104,7 @@ module Byebug
104
104
  end
105
105
 
106
106
  class PutLCommand < Command
107
+ include Columnize
107
108
  self.allow_in_control = true
108
109
 
109
110
  def regexp
@@ -116,7 +117,7 @@ module Byebug
116
117
  vals = debug_eval(@match.post_match, b)
117
118
  if vals.is_a?(Array)
118
119
  vals = vals.map{|item| item.to_s}
119
- print "#{columnize(vals, self.class.settings[:width])}\n"
120
+ print "#{columnize(vals, Command.settings[:width])}\n"
120
121
  else
121
122
  PP.pp(vals, out)
122
123
  print out.string
@@ -140,6 +141,7 @@ module Byebug
140
141
  end
141
142
 
142
143
  class PSCommand < Command
144
+ include Columnize
143
145
  self.allow_in_control = true
144
146
 
145
147
  include EvalFunctions
@@ -154,7 +156,7 @@ module Byebug
154
156
  vals = debug_eval(@match.post_match, b)
155
157
  if vals.is_a?(Array)
156
158
  vals = vals.map{|item| item.to_s}
157
- print "#{columnize(vals.sort!, self.class.settings[:width])}\n"
159
+ print "#{columnize(vals.sort!, Command.settings[:width])}\n"
158
160
  else
159
161
  PP.pp(vals, out)
160
162
  print out.string
@@ -22,6 +22,7 @@ module Byebug
22
22
  errmsg "Adjusting would put us beyond the newest (innermost) frame.\n"
23
23
  return
24
24
  end
25
+
25
26
  if @state.frame_pos != abs_frame_pos then
26
27
  @state.previous_line = nil
27
28
  @state.frame_pos = abs_frame_pos
@@ -30,66 +31,60 @@ module Byebug
30
31
  @state.file = context.frame_file(@state.frame_pos)
31
32
  @state.line = context.frame_line(@state.frame_pos)
32
33
 
33
- print_frame(@state.frame_pos, true)
34
+ print_frame(@state.frame_pos, false)
34
35
  end
35
36
 
36
37
  def get_frame_call(prefix, pos, context)
37
38
  id = context.frame_method(pos)
39
+ return "<main>" unless id
40
+
38
41
  klass = context.frame_class(pos)
39
- call_str = ""
40
- if id
41
- args = context.frame_args(pos)
42
- locals = context.frame_locals(pos)
43
- if Command.settings[:callstyle] != :short && klass
44
- if Command.settings[:callstyle] == :tracked
45
- arg_info = context.frame_args_info(pos)
46
- end
47
- call_str << "#{klass}."
48
- end
49
- call_str << id.id2name
50
- if args.any?
51
- call_str << "("
52
- args.each_with_index do |name, i|
53
- case Command.settings[:callstyle]
54
- when :short
55
- call_str += "%s, " % [name]
56
- when :last
57
- klass = locals[name].class
58
- if klass.inspect.size > 20+3
59
- klass = klass.inspect[0..20]+"..."
60
- end
61
- call_str += "%s#%s, " % [name, klass]
62
- when :tracked
63
- if arg_info && arg_info.size > i
64
- call_str += "#{name}: #{arg_info[i].inspect}, "
65
- else
66
- call_str += "%s, " % name
67
- end
42
+ if Command.settings[:callstyle] != :short && klass
43
+ call_str = "#{klass}.#{id.id2name}"
44
+ else
45
+ call_str = "#{id.id2name}"
46
+ end
47
+
48
+ args = context.frame_args(pos)
49
+ locals = context.frame_locals(pos)
50
+ if args.any?
51
+ call_str += "("
52
+ args.each_with_index do |name, i|
53
+ case Command.settings[:callstyle]
54
+ when :short
55
+ call_str += "#{name}, "
56
+ when :last
57
+ klass = locals[name].class
58
+ if klass.inspect.size > 20 + 3
59
+ klass = klass.inspect[0..20] + "..."
68
60
  end
69
- if call_str.size > self.class.settings[:width] - prefix.size
70
- # Strip off trailing ', ' if any but add stuff for later trunc
71
- call_str[-2..-1] = ",...XX"
72
- break
61
+ call_str += "#{name}##{klass}, "
62
+ when :tracked
63
+ arg_info = context.frame_args_info(pos)
64
+ if arg_info && arg_info.size > i
65
+ call_str += "#{name}: #{arg_info[i].inspect}, "
66
+ else
67
+ call_str += "#{name}, "
73
68
  end
74
69
  end
75
- call_str[-2..-1] = ")" # Strip off trailing ', ' if any
70
+ if call_str.size > Command.settings[:width] - prefix.size
71
+ # Strip off trailing ', ' if any but add stuff for later trunc
72
+ call_str[-2..-1] = ",...XX"
73
+ break
74
+ end
76
75
  end
76
+ call_str[-2..-1] = ")" # Strip off trailing ', ' if any
77
77
  end
78
78
  return call_str
79
79
  end
80
80
 
81
81
  def print_backtrace
82
82
  (0...@state.context.stack_size).each do |idx|
83
- if idx == @state.frame_pos
84
- print "--> "
85
- else
86
- print " "
87
- end
88
83
  print_frame(idx)
89
84
  end
90
85
  end
91
86
 
92
- def print_frame(pos, adjust = false, context=@state.context)
87
+ def print_frame(pos, mark_current = true, context = @state.context)
93
88
  file = context.frame_file(pos)
94
89
  line = context.frame_line(pos)
95
90
  klass = context.frame_class(pos)
@@ -102,17 +97,22 @@ module Byebug
102
97
  end
103
98
  end
104
99
 
105
- frame_num = "##{pos} "
106
- call_str = get_frame_call(frame_num, pos, context)
107
- file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}\n"
108
- print frame_num
109
- unless call_str.empty?
110
- print "#{call_str} "
111
- if call_str.size + frame_num.size + file_line.size > self.class.settings[:width]
112
- print "\n "
113
- end
100
+ if mark_current
101
+ frame_str = (pos == @state.frame_pos) ? "--> " : " "
102
+ else
103
+ frame_str = ""
114
104
  end
115
- print file_line
105
+
106
+ frame_str += sprintf "#%-2d ", pos
107
+ frame_str += get_frame_call(frame_str, pos, context)
108
+ file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}"
109
+ if frame_str.size + file_line.size + 1 > Command.settings[:width]
110
+ frame_str += "\n #{file_line}\n"
111
+ else
112
+ frame_str += " #{file_line}\n"
113
+ end
114
+
115
+ print frame_str
116
116
  #if ENV['EMACS'] && adjust
117
117
  # fmt = (Byebug.annotate.to_i > 1 ?
118
118
  # "\032\032source %s:%d\n" : "\032\032%s:%d\n")
@@ -183,13 +183,13 @@ module Byebug
183
183
 
184
184
  def help(cmd)
185
185
  s = if cmd == 'where'
186
- %{
186
+ %{
187
187
  w[here]\tdisplay stack frames
188
- }
188
+ }
189
189
  else
190
- %{
190
+ %{
191
191
  bt|backtrace\t\talias for where - display stack frames
192
- }
192
+ }
193
193
  end
194
194
  s += %{
195
195
  Print the entire stack frame. Each frame is numbered, the most
@@ -197,7 +197,7 @@ module Byebug
197
197
  command; "up" and "down" add or subtract respectively to frame
198
198
  numbers shown. The position of the current frame is marked with
199
199
  -->.
200
- }
200
+ }
201
201
  end
202
202
  end
203
203
  end
@@ -226,7 +226,7 @@ module Byebug
226
226
  end
227
227
  end
228
228
 
229
- class DownCommand < Command # :nodoc:
229
+ class DownCommand < Command
230
230
  def regexp
231
231
  /^\s* down (?:\s+(.*))? .*$/x
232
232
  end
@@ -250,7 +250,7 @@ module Byebug
250
250
  end
251
251
  end
252
252
 
253
- class FrameCommand < Command # :nodoc:
253
+ class FrameCommand < Command
254
254
  def regexp
255
255
  / ^\s*
256
256
  f(?:rame)?
@@ -273,9 +273,9 @@ module Byebug
273
273
  # return
274
274
  # end
275
275
  #else
276
- context = @state.context
276
+ # context = @state.context
277
277
  #end
278
- adjust_frame(pos, true, context)
278
+ adjust_frame(pos, true)
279
279
  end
280
280
 
281
281
  class << self
@@ -286,17 +286,16 @@ module Byebug
286
286
  def help(cmd)
287
287
  %{
288
288
  f[rame] [frame-number [thread thread-number]]
289
- Move the current frame to the specified frame number, or the
290
- 0 if no frame-number has been given.
291
289
 
292
- A negative number indicates position from the other end. So
293
- 'frame -1' moves to the oldest frame, and 'frame 0' moves to
294
- the newest frame.
290
+ Move the current frame to the specified frame number, or the 0 if no
291
+ frame-number has been given.
292
+
293
+ A negative number indicates position from the other end, so "frame -1"
294
+ moves to the oldest frame, and "frame 0" moves to the newest frame.
295
295
 
296
- Without an argument, the command prints the current stack
297
- frame. Since the current position is redisplayed, it may trigger a
298
- resyncronization if there is a front end also watching over
299
- things.
296
+ Without an argument, the command prints the current stack frame. Since
297
+ the current position is redisplayed, it may trigger a resyncronization
298
+ if there is a front end also watching over things.
300
299
 
301
300
  If a thread number is given then we set the context for evaluating
302
301
  expressions to that frame of that thread.
@@ -2,6 +2,7 @@ module Byebug
2
2
 
3
3
  # Implements byebug "help" command.
4
4
  class HelpCommand < Command
5
+ include Columnize
5
6
  self.allow_in_control = true
6
7
 
7
8
  def regexp
@@ -34,7 +35,7 @@ module Byebug
34
35
  print "Available commands:\n"
35
36
  cmds = @state.commands.map{ |cmd| cmd.help_command }
36
37
  cmds = cmds.flatten.uniq.sort
37
- print columnize(cmds, self.class.settings[:width])
38
+ print columnize(cmds, Command.settings[:width])
38
39
  end
39
40
  end
40
41
  print "\n"
@@ -18,7 +18,9 @@ module Byebug
18
18
 
19
19
  # Implements byebug "info" command.
20
20
  class InfoCommand < Command
21
+ include Columnize
21
22
  self.allow_in_control = true
23
+
22
24
  Subcommands =
23
25
  [
24
26
  ['args', 1, 'Argument variables of current stack frame'],
@@ -74,20 +76,20 @@ module Byebug
74
76
  SubcmdStruct.new(name, min, short_help, long_help)
75
77
  end unless defined?(InfoFileSubcommands)
76
78
 
77
- # InfoThreadSubcommands =
78
- # [
79
- # ['terse', 1, 'summary information'],
80
- # ['verbose', 1, 'summary information and stack frame info'],
81
- # ].map do |name, min, short_help, long_help|
82
- # SubcmdStruct.new(name, min, short_help, long_help)
83
- # end unless defined?(InfoThreadSubcommands)
79
+ InfoThreadSubcommands =
80
+ [
81
+ ['terse', 1, 'summary information'],
82
+ ['verbose', 1, 'summary information and stack frame info'],
83
+ ].map do |name, min, short_help, long_help|
84
+ SubcmdStruct.new(name, min, short_help, long_help)
85
+ end unless defined?(InfoThreadSubcommands)
84
86
 
85
87
  def regexp
86
88
  /^\s* i(?:nfo)? (?:\s+(.*))?$/ix
87
89
  end
88
90
 
89
91
  def execute
90
- return print_subcmds(Subcommands) unless @match[1]
92
+ return print format_subcmds(Subcommands) unless @match[1]
91
93
 
92
94
  args = @match[1].split(/[ \t]+/)
93
95
  param = args.shift
@@ -166,28 +168,33 @@ module Byebug
166
168
  print " - #{path}"
167
169
  end
168
170
  end
171
+ private :info_file_path
169
172
 
170
173
  def info_file_lines(file)
171
174
  lines = LineCache.size(file)
172
175
  print "\t %d lines\n", lines if lines
173
176
  end
177
+ private :info_file_lines
174
178
 
175
179
  def info_file_breakpoints(file)
176
180
  breakpoints = LineCache.trace_line_numbers(file)
177
181
  if breakpoints
178
182
  print "\tbreakpoint line numbers:\n"
179
- print columnize(breakpoints.to_a.sort, self.class.settings[:width])
183
+ print columnize(breakpoints.to_a.sort, Command.settings[:width])
180
184
  end
181
185
  end
186
+ private :info_file_breakpoints
182
187
 
183
188
  def info_file_mtime(file)
184
189
  stat = LineCache.stat(file)
185
190
  print "\t%s\n", stat.mtime if stat
186
191
  end
192
+ private :info_file_mtime
187
193
 
188
194
  def info_file_sha1(file)
189
195
  print "\t%s\n", LineCache.sha1(file)
190
196
  end
197
+ private :info_file_sha1
191
198
 
192
199
  def info_file(*args)
193
200
  return info_files unless args[0]
@@ -270,29 +277,30 @@ module Byebug
270
277
  end
271
278
  end
272
279
 
273
- def info_program(*args)
274
- if not @state.context
275
- print "The program being debugged is not being run.\n"
276
- return
277
- elsif @state.context.dead?
278
- print "The program crashed.\n"
279
- if Byebug.last_exception
280
- print("Exception: #{Byebug.last_exception.inspect}\n")
281
- end
282
- return
280
+ def info_stop_reason(stop_reason)
281
+ case stop_reason
282
+ when :step
283
+ print "It stopped after stepping, next'ing or initial start.\n"
284
+ when :breakpoint
285
+ print("It stopped at a breakpoint.\n")
286
+ when :catchpoint
287
+ print("It stopped at a catchpoint.\n")
288
+ else
289
+ print "unknown reason: %s\n" % @state.context.stop_reason.to_s
283
290
  end
291
+ end
292
+ private :info_stop_reason
293
+
294
+ def info_program(*args)
295
+ return print "The program being debugged is not being run.\n" if
296
+ not @state.context
297
+
298
+ return print "The program crashed.\n" + Byebug.last_exception ?
299
+ "Exception: #{Byebug.last_exception.inspect}" : "" + "\n" if
300
+ @state.context.dead?
284
301
 
285
302
  print "Program stopped. "
286
- case @state.context.stop_reason
287
- when :step
288
- print "It stopped after stepping, next'ing or initial start.\n"
289
- when :breakpoint
290
- print("It stopped at a breakpoint.\n")
291
- when :catchpoint
292
- print("It stopped at a catchpoint.\n")
293
- else
294
- print "unknown reason: %s\n" % @state.context.stop_reason.to_s
295
- end
303
+ info_stop_reason @state.context.stop_reason
296
304
  end
297
305
 
298
306
  def info_stack(*args)
@@ -330,7 +338,7 @@ module Byebug
330
338
  if verbose and not c.ignored?
331
339
  (0...c.stack_size).each do |idx|
332
340
  print "\t"
333
- print_frame(idx, false, c)
341
+ print_frame(idx, true, c)
334
342
  end
335
343
  end
336
344
  end
@@ -349,7 +357,7 @@ module Byebug
349
357
  if verbose and not c.ignored?
350
358
  (0...c.stack_size).each do |idx|
351
359
  print "\t"
352
- print_frame(idx, false, c)
360
+ print_frame(idx, true, c)
353
361
  end
354
362
  end
355
363
  end
@@ -407,24 +415,17 @@ module Byebug
407
415
  return str += "\nInvalid \"file\" attribute \"#{args[2]}\"." \
408
416
  unless subsubcmd
409
417
 
410
- str += "\n" + subsubcmd.short_help + '.'
418
+ return str += "\n" + subsubcmd.short_help + '.'
411
419
  else
412
- str += "\n" + subcmd.long_help if subcmd.long_help
420
+ return str += "\n" + subcmd.long_help if subcmd.long_help
413
421
  end
414
- return str
415
422
  end
416
423
 
417
424
  # general help
418
- s = %{
425
+ str = %{
419
426
  Generic command for showing things about the program being debugged.
420
- --
421
- List of info subcommands:
422
- --
423
427
  }
424
- for subcmd in Subcommands do
425
- s += "info #{subcmd.name} -- #{subcmd.short_help}\n"
426
- end
427
- return s
428
+ str += format_subcmds(Subcommands)
428
429
  end
429
430
  end
430
431
  end