byebug 1.8.2 → 2.0.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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/GUIDE.md +14 -22
  4. data/README.md +69 -6
  5. data/bin/byebug +3 -20
  6. data/ext/byebug/breakpoint.c +185 -101
  7. data/ext/byebug/byebug.c +393 -214
  8. data/ext/byebug/byebug.h +34 -15
  9. data/ext/byebug/context.c +327 -102
  10. data/ext/byebug/extconf.rb +1 -1
  11. data/ext/byebug/locker.c +54 -0
  12. data/ext/byebug/threads.c +113 -0
  13. data/lib/byebug.rb +19 -58
  14. data/lib/byebug/command.rb +18 -19
  15. data/lib/byebug/commands/breakpoints.rb +1 -4
  16. data/lib/byebug/commands/catchpoint.rb +1 -1
  17. data/lib/byebug/commands/condition.rb +1 -1
  18. data/lib/byebug/commands/control.rb +2 -3
  19. data/lib/byebug/commands/display.rb +2 -7
  20. data/lib/byebug/commands/edit.rb +1 -1
  21. data/lib/byebug/commands/enable.rb +12 -12
  22. data/lib/byebug/commands/eval.rb +4 -4
  23. data/lib/byebug/commands/finish.rb +1 -1
  24. data/lib/byebug/commands/frame.rb +12 -8
  25. data/lib/byebug/commands/info.rb +20 -52
  26. data/lib/byebug/commands/kill.rb +1 -5
  27. data/lib/byebug/commands/list.rb +2 -1
  28. data/lib/byebug/commands/quit.rb +1 -1
  29. data/lib/byebug/commands/repl.rb +2 -2
  30. data/lib/byebug/commands/save.rb +1 -1
  31. data/lib/byebug/commands/set.rb +84 -90
  32. data/lib/byebug/commands/show.rb +44 -53
  33. data/lib/byebug/commands/skip.rb +1 -1
  34. data/lib/byebug/commands/stepping.rb +5 -4
  35. data/lib/byebug/commands/threads.rb +202 -0
  36. data/lib/byebug/commands/trace.rb +1 -1
  37. data/lib/byebug/helper.rb +3 -3
  38. data/lib/byebug/interface.rb +2 -20
  39. data/lib/byebug/processor.rb +21 -100
  40. data/lib/byebug/remote.rb +3 -3
  41. data/lib/byebug/version.rb +1 -1
  42. data/old_doc/byebug.1 +0 -6
  43. data/old_doc/byebug.texi +29 -46
  44. data/test/breakpoints_test.rb +44 -65
  45. data/test/conditions_test.rb +0 -9
  46. data/test/continue_test.rb +2 -2
  47. data/test/display_test.rb +4 -23
  48. data/test/edit_test.rb +2 -16
  49. data/test/eval_test.rb +4 -13
  50. data/test/examples/thread.rb +32 -0
  51. data/test/finish_test.rb +1 -13
  52. data/test/frame_test.rb +5 -12
  53. data/test/help_test.rb +2 -12
  54. data/test/info_test.rb +8 -18
  55. data/test/kill_test.rb +1 -10
  56. data/test/list_test.rb +5 -14
  57. data/test/method_test.rb +1 -10
  58. data/test/post_mortem_test.rb +247 -14
  59. data/test/quit_test.rb +0 -9
  60. data/test/reload_test.rb +1 -15
  61. data/test/repl_test.rb +1 -9
  62. data/test/restart_test.rb +3 -18
  63. data/test/save_test.rb +1 -13
  64. data/test/set_test.rb +35 -32
  65. data/test/show_test.rb +8 -27
  66. data/test/source_test.rb +1 -8
  67. data/test/stepping_test.rb +65 -96
  68. data/test/support/test_dsl.rb +12 -17
  69. data/test/test_helper.rb +1 -1
  70. data/test/thread_test.rb +106 -0
  71. data/test/trace_test.rb +5 -17
  72. data/test/variables_test.rb +1 -10
  73. metadata +9 -7
  74. data/lib/byebug/commands/jump.rb +0 -52
  75. data/test/jump_test.rb +0 -77
  76. data/test/support/context.rb +0 -15
@@ -4,7 +4,7 @@ module Byebug
4
4
  self.allow_in_control = true
5
5
 
6
6
  def regexp
7
- /^\s* (?:restart|R) (?:\s+(.+))? \s*$/ix
7
+ /^\s* (?:restart|R) (?:\s+(.+))? \s*$/x
8
8
  end
9
9
 
10
10
  def execute
@@ -19,8 +19,7 @@ module Byebug
19
19
  if not File.executable?(Byebug::PROG_SCRIPT)
20
20
  print "Ruby program #{Byebug::PROG_SCRIPT} not executable... " \
21
21
  "We'll add a call to Ruby.\n"
22
- ruby = begin defined?(Gem) ? Gem.ruby : "ruby" rescue "ruby" end
23
- cmd = "#{ruby} -I#{$:.join(' -I')} #{Byebug::PROG_SCRIPT}"
22
+ cmd = "ruby -rbyebug -I#{$:.join(' -I')} #{Byebug::PROG_SCRIPT}"
24
23
  else
25
24
  cmd = Byebug::PROG_SCRIPT
26
25
  end
@@ -2,7 +2,7 @@ module Byebug
2
2
 
3
3
  module DisplayFunctions
4
4
  def display_expression(exp)
5
- print "#{exp} = #{debug_silent_eval(exp).to_s}\n"
5
+ print "#{exp} = #{debug_silent_eval(exp).inspect}\n"
6
6
  end
7
7
 
8
8
  def active_display_expressions?
@@ -46,12 +46,7 @@ module Byebug
46
46
 
47
47
  class DisplayCommand < Command
48
48
  def self.always_run
49
- Byebug.annotate = 0 unless Byebug.annotate
50
- if Byebug.annotate > 1
51
- 0
52
- else
53
- 2
54
- end
49
+ 2
55
50
  end
56
51
 
57
52
  def regexp
@@ -4,7 +4,7 @@ module Byebug
4
4
  self.allow_in_control = true
5
5
 
6
6
  def regexp
7
- /^\s* ed(?:it)? (?:\s+(\S+))? \s*$/ix
7
+ /^\s* ed(?:it)? (?:\s+(\S+))? \s*$/x
8
8
  end
9
9
 
10
10
  def execute
@@ -16,7 +16,7 @@ module Byebug
16
16
  return nil unless pos
17
17
  breakpoints.each do |b|
18
18
  if b.id == pos
19
- enabled = ('Enable' == is_enable)
19
+ enabled = ('enable' == is_enable)
20
20
  if enabled
21
21
  unless syntax_valid?(b.expr)
22
22
  errmsg "Expression \"#{b.expr}\" syntactically incorrect; " \
@@ -24,7 +24,7 @@ module Byebug
24
24
  break
25
25
  end
26
26
  end
27
- b.enabled = ('Enable' == is_enable)
27
+ b.enabled = ('enable' == is_enable)
28
28
  break
29
29
  end
30
30
  end
@@ -39,7 +39,7 @@ module Byebug
39
39
  args.each do |pos|
40
40
  pos = get_int(pos, "#{is_enable} display", 1, @state.display.size)
41
41
  return nil unless pos
42
- @state.display[pos-1][0] = ('Enable' == is_enable)
42
+ @state.display[pos-1][0] = ('enable' == is_enable)
43
43
  end
44
44
  end
45
45
  end
@@ -52,15 +52,15 @@ module Byebug
52
52
  'used to cancel the effect of the "disable" command.'],
53
53
  ['display', 2,
54
54
  'Enable some expressions to be displayed when program stops',
55
- 'Arguments are the code numbers of the expressions to resume ' \
55
+ 'Arguments are the code numbers of the expressions to resume ' \
56
56
  'displaying. Do "info display" to see the current list of code ' \
57
57
  'numbers.'],
58
58
  ].map do |name, min, short_help, long_help|
59
- SubcmdStruct.new(name, min, short_help, long_help)
59
+ Subcmd.new(name, min, short_help, long_help)
60
60
  end unless defined?(Subcommands)
61
61
 
62
62
  def regexp
63
- /^\s* en(?:able)? (?:\s+(.+))? \s*$/ix
63
+ /^\s* en(?:able)? (?:\s+(.+))? \s*$/x
64
64
  end
65
65
 
66
66
  def execute
@@ -78,11 +78,11 @@ module Byebug
78
78
  end
79
79
 
80
80
  def enable_breakpoints(args)
81
- enable_disable_breakpoints('Enable', args)
81
+ enable_disable_breakpoints('enable', args)
82
82
  end
83
83
 
84
84
  def enable_display(args)
85
- enable_disable_display('Enable', args)
85
+ enable_disable_display('enable', args)
86
86
  end
87
87
 
88
88
  class << self
@@ -110,11 +110,11 @@ module Byebug
110
110
  'displaying. Do "info display" to see the current list of code ' \
111
111
  'numbers.'],
112
112
  ].map do |name, min, short_help, long_help|
113
- SubcmdStruct.new(name, min, short_help, long_help)
113
+ Subcmd.new(name, min, short_help, long_help)
114
114
  end unless defined?(Subcommands)
115
115
 
116
116
  def regexp
117
- /^\s* dis(?:able)? (?:\s+(.+))? \s*$/ix
117
+ /^\s* dis(?:able)? (?:\s+(.+))? \s*$/x
118
118
  end
119
119
 
120
120
  def execute
@@ -132,11 +132,11 @@ module Byebug
132
132
  end
133
133
 
134
134
  def disable_breakpoints(args)
135
- enable_disable_breakpoints('Disable', args)
135
+ enable_disable_breakpoints('disable', args)
136
136
  end
137
137
 
138
138
  def disable_display(args)
139
- enable_disable_display('Disable', args)
139
+ enable_disable_display('disable', args)
140
140
  end
141
141
 
142
142
  class << self
@@ -43,7 +43,7 @@ module Byebug
43
43
  end
44
44
 
45
45
  def regexp
46
- /^\s*(p|e(?:val)?)\s+/x
46
+ /^\s* (p|e(?:val)?)\s+/x
47
47
  end
48
48
 
49
49
  def execute
@@ -72,7 +72,7 @@ module Byebug
72
72
  self.allow_in_control = true
73
73
 
74
74
  def regexp
75
- /^\s*pp\s+/
75
+ /^\s* pp \s+/x
76
76
  end
77
77
 
78
78
  def execute
@@ -101,7 +101,7 @@ module Byebug
101
101
  self.allow_in_control = true
102
102
 
103
103
  def regexp
104
- /^\s*putl\s+/
104
+ /^\s* putl\s+/x
105
105
  end
106
106
 
107
107
  def execute
@@ -138,7 +138,7 @@ module Byebug
138
138
  self.allow_in_control = true
139
139
 
140
140
  def regexp
141
- /^\s*ps\s+/
141
+ /^\s* ps\s+/x
142
142
  end
143
143
 
144
144
  def execute
@@ -14,7 +14,7 @@ module Byebug
14
14
  if not @match[1]
15
15
  frame_pos = @state.frame_pos
16
16
  else
17
- frame_pos = get_int(@match[1], "Finish", 0, max_frame-1, 0)
17
+ frame_pos = get_int(@match[1], "finish", 0, max_frame-1, 0)
18
18
  return nil unless frame_pos
19
19
  end
20
20
  @state.context.step_out frame_pos
@@ -103,13 +103,17 @@ module Byebug
103
103
  end
104
104
 
105
105
  def print_backtrace
106
- realsize = caller_locations.
107
- drop_while{ |l| IGNORED_FILES.include?(l.path) || l.path == '(eval)' }.
108
- take_while{ |l| !IGNORED_FILES.include?(l.path) }.size
109
- if @state.context.stack_size != realsize
110
- errmsg "Warning, Byebug's stacksize (#{@state.context.stack_size}) is" \
111
- " incorrect (must be #{realsize}). This might be a bug in " \
112
- "byebug or ruby's debugging API's\n"
106
+ if Byebug.post_mortem?
107
+ realsize = @state.context.stack_size
108
+ else
109
+ realsize = Thread.current.backtrace_locations.
110
+ drop_while{ |l| IGNORED_FILES.include?(l.path) || l.path == '(eval)' }.
111
+ take_while{ |l| !IGNORED_FILES.include?(l.path) }.size
112
+ size = @state.context.stack_size
113
+ if size != realsize
114
+ errmsg "Byebug's stacksize (#{size}) should be #{realsize}. " \
115
+ "This might be a bug in byebug or ruby's debugging API's\n"
116
+ end
113
117
  end
114
118
  (0...realsize).each do |idx|
115
119
  print_frame(idx)
@@ -120,7 +124,7 @@ module Byebug
120
124
  file = @state.context.frame_file pos
121
125
  line = @state.context.frame_line pos
122
126
 
123
- unless Command.settings[:frame_fullpath]
127
+ unless Command.settings[:fullpath]
124
128
  path_components = file.split(/[\\\/]/)
125
129
  if path_components.size > 3
126
130
  path_components[0...-3] = '...'
@@ -44,7 +44,7 @@ module Byebug
44
44
  ['variables', 1,
45
45
  'Local and instance variables of the current stack frame']
46
46
  ].map do |name, min, short_help, long_help|
47
- SubcmdStruct.new(name, min, short_help, long_help)
47
+ Subcmd.new(name, min, short_help, long_help)
48
48
  end unless defined?(Subcommands)
49
49
 
50
50
  InfoFileSubcommands =
@@ -59,11 +59,11 @@ module Byebug
59
59
  ['path', 4, 'Show full file path name for file'],
60
60
  ['sha1', 1, 'Show SHA1 hash of contents of the file']
61
61
  ].map do |name, min, short_help, long_help|
62
- SubcmdStruct.new(name, min, short_help, long_help)
63
- end unless defined?(InfoFileSubcommands)
62
+ Subcmd.new(name, min, short_help, long_help)
63
+ end unless defined?(InfoFileSubcommands)
64
64
 
65
65
  def regexp
66
- /^\s* i(?:nfo)? (?:\s+(.+))? \s*$/ix
66
+ /^\s* i(?:nfo)? (?:\s+(.+))? \s*$/x
67
67
  end
68
68
 
69
69
  def execute
@@ -72,16 +72,16 @@ module Byebug
72
72
  args = @match[1].split(/[ \t]+/)
73
73
  param = args.shift
74
74
  subcmd = Command.find(Subcommands, param)
75
- if subcmd
75
+ return errmsg "Unknown info command #{param}\n" unless subcmd
76
+
77
+ if @state.context
76
78
  send("info_#{subcmd.name}", *args)
77
79
  else
78
- errmsg "Unknown info command #{param}\n"
80
+ errmsg "info_#{subcmd.name} not available without a context.\n"
79
81
  end
80
82
  end
81
83
 
82
84
  def info_args(*args)
83
- return errmsg "No frame selected.\n" unless @state.context
84
-
85
85
  locals = @state.context.frame_locals
86
86
  args = @state.context.frame_args
87
87
  return if args == [[:rest]]
@@ -106,9 +106,6 @@ module Byebug
106
106
  private :info_breakpoint
107
107
 
108
108
  def info_breakpoints(*args)
109
- return errmsg "\"info breakpoints\" not available here.\n" unless
110
- @state.context
111
-
112
109
  return print "No breakpoints.\n" if Byebug.breakpoints.empty?
113
110
 
114
111
  brkpts = Byebug.breakpoints.sort_by{|b| b.id}
@@ -123,9 +120,6 @@ module Byebug
123
120
  end
124
121
 
125
122
  def info_display(*args)
126
- return errmsg "\"info display\" not available here.\n" unless
127
- @state.context
128
-
129
123
  return print "There are no auto-display expressions now.\n" unless
130
124
  @state.display.find{|d| d[0]}
131
125
 
@@ -207,38 +201,35 @@ module Byebug
207
201
  end
208
202
 
209
203
  def info_instance_variables(*args)
210
- return errmsg "\"info instance_variables\" not available here.\n" unless
211
- @state.context
212
-
213
204
  obj = debug_eval('self')
214
205
  var_list(obj.instance_variables)
215
206
  end
216
207
 
217
208
  def info_line(*args)
218
- return errmsg "\"info line\" not available here.\n" unless @state.context
219
209
  print "Line #{@state.line} of \"#{@state.file}\"\n"
220
210
  end
221
211
 
222
212
  def info_locals(*args)
223
- return errmsg "\"info locals\" not available here.\n" unless
224
- @state.context
225
-
226
213
  locals = @state.context.frame_locals
227
- locals.keys.sort.each do |name|
228
- ### FIXME: make a common routine
214
+ print_hash(locals)
215
+ end
216
+
217
+ def print_hash(vars)
218
+ vars.keys.sort.each do |name|
229
219
  begin
230
- s = "#{name} = #{locals[name].inspect}"
220
+ s = "#{name} = #{vars[name].inspect}"
231
221
  rescue
232
222
  begin
233
- s = "#{name} = #{locals[name].to_s}"
223
+ s = "#{name} = #{vars[name].to_s}"
234
224
  rescue
235
- s = "*Error in evaluation*"
225
+ s = "#{name} = *Error in evaluation*"
236
226
  end
237
227
  end
238
228
  pad_with_dots(s)
239
229
  print "#{s}\n"
240
230
  end
241
231
  end
232
+ private :print_hash
242
233
 
243
234
  def info_stop_reason(stop_reason)
244
235
  case stop_reason
@@ -255,9 +246,6 @@ module Byebug
255
246
  private :info_stop_reason
256
247
 
257
248
  def info_program(*args)
258
- return errmsg "The program being debugged is not being run.\n" unless
259
- @state.context
260
-
261
249
  return print "The program crashed.\n" + Byebug.last_exception ?
262
250
  "Exception: #{Byebug.last_exception.inspect}" : "" + "\n" if
263
251
  @state.context.dead?
@@ -267,39 +255,19 @@ module Byebug
267
255
  end
268
256
 
269
257
  def info_stack(*args)
270
- return errmsg "\"info stack\" not available here.\n" unless @state.context
271
-
272
258
  print_backtrace
273
259
  end
274
260
 
275
261
  def info_global_variables(*args)
276
- return errmsg "\"info global_variables\" not available here.\n" unless
277
- @state.context
278
-
279
262
  var_global
280
263
  end
281
264
 
282
265
  def info_variables(*args)
283
- return errmsg "\"info variables\" not available here.\n" unless
284
- @state.context
285
-
286
- obj = debug_eval('self')
287
266
  locals = @state.context.frame_locals
288
267
  locals[:self] = @state.context.frame_self(@state.frame_pos)
289
- locals.keys.sort.each do |name|
290
- ### FIXME: make a common routine
291
- begin
292
- s = "#{name} = #{locals[name].inspect}"
293
- rescue
294
- begin
295
- s = "#{name} = #{locals[name].to_s}"
296
- rescue
297
- s = "#{name} = *Error in evaluation*"
298
- end
299
- end
300
- pad_with_dots(s)
301
- print "#{s}\n"
302
- end
268
+ print_hash(locals)
269
+
270
+ obj = debug_eval('self')
303
271
  var_list(obj.instance_variables, obj.instance_eval{binding()})
304
272
  var_class_self
305
273
  end
@@ -5,11 +5,7 @@ module Byebug
5
5
  self.allow_in_control = true
6
6
 
7
7
  def regexp
8
- / ^\s*
9
- (?:kill) \s*
10
- (?:\s+(\S+))?\s*
11
- $
12
- /ix
8
+ /^\s* (?:kill) \s* (?:\s+(\S+))? \s*$/x
13
9
  end
14
10
 
15
11
  def execute
@@ -28,7 +28,7 @@ module Byebug
28
28
  b, e = set_line_range(Command.settings[:listsize], lines.size)
29
29
  return @state.previous_line if b < 0
30
30
 
31
- print "[#{b}, #{e}] in #{@state.file}\n"
31
+ print "\n[#{b}, #{e}] in #{@state.file}\n"
32
32
  @state.previous_line = display_list(b, e, lines, @state.line)
33
33
  end
34
34
 
@@ -114,6 +114,7 @@ module Byebug
114
114
  end
115
115
  end
116
116
  end
117
+ print "\n"
117
118
  return e == lines.size ? @state.previous_line : b
118
119
  end
119
120
  end
@@ -5,7 +5,7 @@ module Byebug
5
5
  self.allow_in_control = true
6
6
 
7
7
  def regexp
8
- /^\s* (?:q(?:uit)?|exit) \s* (!|\s+unconditionally)? \s*$/ix
8
+ /^\s* (?:q(?:uit)?|exit) \s* (!|\s+unconditionally)? \s*$/x
9
9
  end
10
10
 
11
11
  def execute
@@ -74,11 +74,11 @@ module Byebug
74
74
  when :cont
75
75
  @state.proceed
76
76
  when :step
77
- force = Command.settings[:force_stepping]
77
+ force = Command.settings[:forcestep]
78
78
  @state.context.step_into 1, force
79
79
  @state.proceed
80
80
  when :next
81
- force = Command.settings[:force_stepping]
81
+ force = Command.settings[:forcestep]
82
82
  @state.context.step_over 1, @state.frame_pos, force
83
83
  @state.proceed
84
84
  else
@@ -49,7 +49,7 @@ module Byebug
49
49
  end
50
50
 
51
51
  def regexp
52
- /^\s* sa(?:ve)? (?:\s+(\S+))? \s*$/ix
52
+ /^\s* sa(?:ve)? (?:\s+(\S+))? \s*$/x
53
53
  end
54
54
 
55
55
  def execute
@@ -1,5 +1,69 @@
1
1
  module Byebug
2
2
 
3
+ # Mix-in module to setting settings
4
+ module SetFunctions
5
+
6
+ def set_setting(setting_name, setting_value, setting_args)
7
+ case setting_name
8
+ when /^args$/
9
+ if defined?(Byebug::BYEBUG_SCRIPT)
10
+ Command.settings[:argv][1..-1] = setting_args
11
+ else
12
+ Command.settings[:argv] = setting_args
13
+ end
14
+ when /^autoirb$/
15
+ Command.settings[:autoirb] = (setting_value ? 1 : 0)
16
+ when /^autolist$/
17
+ Command.settings[:autolist] = (setting_value ? 1 : 0)
18
+ when /^callstyle$/
19
+ if setting_args[0] and ['short', 'long'].include?(setting_args[0])
20
+ Command.settings[:callstyle] = setting_args[0].to_sym
21
+ else
22
+ print "Invalid callstyle. Should be one of: \"short\" or \"long\"\n"
23
+ end
24
+ when /^history$/
25
+ try_subcmd = setting_args[0]
26
+ subcmd = Command.find(SetCommand::SetHistorySubcommands, try_subcmd)
27
+ return print "Invalid history parameter #{try_subcmd}. Should be" \
28
+ ' "filename", "save" or "size"' unless subcmd
29
+
30
+ sub_sub_cmd = setting_args[1]
31
+ iface = @state.interface
32
+ case subcmd.name
33
+ when /^save$/
34
+ iface.history_save = sub_sub_cmd ? get_onoff(sub_sub_cmd) : true
35
+ when /^size$/
36
+ return print 'You need to specify the history size' unless sub_sub_cmd
37
+ iface.history_length = get_int(sub_sub_cmd, "Set history size")
38
+ when /^filename$/
39
+ return print 'You need to specify a filename' unless sub_sub_cmd
40
+ iface.histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", sub_sub_cmd)
41
+ end
42
+ when /^linetrace$/
43
+ Byebug.tracing = setting_value
44
+ when /^listsize$/
45
+ listsize = get_int(setting_args[0], "Set listsize", 1, nil, 10)
46
+ return unless listsize
47
+ Command.settings[:listsize] = listsize
48
+ when /^width$/
49
+ return unless width = get_int(setting_args[0], "Set width", 10, nil, 80)
50
+ Command.settings[:width] = width
51
+ when /^post_mortem$/
52
+ if setting_value
53
+ Byebug.post_mortem
54
+ else
55
+ Byebug.post_mortem = false
56
+ end
57
+ when /^autoeval|autoreload|basename|forcestep|fullpath|linetrace_plus|
58
+ testing|stack_trace_on_error$/x
59
+ Command.settings[setting_name.to_sym] = setting_value
60
+ else
61
+ return print "Unknown setting #{@match[1]}.\n"
62
+ end
63
+ end
64
+ end
65
+
66
+
3
67
  # Implements byebug "set" command.
4
68
  class SetCommand < Command
5
69
  SubcmdStruct2 = Struct.new(:name,
@@ -10,12 +74,8 @@ module Byebug
10
74
 
11
75
  Subcommands =
12
76
  [
13
- ['annotate', 2, false, 'Set annotation level',
14
- '0 == normal; ' \
15
- '2 == output annotated suitably for use by programs that control ' \
16
- 'byebug'],
17
77
  ['args', 2, false,
18
- 'Set argument list to give program being debugged when it is started'],
78
+ 'Set argument list to the program being debugged when it is started'],
19
79
  ['autoeval', 4, true, 'Evaluate every unrecognized command'],
20
80
  ['autolist', 4, true, 'Execute "list" command on every breakpoint'],
21
81
  ['autoirb', 4, true, 'Invoke IRB on every stop'],
@@ -26,27 +86,34 @@ module Byebug
26
86
  ['forcestep', 2, true,
27
87
  'Make sure "next/step" commands always move to a new line'],
28
88
  ['fullpath', 2, true, 'Display full file names in frames'],
29
- ['history', 2, false,
30
- 'Generic command for setting command history parameters',
31
- 'set history filename -- Set the filename in which to record the ' \
32
- 'command history' \
33
- 'set history save -- Set saving of the history record on exit' \
34
- 'set history size -- Set the size of the command history'],
35
- ['linetrace+', 10, true,
89
+ ['history', 2, false, 'Command for setting command history parameters',
90
+ 'History parameters are "filename", "save" and "size"'],
91
+ ['linetrace', 3, true, 'Enable line execution tracing'],
92
+ ['linetrace_plus', 10, true,
36
93
  'Set line execution tracing to show different lines'],
37
- ['linetrace', 3, true, 'Set line execution tracing'],
38
94
  ['listsize', 3, false, 'Set number of source lines to list by default'],
39
- ['trace', 1, true, 'Display stack trace when "eval" raises exception'],
95
+ ['post_mortem', 2, true, 'Enable post-mortem mode'],
96
+ ['stack_trace_on_error', 1, true,
97
+ 'Display stack trace when "eval" raises exception'],
40
98
  ['width', 1, false,
41
99
  'Number of characters per line for byebug\'s output']
42
100
  ].map do |name, min, is_bool, short_help, long_help|
43
101
  SubcmdStruct2.new(name, min, is_bool, short_help, long_help)
44
102
  end unless defined?(Subcommands)
45
103
 
104
+ SetHistorySubcommands =
105
+ [
106
+ ['filename', 1, 'Set the filename in which to record command history'],
107
+ ['save', 1, 'Set saving of the history record on exit'],
108
+ ['size', 1, 'Set the size of the command history']
109
+ ].map do |name, min, short_help, long_help|
110
+ Subcmd.new(name, min, short_help, long_help)
111
+ end unless defined?(SetHistorySubcommands)
112
+
46
113
  self.allow_in_control = true
47
114
 
48
115
  def regexp
49
- /^\s* set (?:\s+(.*))? \s*$/ix
116
+ /^\s* set (?:\s+(.*))? \s*$/x
50
117
  end
51
118
 
52
119
  def execute
@@ -63,8 +130,6 @@ module Byebug
63
130
  end
64
131
 
65
132
  subcmd = Command.find(Subcommands, try_subcmd)
66
-
67
- # Subcommand not found...
68
133
  return print "Unknown set command \"#{try_subcmd}\"\n" unless subcmd
69
134
 
70
135
  begin
@@ -73,79 +138,8 @@ module Byebug
73
138
  return
74
139
  end
75
140
 
76
- case subcmd.name
77
- when /^annotate$/
78
- level = get_int(args[0], "Set annotate", 0, 3, 0)
79
- if level
80
- Byebug.annotate = level
81
- else
82
- return
83
- end
84
- when /^args$/
85
- if defined?(Byebug::BYEBUG_SCRIPT)
86
- Command.settings[:argv][1..-1] = args
87
- else
88
- Command.settings[:argv] = args
89
- end
90
- when /^autolist$/
91
- Command.settings[:autolist] = (set_on ? 1 : 0)
92
- when /^autoeval$/
93
- Command.settings[:autoeval] = set_on
94
- when /^basename$/
95
- Command.settings[:basename] = set_on
96
- when /^callstyle$/
97
- if args[0] and (args[0] == 'short' or args[0] == 'long')
98
- Command.settings[:callstyle] = args[0].to_sym
99
- else
100
- print "Invalid callstyle. Should be one of: \"short\" or \"long\"\n"
101
- end
102
- when /^trace$/
103
- Command.settings[:stack_trace_on_error] = set_on
104
- when /^fullpath$/
105
- Command.settings[:frame_fullpath] = set_on
106
- when /^autoreload$/
107
- Command.settings[:autoreload] = set_on
108
- when /^autoirb$/
109
- Command.settings[:autoirb] = (set_on ? 1 : 0)
110
- when /^testing$/
111
- Command.settings[:testing] = set_on
112
- when /^forcestep$/
113
- Command.settings[:force_stepping] = set_on
114
- when /^history$/
115
- if 2 == args.size
116
- interface = @state.interface
117
- case args[0]
118
- when /^save$/
119
- interface.history_save = get_onoff(args[1])
120
- when /^size$/
121
- interface.history_length =
122
- get_int(args[1], "Set history size")
123
- when /^filename$/
124
- interface.histfile =
125
- File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", args[1])
126
- else
127
- print "Invalid history parameter #{args[0]}. Should be " \
128
- "\"filename\", \"save\" or \"size\".\n"
129
- end
130
- else
131
- print 'Need two parameters for "set history"; got ' \
132
- "#{args.size}.\n"
133
- return
134
- end
135
- when /^linetrace\+$/
136
- self.class.settings[:tracing_plus] = set_on
137
- when /^linetrace$/
138
- Byebug.tracing = set_on
139
- when /^listsize$/
140
- listsize = get_int(args[0], "Set listsize", 1, nil, 10)
141
- return unless listsize
142
- self.class.settings[:listsize] = listsize
143
- when /^width$/
144
- return unless width = get_int(args[0], "Set width", 10, nil, 80)
145
- Command.settings[:width] = width
146
- else
147
- return print "Unknown setting #{@match[1]}.\n"
148
- end
141
+ set_setting(subcmd.name, set_on, args)
142
+
149
143
  return print "#{show_setting(subcmd.name)}\n"
150
144
  end
151
145