byebug 3.0.0 → 3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/GUIDE.md +2 -2
- data/LICENSE +3 -3
- data/README.md +5 -4
- data/byebug.gemspec +1 -1
- data/ext/byebug/byebug.c +20 -19
- data/lib/byebug.rb +2 -53
- data/lib/byebug/command.rb +9 -109
- data/lib/byebug/commands/breakpoints.rb +1 -1
- data/lib/byebug/commands/control.rb +20 -21
- data/lib/byebug/commands/display.rb +2 -3
- data/lib/byebug/commands/eval.rb +6 -16
- data/lib/byebug/commands/finish.rb +1 -1
- data/lib/byebug/commands/frame.rb +9 -9
- data/lib/byebug/commands/help.rb +2 -3
- data/lib/byebug/commands/history.rb +28 -0
- data/lib/byebug/commands/info.rb +3 -3
- data/lib/byebug/commands/list.rb +2 -13
- data/lib/byebug/commands/method.rb +5 -45
- data/lib/byebug/commands/reload.rb +1 -12
- data/lib/byebug/commands/repl.rb +6 -15
- data/lib/byebug/commands/save.rb +2 -7
- data/lib/byebug/commands/set.rb +45 -116
- data/lib/byebug/commands/show.rb +22 -126
- data/lib/byebug/commands/stepping.rb +1 -1
- data/lib/byebug/commands/trace.rb +14 -25
- data/lib/byebug/commands/variables.rb +3 -41
- data/lib/byebug/helper.rb +11 -42
- data/lib/byebug/history.rb +5 -13
- data/lib/byebug/processors/command_processor.rb +6 -6
- data/lib/byebug/setting.rb +82 -0
- data/lib/byebug/settings/autoeval.rb +20 -0
- data/lib/byebug/settings/autoirb.rb +19 -0
- data/lib/byebug/settings/autolist.rb +19 -0
- data/lib/byebug/settings/autoreload.rb +11 -0
- data/lib/byebug/settings/autosave.rb +11 -0
- data/lib/byebug/settings/basename.rb +7 -0
- data/lib/byebug/settings/callstyle.rb +15 -0
- data/lib/byebug/settings/forcestep.rb +11 -0
- data/lib/byebug/settings/fullpath.rb +11 -0
- data/lib/byebug/settings/histfile.rb +16 -0
- data/lib/byebug/settings/histsize.rb +18 -0
- data/lib/byebug/settings/linetrace.rb +15 -0
- data/lib/byebug/settings/listsize.rb +15 -0
- data/lib/byebug/settings/post_mortem.rb +15 -0
- data/lib/byebug/settings/stack_on_error.rb +7 -0
- data/lib/byebug/settings/testing.rb +7 -0
- data/lib/byebug/settings/tracing_plus.rb +7 -0
- data/lib/byebug/settings/verbose.rb +7 -0
- data/lib/byebug/settings/width.rb +29 -0
- data/lib/byebug/version.rb +1 -1
- data/test/breakpoints_test.rb +345 -324
- data/test/conditions_test.rb +61 -48
- data/test/continue_test.rb +38 -27
- data/test/debugger_alias_test.rb +5 -3
- data/test/display_test.rb +103 -92
- data/test/edit_test.rb +42 -34
- data/test/eval_test.rb +91 -75
- data/test/finish_test.rb +51 -40
- data/test/frame_test.rb +197 -184
- data/test/help_test.rb +47 -38
- data/test/history_test.rb +54 -0
- data/test/info_test.rb +306 -293
- data/test/interrupt_test.rb +44 -38
- data/test/kill_test.rb +40 -31
- data/test/list_test.rb +166 -133
- data/test/method_test.rb +67 -60
- data/test/post_mortem_test.rb +56 -48
- data/test/quit_test.rb +44 -35
- data/test/reload_test.rb +36 -24
- data/test/repl_test.rb +57 -47
- data/test/restart_test.rb +56 -69
- data/test/save_test.rb +62 -53
- data/test/set_test.rb +140 -118
- data/test/show_test.rb +68 -201
- data/test/source_test.rb +39 -29
- data/test/stepping_test.rb +163 -136
- data/test/support/test_dsl.rb +9 -11
- data/test/test_helper.rb +2 -7
- data/test/thread_test.rb +121 -107
- data/test/trace_test.rb +86 -83
- data/test/variables_test.rb +104 -98
- metadata +27 -86
- data/test/examples/breakpoint.rb +0 -6
- data/test/examples/breakpoint_deep.rb +0 -4
- data/test/examples/conditions.rb +0 -4
- data/test/examples/continue.rb +0 -5
- data/test/examples/display.rb +0 -5
- data/test/examples/edit.rb +0 -4
- data/test/examples/eval.rb +0 -4
- data/test/examples/finish.rb +0 -3
- data/test/examples/frame.rb +0 -4
- data/test/examples/frame_deep.rb +0 -1
- data/test/examples/gcd.rb +0 -15
- data/test/examples/hanoi.rb +0 -34
- data/test/examples/help.rb +0 -1
- data/test/examples/info.rb +0 -6
- data/test/examples/info2.rb +0 -3
- data/test/examples/interrupt.rb +0 -8
- data/test/examples/kill.rb +0 -2
- data/test/examples/list.rb +0 -23
- data/test/examples/method.rb +0 -4
- data/test/examples/post_mortem.rb +0 -4
- data/test/examples/primes.rb +0 -25
- data/test/examples/quit.rb +0 -2
- data/test/examples/reload.rb +0 -6
- data/test/examples/repl.rb +0 -6
- data/test/examples/restart.rb +0 -6
- data/test/examples/save.rb +0 -3
- data/test/examples/set.rb +0 -3
- data/test/examples/settings.rb +0 -1
- data/test/examples/show.rb +0 -1
- data/test/examples/source.rb +0 -3
- data/test/examples/stepping.rb +0 -8
- data/test/examples/stepping_raise_from_c_method.rb +0 -3
- data/test/examples/stepping_raise_from_ruby_method.rb +0 -3
- data/test/examples/test-triangle.rb +0 -14
- data/test/examples/thread.rb +0 -5
- data/test/examples/tmate.rb +0 -10
- data/test/examples/trace.rb +0 -8
- data/test/examples/tri3.rb +0 -6
- data/test/examples/triangle.rb +0 -13
- data/test/examples/variables.rb +0 -4
- data/test/timeout_test.rb +0 -9
data/lib/byebug/helper.rb
CHANGED
@@ -1,69 +1,38 @@
|
|
1
1
|
module Byebug
|
2
|
-
|
3
2
|
module ParseFunctions
|
4
3
|
Position_regexp = '(?:(\d+)|(.+?)[:.#]([^.:\s]+))'
|
5
4
|
|
6
5
|
# Parse 'str' of command 'cmd' as an integer between
|
7
6
|
# min and max. If either min or max is nil, that
|
8
7
|
# value has no bound.
|
9
|
-
def get_int(str, cmd, min=nil, max=nil, default=1)
|
10
|
-
|
8
|
+
def get_int(str, cmd, min = nil, max = nil, default = 1)
|
9
|
+
unless str
|
10
|
+
return default if default
|
11
|
+
print "You need to specify an argument for \"#{cmd}\"\n"
|
12
|
+
return nil
|
13
|
+
end
|
14
|
+
|
11
15
|
begin
|
12
16
|
int = Integer(str)
|
13
17
|
if min and int < min
|
14
|
-
print "\"#{cmd}\" argument \"#{str}\" needs to be at least #{min}
|
18
|
+
print "\"#{cmd}\" argument \"#{str}\" needs to be at least #{min}\n"
|
15
19
|
return nil
|
16
20
|
elsif max and int > max
|
17
|
-
print "\"#{cmd}\" argument \"#{str}\" needs to be at most #{max}
|
21
|
+
print "\"#{cmd}\" argument \"#{str}\" needs to be at most #{max}\n"
|
18
22
|
return nil
|
19
23
|
end
|
20
24
|
return int
|
21
25
|
rescue
|
22
|
-
print "\"#{cmd}\" argument \"#{str}\" needs to be a number
|
26
|
+
print "\"#{cmd}\" argument \"#{str}\" needs to be a number\n"
|
23
27
|
return nil
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
# Return true if arg is 'on' or 1 and false arg is 'off' or 0.
|
28
|
-
# Any other value raises RuntimeError.
|
29
|
-
def get_onoff(arg, default=nil, print_error=true)
|
30
|
-
if arg.nil? or arg == ''
|
31
|
-
if default.nil?
|
32
|
-
if print_error
|
33
|
-
print "Expecting 'on', 1, 'off', or 0. Got nothing.\n"
|
34
|
-
raise RuntimeError
|
35
|
-
end
|
36
|
-
return default
|
37
|
-
end
|
38
|
-
end
|
39
|
-
case arg.downcase
|
40
|
-
when '1', 'on'
|
41
|
-
return true
|
42
|
-
when '0', 'off'
|
43
|
-
return false
|
44
|
-
else
|
45
|
-
if print_error
|
46
|
-
print "Expecting 'on', 1, 'off', or 0. Got: #{arg.to_s}.\n"
|
47
|
-
raise RuntimeError
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Return 'on' or 'off' for supplied parameter. The parameter should
|
53
|
-
# be true, false or nil.
|
54
|
-
def show_onoff(bool)
|
55
|
-
if not [TrueClass, FalseClass, NilClass].member?(bool.class)
|
56
|
-
return "??"
|
57
|
-
end
|
58
|
-
return bool ? 'on' : 'off'
|
59
|
-
end
|
60
|
-
|
61
31
|
# Return true if code is syntactically correct for Ruby.
|
62
32
|
def syntax_valid?(code)
|
63
|
-
eval("BEGIN {return true}\n#{code}", nil,
|
33
|
+
eval("BEGIN {return true}\n#{code}", nil, '', 0)
|
64
34
|
rescue SyntaxError
|
65
35
|
false
|
66
36
|
end
|
67
|
-
|
68
37
|
end
|
69
38
|
end
|
data/lib/byebug/history.rb
CHANGED
@@ -2,33 +2,25 @@ require 'readline'
|
|
2
2
|
|
3
3
|
module Byebug
|
4
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
5
|
class << self
|
12
|
-
attr_accessor :file, :max_size
|
13
|
-
|
14
6
|
def load
|
15
|
-
open(
|
7
|
+
open(Setting[:histfile], 'r') do |file|
|
16
8
|
file.each do |line|
|
17
9
|
line.chomp!
|
18
10
|
Readline::HISTORY << line
|
19
11
|
end
|
20
|
-
end if File.exist?(
|
12
|
+
end if File.exist?(Setting[:histfile])
|
21
13
|
end
|
22
14
|
|
23
15
|
def save
|
24
|
-
open(
|
25
|
-
Readline::HISTORY.to_a.last(
|
16
|
+
open(Setting[:histfile], 'w') do |file|
|
17
|
+
Readline::HISTORY.to_a.last(Setting[:histsize]).each do |line|
|
26
18
|
file.puts line unless line.strip.empty?
|
27
19
|
end
|
28
20
|
end
|
29
21
|
end
|
30
22
|
|
31
|
-
def to_s(size =
|
23
|
+
def to_s(size = Setting[:histsize])
|
32
24
|
n_entries = Readline::HISTORY.length < size ? Readline::HISTORY.length : size
|
33
25
|
|
34
26
|
first = Readline::HISTORY.length - n_entries
|
@@ -33,7 +33,7 @@ module Byebug
|
|
33
33
|
return filename if ['(irb)', '-e'].include?(filename)
|
34
34
|
|
35
35
|
# For now we want resolved filenames
|
36
|
-
if
|
36
|
+
if Setting[:basename]
|
37
37
|
File.basename(filename)
|
38
38
|
else
|
39
39
|
Pathname.new(filename).cleanpath.to_s
|
@@ -75,7 +75,7 @@ module Byebug
|
|
75
75
|
protect :at_catchpoint
|
76
76
|
|
77
77
|
def at_tracing(context, file, line)
|
78
|
-
if file != @last_file || line != @last_line ||
|
78
|
+
if file != @last_file || line != @last_line || Setting[:tracing_plus]
|
79
79
|
@last_file, @last_line = file, line
|
80
80
|
print "Tracing: #{CommandProcessor.canonic_file(file)}:#{line} " \
|
81
81
|
"#{Byebug.line_at(file,line)}\n"
|
@@ -85,7 +85,7 @@ module Byebug
|
|
85
85
|
protect :at_tracing
|
86
86
|
|
87
87
|
def at_line(context, file, line)
|
88
|
-
Byebug.source_reload if
|
88
|
+
Byebug.source_reload if Setting[:autoreload]
|
89
89
|
process_commands(context, file, line)
|
90
90
|
end
|
91
91
|
protect :at_line
|
@@ -117,7 +117,7 @@ module Byebug
|
|
117
117
|
state = State.new(cmds, context, @display, file, @interface, line)
|
118
118
|
|
119
119
|
# Change default when in irb or code included in command line
|
120
|
-
|
120
|
+
Setting[:autolist] = false if ['(irb)', '-e'].include?(file)
|
121
121
|
|
122
122
|
# Bind commands to the current state.
|
123
123
|
commands = cmds.map { |cmd| cmd.new(state) }
|
@@ -154,14 +154,14 @@ module Byebug
|
|
154
154
|
def process_commands(context, file, line)
|
155
155
|
state, commands = always_run(context, file, line, 1)
|
156
156
|
|
157
|
-
if
|
157
|
+
if Setting[:testing]
|
158
158
|
Thread.current.thread_variable_set('state', state)
|
159
159
|
else
|
160
160
|
Thread.current.thread_variable_set('state', nil)
|
161
161
|
end
|
162
162
|
|
163
163
|
preloop(commands, context)
|
164
|
-
print state.location if
|
164
|
+
print state.location if Setting[:autolist] == 0
|
165
165
|
|
166
166
|
while !state.proceed?
|
167
167
|
input = @interface.command_queue.empty? ?
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Byebug
|
2
|
+
class Setting
|
3
|
+
attr_accessor :value
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@value = false
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.settings
|
10
|
+
@settings ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.[](name)
|
14
|
+
settings[name].value
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.[]=(name, value)
|
18
|
+
settings[name].value = value
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.boolean?(name)
|
22
|
+
key = (name =~ /^no/ ? name[2..-1] : name).to_sym
|
23
|
+
settings[key].boolean?
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.integer?(name)
|
27
|
+
settings[name.to_sym].integer?
|
28
|
+
end
|
29
|
+
|
30
|
+
def boolean?
|
31
|
+
[true, false].include?(value)
|
32
|
+
end
|
33
|
+
|
34
|
+
def integer?
|
35
|
+
integer = Integer(value) rescue nil
|
36
|
+
integer ? true : false
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.exists?(name)
|
40
|
+
key = (name =~ /^no/ ? name[2..-1] : name).to_sym
|
41
|
+
boolean?(key) ? settings.include?(key) : settings.include?(name.to_sym)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.load
|
45
|
+
Dir.glob(File.expand_path('../settings/*.rb', __FILE__)).each do |file|
|
46
|
+
require file
|
47
|
+
end
|
48
|
+
Byebug.constants.grep(/[a-z]Setting/).map do |name|
|
49
|
+
setting = Byebug.const_get(name).new
|
50
|
+
settings[setting.to_sym] = setting
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.find(shortcut)
|
55
|
+
abbr = shortcut =~ /^no/ ? shortcut[2..-1] : shortcut
|
56
|
+
matches = settings.select do |key, value|
|
57
|
+
value.boolean? ? key =~ /#{abbr}/ : key =~ /#{shortcut}/
|
58
|
+
end
|
59
|
+
matches.size == 1 ? matches.keys.first : nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.format()
|
63
|
+
output = "List of settings supported in byebug:\n"
|
64
|
+
width = settings.keys.max_by(&:size).size
|
65
|
+
settings.values.each do |setting|
|
66
|
+
output << sprintf("%-#{width}s -- %s\n", setting.to_sym, setting.help)
|
67
|
+
end
|
68
|
+
output
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_sym
|
72
|
+
name = self.class.name.gsub(/^Byebug::/, '').gsub(/Setting$/, '')
|
73
|
+
name.gsub(/(.)([A-Z])/,'\1_\2').downcase.to_sym
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_s
|
77
|
+
"#{to_sym} is #{value ? 'on' : 'off'}\n"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
Setting.load
|
82
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Byebug
|
2
|
+
class AutoevalSetting < Setting
|
3
|
+
def initialize
|
4
|
+
EvalCommand.unknown = true
|
5
|
+
end
|
6
|
+
|
7
|
+
def help
|
8
|
+
'If true, byebug will evaluate every unrecognized command. If false, ' \
|
9
|
+
'need to use the `eval` command to evaluate stuff'
|
10
|
+
end
|
11
|
+
|
12
|
+
def value=(v)
|
13
|
+
EvalCommand.unknown = v
|
14
|
+
end
|
15
|
+
|
16
|
+
def value
|
17
|
+
EvalCommand.unknown
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Byebug
|
2
|
+
class AutoirbSetting < Setting
|
3
|
+
def initialize
|
4
|
+
IrbCommand.always_run = 0
|
5
|
+
end
|
6
|
+
|
7
|
+
def help
|
8
|
+
'Invoke IRB on every stop'
|
9
|
+
end
|
10
|
+
|
11
|
+
def value=(v)
|
12
|
+
IrbCommand.always_run = v ? 1 : 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
IrbCommand.always_run == 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Byebug
|
2
|
+
class AutolistSetting < Setting
|
3
|
+
def initialize
|
4
|
+
ListCommand.always_run = 1
|
5
|
+
end
|
6
|
+
|
7
|
+
def help
|
8
|
+
'If true, `list` command is run everytime byebug stops'
|
9
|
+
end
|
10
|
+
|
11
|
+
def value=(v)
|
12
|
+
ListCommand.always_run = v ? 1 : 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def value
|
16
|
+
ListCommand.always_run == 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Byebug
|
2
|
+
class HistfileSetting < Setting
|
3
|
+
def initialize
|
4
|
+
@value = File.expand_path("#{ENV['HOME']||'.'}/.byebug_hist")
|
5
|
+
end
|
6
|
+
|
7
|
+
def help
|
8
|
+
"Customize file where history is loaded from and saved to. By default, " \
|
9
|
+
"~/.byebug_hist"
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"The command history file is #{value}\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Byebug
|
2
|
+
class HistsizeSetting < Setting
|
3
|
+
DEFAULT = 256
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@value = DEFAULT
|
7
|
+
end
|
8
|
+
|
9
|
+
def help
|
10
|
+
"Customize maximum number of commands that can be stored in byebug's " \
|
11
|
+
"history record. By default, #{DEFAULT}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"Maximum size of byebug's command history is #{value}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|