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