byebug 1.8.2 → 2.0.0

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