byebug 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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