byebug 2.7.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -6
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +23 -0
  5. data/Gemfile +9 -0
  6. data/README.md +35 -32
  7. data/Rakefile +1 -3
  8. data/byebug.gemspec +0 -6
  9. data/ext/byebug/byebug.c +64 -51
  10. data/ext/byebug/byebug.h +12 -13
  11. data/ext/byebug/context.c +28 -43
  12. data/ext/byebug/extconf.rb +6 -6
  13. data/lib/byebug.rb +34 -38
  14. data/lib/byebug/command.rb +4 -2
  15. data/lib/byebug/commands/continue.rb +0 -1
  16. data/lib/byebug/commands/control.rb +0 -1
  17. data/lib/byebug/commands/edit.rb +1 -1
  18. data/lib/byebug/commands/finish.rb +10 -16
  19. data/lib/byebug/commands/help.rb +1 -1
  20. data/lib/byebug/commands/kill.rb +1 -1
  21. data/lib/byebug/commands/quit.rb +1 -1
  22. data/lib/byebug/commands/repl.rb +3 -3
  23. data/lib/byebug/commands/set.rb +24 -39
  24. data/lib/byebug/commands/show.rb +39 -112
  25. data/lib/byebug/commands/stepping.rb +0 -2
  26. data/lib/byebug/commands/threads.rb +0 -5
  27. data/lib/byebug/commands/trace.rb +1 -1
  28. data/lib/byebug/commands/variables.rb +1 -1
  29. data/lib/byebug/context.rb +8 -12
  30. data/lib/byebug/helper.rb +1 -1
  31. data/lib/byebug/history.rb +46 -0
  32. data/lib/byebug/interface.rb +5 -5
  33. data/lib/byebug/interfaces/local_interface.rb +11 -62
  34. data/lib/byebug/interfaces/remote_interface.rb +6 -22
  35. data/lib/byebug/interfaces/script_interface.rb +2 -17
  36. data/lib/byebug/processor.rb +4 -4
  37. data/lib/byebug/{command_processor.rb → processors/command_processor.rb} +7 -14
  38. data/lib/byebug/{control_command_processor.rb → processors/control_command_processor.rb} +3 -7
  39. data/lib/byebug/version.rb +1 -1
  40. data/test/edit_test.rb +6 -6
  41. data/test/examples/breakpoint_deep.rb +1 -1
  42. data/test/finish_test.rb +6 -6
  43. data/test/help_test.rb +1 -1
  44. data/test/info_test.rb +0 -1
  45. data/test/kill_test.rb +2 -2
  46. data/test/post_mortem_test.rb +35 -219
  47. data/test/quit_test.rb +2 -2
  48. data/test/restart_test.rb +12 -33
  49. data/test/set_test.rb +80 -107
  50. data/test/show_test.rb +42 -77
  51. data/test/stepping_test.rb +1 -1
  52. data/test/support/test_dsl.rb +4 -25
  53. data/test/support/test_interface.rb +40 -48
  54. data/test/test_helper.rb +1 -3
  55. data/test/timeout_test.rb +9 -0
  56. metadata +8 -75
@@ -23,41 +23,29 @@ module Byebug
23
23
  end
24
24
  when /^verbose$/
25
25
  Byebug.verbose = setting_value
26
- when /^history$/
27
- try_subcmd = setting_args[0]
28
- subcmd = Command.find(SetCommand::SetHistorySubcommands, try_subcmd)
29
- return print "Invalid history parameter #{try_subcmd}. Should be" \
30
- ' "filename", "save" or "size"' unless subcmd
31
-
32
- sub_sub_cmd = setting_args[1]
33
- iface = @state.interface
34
- case subcmd.name
35
- when /^save$/
36
- iface.history_save = sub_sub_cmd ? get_onoff(sub_sub_cmd) : true
37
- when /^size$/
38
- return print 'You need to specify the history size' unless sub_sub_cmd
39
- iface.history_length = get_int(sub_sub_cmd, "Set history size")
40
- when /^filename$/
41
- return print 'You need to specify a filename' unless sub_sub_cmd
42
- iface.histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", sub_sub_cmd)
43
- end
26
+ when /^histfile$/
27
+ return print 'You need to specify a filename' unless setting_args[0]
28
+ Byebug::History.file = File.expand_path(setting_args[0])
29
+ when /^histsize$/
30
+ return print 'You need to specify the history size' unless setting_args[0]
31
+ Byebug::History.max_size = get_int(setting_args[0], "Set histsize")
44
32
  when /^linetrace$/
45
33
  Byebug.tracing = setting_value
46
34
  when /^listsize$/
47
- listsize = get_int(setting_args[0], "Set listsize", 1, nil, 10)
35
+ listsize = get_int(setting_args[0], 'Set listsize', 1, nil, 10)
48
36
  return unless listsize
49
37
  Command.settings[:listsize] = listsize
50
38
  when /^width$/
51
- return unless width = get_int(setting_args[0], "Set width", 10, nil, 80)
39
+ return unless width = get_int(setting_args[0], 'Set width', 10, nil, 80)
52
40
  Command.settings[:width] = width
53
41
  when /^post_mortem$/
54
42
  if setting_value == true
55
43
  Byebug.post_mortem
56
44
  else
57
- return print 'Sorry... not implemented yet. Restart byebug'
45
+ Byebug.post_mortem = false
58
46
  end
59
- when /^autoeval|autoreload|basename|forcestep|fullpath|linetrace_plus|
60
- testing|stack_on_error$/x
47
+ when /^autoeval|autoreload|autosave|basename|forcestep|fullpath|
48
+ linetrace_plus|testing|stack_on_error$/x
61
49
  Command.settings[setting_name.to_sym] = setting_value
62
50
  else
63
51
  return print "Unknown setting #{@match[1]}.\n"
@@ -72,21 +60,25 @@ module Byebug
72
60
  Subcommands = [
73
61
  ['args' , 2 , false, 'Set argument list to the program ' \
74
62
  'being debugged when it is started' ],
75
- ['autoeval' , 4 , true , 'Evaluate every unrecognized command' ],
76
- ['autolist' , 4 , true , 'Execute "list" command on every ' \
63
+ ['autoeval' , 5 , true , 'Evaluate every unrecognized command' ],
64
+ ['autolist' , 5 , true , 'Execute "list" command on every ' \
77
65
  'breakpoint' ],
78
- ['autoirb' , 4 , true , 'Invoke IRB on every stop' ],
79
- ['autoreload' , 4 , true , 'Reload source code when changed' ],
66
+ ['autoirb' , 5 , true , 'Invoke IRB on every stop' ],
67
+ ['autoreload' , 5 , true , 'Reload source code when changed' ],
68
+ ['autosave' , 5 , true , 'Automatically save command history ' \
69
+ 'record on exit' ],
80
70
  ['basename' , 1 , true , 'Set filename display style' ],
81
71
  ['callstyle' , 2 , false, 'Set how you want call parameters ' \
82
72
  'displayed' ],
83
- ['testing' , 2 , false, 'Used when testing byebug' ],
84
73
  ['forcestep' , 2 , true , 'Make sure "next/step" commands always' \
85
74
  'move to a new line' ],
86
75
  ['fullpath' , 2 , true , 'Display full file names in frames' ],
87
- ['history' , 2 , false, 'Command for setting command history ' \
88
- 'parameters, namely, "filename", ' \
89
- '"save" and "size"' ],
76
+ ['histfile' , 5 , false, 'Customize file where history is ' \
77
+ 'loaded from and saved to. By ' \
78
+ 'default, .byebug_hist' ],
79
+ ['histsize' , 5 , false, 'Customize maximum number of commands ' \
80
+ 'that are stored in byebug history ' \
81
+ 'record. By default, 256' ],
90
82
  ['linetrace' , 3 , true , 'Enable line execution tracing' ],
91
83
  ['linetrace_plus', 10, true , 'Set line execution tracing to show' \
92
84
  'different lines' ],
@@ -95,6 +87,7 @@ module Byebug
95
87
  ['post_mortem' , 2 , true , 'Enable post-mortem mode' ],
96
88
  ['stack_on_error', 1 , true , 'Display stack trace when "eval" ' \
97
89
  'raises exception' ],
90
+ ['testing' , 2 , false, 'Used when testing byebug' ],
98
91
  ['verbose' , 1 , true , 'Enable verbose output of TracePoint ' \
99
92
  'API events is enabled' ],
100
93
  ['width' , 1 , false, 'Number of characters per line for ' \
@@ -103,14 +96,6 @@ module Byebug
103
96
  Subcmd2.new(name, min, is_bool, help)
104
97
  end unless defined?(Subcommands)
105
98
 
106
- SetHistorySubcommands = [
107
- ['filename', 1, 'Set the filename in which to record command history'],
108
- ['save' , 1, 'Set saving of the history record on exit' ],
109
- ['size' , 1, 'Set the size of the command history' ]
110
- ].map do |name, min, help|
111
- Subcmd.new(name, min, help)
112
- end unless defined?(SetHistorySubcommands)
113
-
114
99
  self.allow_in_control = true
115
100
 
116
101
  def regexp
@@ -17,129 +17,60 @@ module Byebug
17
17
  else
18
18
  args = ''
19
19
  end
20
- return "Argument list to give program being debugged when it is started is \"#{args}\"."
20
+ "Argument list to give program being debugged when it is started is \"#{args}\"."
21
21
  when /^autolist$/
22
- on_off = Command.settings[:autolist] > 0
23
- return "autolist is #{show_onoff(on_off)}."
24
- when /^autoeval$/
25
- on_off = Command.settings[:autoeval]
26
- return "autoeval is #{show_onoff(on_off)}."
27
- when /^autoreload$/
28
- on_off = Command.settings[:autoreload]
29
- return "autoreload is #{show_onoff(on_off)}."
22
+ "autolist is #{show_onoff(Command.settings[:autolist] > 0)}."
30
23
  when /^autoirb$/
31
- on_off = Command.settings[:autoirb] > 0
32
- return "autoirb is #{show_onoff(on_off)}."
33
- when /^basename$/
34
- on_off = Command.settings[:basename]
35
- return "basename is #{show_onoff(on_off)}."
24
+ "autoirb is #{show_onoff(Command.settings[:autoirb] > 0)}."
25
+ when /^autosave$/
26
+ "Saving history is #{show_onoff(Command.settings[:autosave])}."
36
27
  when /^callstyle$/
37
- style = Command.settings[:callstyle]
38
- return "Frame call-display style is #{style}."
28
+ "Frame call-display style is #{Command.settings[:callstyle]}."
39
29
  when /^commands(:?\s+(\d+))?$/
40
- if @state.interface.readline_support?
41
- s = '';
30
+ if Command.settings[:autosave]
31
+ history = Byebug::History
42
32
  args = @match[1].split
43
33
  if args[1]
44
- first_line = args[1].to_i - 4
45
- last_line = first_line + 10 - 1
46
- if first_line > Readline::HISTORY.length
47
- first_line = last_line = Readline::HISTORY.length
48
- elsif first_line <= 0
49
- first_line = 1
50
- end
51
- if last_line > Readline::HISTORY.length
52
- last_line = Readline::HISTORY.length
53
- end
54
- i = first_line
55
- commands = Readline::HISTORY.to_a[first_line..last_line]
56
- else
57
- if Readline::HISTORY.length > 10
58
- commands = Readline::HISTORY.to_a[-10..-1]
59
- i = Readline::HISTORY.length - 10
60
- else
61
- commands = Readline::HISTORY.to_a
62
- i = 1
63
- end
64
- end
65
- commands.each do |cmd|
66
- s += ("%5d %s\n" % [i, cmd])
67
- i += 1
34
+ size = get_int(args[1], 'show commands', 1, history.max_size)
68
35
  end
36
+ size ? history.to_s(size) : history.to_s
69
37
  else
70
- s='No readline support'
38
+ 'Not currently saving history. Enable it with "set autosave"'
71
39
  end
72
- return s
73
40
  when /^testing$/
74
- on_off = Command.settings[:testing]
75
- return "Currently testing byebug is #{show_onoff(on_off)}."
41
+ "Currently testing byebug is #{show_onoff(Command.settings[:testing])}."
76
42
  when /^forcestep$/
77
- on_off = Command.settings[:forcestep]
78
- return "force-stepping is #{show_onoff(on_off)}."
43
+ "force-stepping is #{show_onoff(Command.settings[:forcestep])}."
79
44
  when /^fullpath$/
80
- on_off = Command.settings[:fullpath]
81
- return "Displaying frame's full file names is #{show_onoff(on_off)}."
82
- when /^history(:?\s+(filename|save|size))?$/
83
- args = @match[1].split
84
- interface = @state.interface
85
- if args[1]
86
- show_save = show_size = show_filename = false
87
- prefix = false
88
- if args[1] == "save"
89
- show_save = true
90
- elsif args[1] == "size"
91
- show_size = true
92
- elsif args[1] == "filename"
93
- show_filename = true
94
- end
95
- else
96
- show_save = show_size = show_filename = true
97
- prefix = true
98
- end
99
- s = []
100
- if show_filename
101
- msg = "#{prefix ? 'filename:' : ''} The command history file is " \
102
- "#{interface.histfile.inspect}"
103
- s << msg
104
- end
105
- if show_save
106
- msg = (prefix ? "save: " : "") +
107
- "Saving of history save is #{show_onoff(interface.history_save)}."
108
- s << msg
109
- end
110
- if show_size
111
- msg = (prefix ? "size: " : "") +
112
- "Byebug history size is #{interface.history_length}"
113
- s << msg
114
- end
115
- return s.join("\n")
45
+ "Displaying frame's full file names is #{show_onoff(Command.settings[:fullpath])}."
46
+ when /^histfile$/
47
+ "The command history file is \"#{Byebug::History.file}\""
48
+ when /^histsize$/
49
+ "Byebug history's maximum size is #{Byebug::History.max_size}"
116
50
  when /^linetrace$/
117
- on_off = Byebug.tracing?
118
- return "line tracing is #{show_onoff(on_off)}."
51
+ "line tracing is #{show_onoff(Byebug.tracing?)}."
119
52
  when /^linetrace_plus$/
120
53
  if Command.settings[:linetrace_plus]
121
- return "line tracing style is every line."
54
+ 'line tracing style is every line.'
122
55
  else
123
- return "line tracing style is different consecutive lines."
56
+ 'line tracing style is different consecutive lines.'
124
57
  end
125
58
  when /^listsize$/
126
- listlines = Command.settings[:listsize]
127
- return "Number of source lines to list is #{listlines}."
59
+ "Number of source lines to list is #{Command.settings[:listsize]}."
128
60
  when /^post_mortem$/
129
- on_off = Byebug.post_mortem?
130
- return "post-mortem mode is #{show_onoff(on_off)}"
61
+ "Post-mortem mode is #{show_onoff(Byebug.post_mortem?)}"
131
62
  when /^stack_on_error$/
132
- on_off = Command.settings[:stack_on_error]
133
- return "Displaying stack trace is #{show_onoff(on_off)}."
63
+ "Displaying stack trace is #{show_onoff(Command.settings[:stack_on_error])}."
134
64
  when /^verbose$/
135
- on_off = Byebug.verbose
136
- return "Verbose output of TracePoint API events is #{show_onoff(on_off)}."
65
+ "Verbose output of TracePoint API events is #{show_onoff(Byebug.verbose)}."
137
66
  when /^version$/
138
- return "Byebug #{Byebug::VERSION}"
67
+ "Byebug #{Byebug::VERSION}"
139
68
  when /^width$/
140
- return "width is #{Command.settings[:width]}."
69
+ "Width is #{Command.settings[:width]}."
70
+ when /^autoeval|autoreload|basename$/x
71
+ "#{setting_name} is #{show_onoff(Command.settings[setting_name.to_sym])}."
141
72
  else
142
- return "Unknown show subcommand #{setting_name}."
73
+ "Unknown show subcommand #{setting_name}."
143
74
  end
144
75
  end
145
76
  end
@@ -150,12 +81,14 @@ module Byebug
150
81
  Subcommands = [
151
82
  ['args' , 2 , 'Show argument list to the program being ' \
152
83
  'debugged when it is started' ],
153
- ['autoeval' , 4 , 'Show whether unrecognized commands are ' \
84
+ ['autoeval' , 5 , 'Show whether unrecognized commands are ' \
154
85
  'evaluated' ],
155
- ['autolist' , 4 , 'Show whether "list" command is run on stopping' ],
156
- ['autoirb' , 4 , 'Show whether IRB is invoked on stopping' ],
157
- ['autoreload' , 4 , 'Show whether source code is reloaded when ' \
86
+ ['autolist' , 5 , 'Show whether "list" command is run on stopping' ],
87
+ ['autoirb' , 5 , 'Show whether IRB is invoked on stopping' ],
88
+ ['autoreload' , 5 , 'Show whether source code is reloaded when ' \
158
89
  'changed' ],
90
+ ['autosave' , 5 , 'Show whether command history is ' \
91
+ 'automatically saved on exit' ],
159
92
  ['basename' , 1 , 'Show whether basename is used when reporting' \
160
93
  ' files' ],
161
94
  ['callstyle' , 2 , 'Show parameter style used when showing call' \
@@ -165,7 +98,9 @@ module Byebug
165
98
  ['forcestep' , 1 , 'Show whether "next/step" commands are set to' \
166
99
  ' always move to a line' ],
167
100
  ['fullpath' , 2 , 'Show whether full paths are displayed in frames'],
168
- ['history' , 2 , 'Show command history configurations. ' ],
101
+ ['histfile' , 5 , 'File where byebug save history of commands' ],
102
+ ['histsize' , 5 , 'Maximum number of commands stored in ' \
103
+ 'byebug\'s history' ],
169
104
  ['linetrace' , 3 , 'Show line execution tracing status' ],
170
105
  ['linetrace_plus', 10, 'Show whether different consecutive lines are' \
171
106
  ' shown in tracing' ],
@@ -183,14 +118,6 @@ module Byebug
183
118
  Subcmd.new(name, min, help)
184
119
  end unless defined?(Subcommands)
185
120
 
186
- ShowHistorySubcommands = [
187
- ['filename', 1, 'Show the filename in which to record command history' ],
188
- ['save' , 1, 'Show whether history record should be saved on exit' ],
189
- ['size' , 1, 'Show the size of the command history' ]
190
- ].map do |name, min, help|
191
- Subcmd.new(name, min, help)
192
- end unless defined?(SetHistorySubcommands)
193
-
194
121
  self.allow_in_control = true
195
122
 
196
123
  def regexp
@@ -18,7 +18,6 @@ module Byebug
18
18
  # Implements byebug "next" command.
19
19
  class NextCommand < Command
20
20
  self.allow_in_post_mortem = false
21
- self.need_context = true
22
21
 
23
22
  def regexp
24
23
  /^\s* n(?:ext)?([+-])? (?:\s+(\S+))? \s*$/x
@@ -48,7 +47,6 @@ module Byebug
48
47
  # Implements byebug "step" command.
49
48
  class StepCommand < Command
50
49
  self.allow_in_post_mortem = false
51
- self.need_context = true
52
50
 
53
51
  def regexp
54
52
  /^\s* s(?:tep)?([+-]) ?(?:\s+(\S+))? \s*$/x
@@ -90,8 +90,6 @@ module Byebug
90
90
  end
91
91
 
92
92
  class ThreadCurrentCommand < Command
93
- self.need_context = true
94
-
95
93
  def regexp
96
94
  /^\s* th(?:read)? \s+ (?:cur(?:rent)?)? \s*$/x
97
95
  end
@@ -114,7 +112,6 @@ module Byebug
114
112
  class ThreadStopCommand < Command
115
113
  self.allow_in_control = true
116
114
  self.allow_in_post_mortem = false
117
- self.need_context = true
118
115
 
119
116
  def regexp
120
117
  /^\s* th(?:read)? \s+ stop \s* (\S*) \s*$/x
@@ -141,7 +138,6 @@ module Byebug
141
138
  class ThreadResumeCommand < Command
142
139
  self.allow_in_control = true
143
140
  self.allow_in_post_mortem = false
144
- self.need_context = true
145
141
 
146
142
  def regexp
147
143
  /^\s* th(?:read)? \s+ resume \s* (\S*) \s*$/x
@@ -172,7 +168,6 @@ module Byebug
172
168
  class ThreadSwitchCommand < Command
173
169
  self.allow_in_control = true
174
170
  self.allow_in_post_mortem = false
175
- self.need_context = true
176
171
 
177
172
  def regexp
178
173
  /^\s* th(?:read)? \s+ (?:sw(?:itch)?\s+)? (\S+) \s*$/x
@@ -19,7 +19,7 @@ module Byebug
19
19
  if @match[3] && @match[3] !~ /(:?no)?stop/
20
20
  errmsg "expecting \"stop\" or \"nostop\"; got \"#{@match[3]}\"\n"
21
21
  else
22
- dbg_cmd = (@match[3] && @match[3] !~ /nostop/) ? 'byebug(1,0)' : ''
22
+ dbg_cmd = (@match[3] && @match[3] !~ /nostop/) ? 'byebug(1, false)' : ''
23
23
  end
24
24
  eval("trace_var(:\"\$#{varname}\") do |val|
25
25
  print \"traced global variable '#{varname}' has value '\#{val}'\"\n
@@ -27,7 +27,7 @@ module Byebug
27
27
  end
28
28
 
29
29
  # Implements byebug's 'var class' command
30
- class VarClassVarCommand < Command
30
+ class VarClassCommand < Command
31
31
  def regexp
32
32
  /^\s* v(?:ar)? \s+ cl(?:ass)? \s*/x
33
33
  end
@@ -3,24 +3,20 @@ module Byebug
3
3
  class Context
4
4
 
5
5
  class << self
6
- def stack_size
6
+ def stack_size(byebug_frames = false)
7
7
  if backtrace = Thread.current.backtrace_locations(0)
8
- backtrace.drop_while { |l| !ignored(l.path) }
9
- .drop_while { |l| ignored(l.path) }
10
- .take_while { |l| !ignored(l.path) }
11
- .size
8
+ unless byebug_frames
9
+ backtrace = backtrace.drop_while { |l| !ignored(l.path) }
10
+ .drop_while { |l| ignored(l.path) }
11
+ .take_while { |l| !ignored(l.path) }
12
+ end
13
+ backtrace.size
12
14
  else
13
- print 'No backtrace available!!'
15
+ print 'WARNING: No backtrace available!!'
14
16
  0
15
17
  end
16
18
  end
17
19
 
18
- def real_stack_size
19
- if backtrace = Thread.current.backtrace_locations(0)
20
- backtrace.size
21
- end
22
- end
23
-
24
20
  def ignored(path)
25
21
  IGNORED_FILES.include?(path)
26
22
  end
@@ -61,7 +61,7 @@ module Byebug
61
61
  # Return true if code is syntactically correct for Ruby.
62
62
  def syntax_valid?(code)
63
63
  eval("BEGIN {return true}\n#{code}", nil, "", 0)
64
- rescue Exception
64
+ rescue SyntaxError
65
65
  false
66
66
  end
67
67
 
@@ -0,0 +1,46 @@
1
+ require 'readline'
2
+
3
+ module Byebug
4
+ class History
5
+ DEFAULT_FILE = File.expand_path("#{ENV['HOME']||'.'}/.byebug_hist")
6
+ DEFAULT_MAX_SIZE = 256
7
+
8
+ @file = DEFAULT_FILE
9
+ @max_size = DEFAULT_MAX_SIZE
10
+
11
+ class << self
12
+ attr_accessor :file, :max_size
13
+
14
+ def load
15
+ open(@file, 'r') do |file|
16
+ file.each do |line|
17
+ line.chomp!
18
+ Readline::HISTORY << line
19
+ end
20
+ end if File.exist?(@file)
21
+ end
22
+
23
+ def save
24
+ open(@file, 'w') do |file|
25
+ Readline::HISTORY.to_a.last(@max_size).each do |line|
26
+ file.puts line unless line.strip.empty?
27
+ end
28
+ end
29
+ end
30
+
31
+ def to_s(size = @max_size)
32
+ n_entries = Readline::HISTORY.length < size ? Readline::HISTORY.length : size
33
+
34
+ first = Readline::HISTORY.length - n_entries
35
+ commands = Readline::HISTORY.to_a.last(n_entries)
36
+
37
+ s = ''
38
+ commands.each_with_index do |command, index|
39
+ s += ("%5d %s\n" % [first + index + 1, command])
40
+ end
41
+
42
+ return s
43
+ end
44
+ end
45
+ end
46
+ end