byebug 3.2.0 → 3.3.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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +125 -99
  4. data/CONTRIBUTING.md +4 -6
  5. data/GUIDE.md +42 -20
  6. data/Gemfile +5 -3
  7. data/README.md +2 -3
  8. data/Rakefile +11 -7
  9. data/bin/byebug +2 -252
  10. data/byebug.gemspec +7 -4
  11. data/ext/byebug/byebug.c +17 -18
  12. data/ext/byebug/byebug.h +4 -5
  13. data/ext/byebug/context.c +37 -39
  14. data/ext/byebug/threads.c +39 -18
  15. data/lib/byebug.rb +2 -110
  16. data/lib/byebug/attacher.rb +23 -0
  17. data/lib/byebug/breakpoint.rb +60 -0
  18. data/lib/byebug/command.rb +62 -70
  19. data/lib/byebug/commands/break.rb +24 -24
  20. data/lib/byebug/commands/catchpoint.rb +18 -10
  21. data/lib/byebug/commands/condition.rb +18 -17
  22. data/lib/byebug/commands/continue.rb +17 -9
  23. data/lib/byebug/commands/delete.rb +19 -13
  24. data/lib/byebug/commands/display.rb +19 -53
  25. data/lib/byebug/commands/edit.rb +7 -4
  26. data/lib/byebug/commands/enable_disable.rb +130 -0
  27. data/lib/byebug/commands/eval.rb +40 -22
  28. data/lib/byebug/commands/finish.rb +13 -4
  29. data/lib/byebug/commands/frame.rb +65 -45
  30. data/lib/byebug/commands/help.rb +17 -18
  31. data/lib/byebug/commands/history.rb +14 -8
  32. data/lib/byebug/commands/info.rb +160 -182
  33. data/lib/byebug/commands/interrupt.rb +4 -1
  34. data/lib/byebug/commands/irb.rb +30 -0
  35. data/lib/byebug/commands/kill.rb +7 -8
  36. data/lib/byebug/commands/list.rb +71 -66
  37. data/lib/byebug/commands/method.rb +14 -6
  38. data/lib/byebug/commands/pry.rb +35 -0
  39. data/lib/byebug/commands/quit.rb +9 -6
  40. data/lib/byebug/commands/reload.rb +5 -2
  41. data/lib/byebug/commands/restart.rb +13 -9
  42. data/lib/byebug/commands/save.rb +17 -17
  43. data/lib/byebug/commands/set.rb +16 -15
  44. data/lib/byebug/commands/show.rb +10 -11
  45. data/lib/byebug/commands/source.rb +11 -5
  46. data/lib/byebug/commands/stepping.rb +38 -24
  47. data/lib/byebug/commands/threads.rb +45 -31
  48. data/lib/byebug/commands/trace.rb +22 -9
  49. data/lib/byebug/commands/undisplay.rb +45 -0
  50. data/lib/byebug/commands/variables.rb +83 -27
  51. data/lib/byebug/context.rb +25 -22
  52. data/lib/byebug/core.rb +82 -0
  53. data/lib/byebug/helper.rb +37 -28
  54. data/lib/byebug/history.rb +8 -4
  55. data/lib/byebug/interface.rb +12 -17
  56. data/lib/byebug/interfaces/local_interface.rb +11 -8
  57. data/lib/byebug/interfaces/remote_interface.rb +11 -8
  58. data/lib/byebug/interfaces/script_interface.rb +9 -6
  59. data/lib/byebug/options.rb +46 -0
  60. data/lib/byebug/processor.rb +7 -1
  61. data/lib/byebug/processors/command_processor.rb +135 -125
  62. data/lib/byebug/processors/control_command_processor.rb +23 -23
  63. data/lib/byebug/remote.rb +17 -26
  64. data/lib/byebug/runner.rb +100 -0
  65. data/lib/byebug/setting.rb +33 -8
  66. data/lib/byebug/settings/autoeval.rb +5 -15
  67. data/lib/byebug/settings/autoirb.rb +4 -1
  68. data/lib/byebug/settings/autolist.rb +5 -2
  69. data/lib/byebug/settings/autoreload.rb +5 -2
  70. data/lib/byebug/settings/autosave.rb +6 -2
  71. data/lib/byebug/settings/basename.rb +7 -2
  72. data/lib/byebug/settings/callstyle.rb +4 -1
  73. data/lib/byebug/settings/forcestep.rb +6 -3
  74. data/lib/byebug/settings/fullpath.rb +5 -2
  75. data/lib/byebug/settings/histfile.rb +5 -3
  76. data/lib/byebug/settings/histsize.rb +5 -3
  77. data/lib/byebug/settings/linetrace.rb +4 -1
  78. data/lib/byebug/settings/listsize.rb +5 -1
  79. data/lib/byebug/settings/post_mortem.rb +21 -13
  80. data/lib/byebug/settings/stack_on_error.rb +6 -2
  81. data/lib/byebug/settings/testing.rb +6 -1
  82. data/lib/byebug/settings/tracing_plus.rb +5 -1
  83. data/lib/byebug/settings/verbose.rb +13 -2
  84. data/lib/byebug/settings/width.rb +4 -1
  85. data/lib/byebug/version.rb +1 -1
  86. data/test/{break_test.rb → commands/break_test.rb} +41 -53
  87. data/test/{condition_test.rb → commands/condition_test.rb} +14 -14
  88. data/test/{continue_test.rb → commands/continue_test.rb} +0 -0
  89. data/test/{delete_test.rb → commands/delete_test.rb} +2 -2
  90. data/test/commands/display_test.rb +37 -0
  91. data/test/{edit_test.rb → commands/edit_test.rb} +0 -0
  92. data/test/{eval_test.rb → commands/eval_test.rb} +1 -0
  93. data/test/{finish_test.rb → commands/finish_test.rb} +11 -1
  94. data/test/{frame_test.rb → commands/frame_test.rb} +12 -16
  95. data/test/{help_test.rb → commands/help_test.rb} +21 -4
  96. data/test/{history_test.rb → commands/history_test.rb} +0 -0
  97. data/test/{info_test.rb → commands/info_test.rb} +5 -55
  98. data/test/{interrupt_test.rb → commands/interrupt_test.rb} +0 -0
  99. data/test/commands/irb_test.rb +28 -0
  100. data/test/{kill_test.rb → commands/kill_test.rb} +1 -1
  101. data/test/{list_test.rb → commands/list_test.rb} +1 -1
  102. data/test/{method_test.rb → commands/method_test.rb} +0 -0
  103. data/test/{post_mortem_test.rb → commands/post_mortem_test.rb} +6 -10
  104. data/test/{pry_test.rb → commands/pry_test.rb} +4 -13
  105. data/test/{quit_test.rb → commands/quit_test.rb} +4 -4
  106. data/test/{reload_test.rb → commands/reload_test.rb} +0 -0
  107. data/test/{restart_test.rb → commands/restart_test.rb} +6 -0
  108. data/test/{save_test.rb → commands/save_test.rb} +2 -2
  109. data/test/{set_test.rb → commands/set_test.rb} +9 -2
  110. data/test/{show_test.rb → commands/show_test.rb} +1 -1
  111. data/test/{source_test.rb → commands/source_test.rb} +3 -3
  112. data/test/{stepping_test.rb → commands/stepping_test.rb} +44 -35
  113. data/test/{thread_test.rb → commands/thread_test.rb} +0 -0
  114. data/test/{trace_test.rb → commands/trace_test.rb} +0 -0
  115. data/test/{display_test.rb → commands/undisplay_test.rb} +7 -45
  116. data/test/{variables_test.rb → commands/variables_test.rb} +10 -1
  117. data/test/debugger_alias_test.rb +2 -2
  118. data/test/runner_test.rb +127 -0
  119. data/test/support/matchers.rb +27 -25
  120. data/test/support/test_interface.rb +9 -5
  121. data/test/support/utils.rb +96 -101
  122. data/test/test_helper.rb +32 -20
  123. metadata +93 -68
  124. data/lib/byebug/commands/enable.rb +0 -154
  125. data/lib/byebug/commands/repl.rb +0 -126
  126. data/test/irb_test.rb +0 -47
  127. data/test/support/breakpoint.rb +0 -13
@@ -1,32 +1,32 @@
1
1
  module Byebug
2
+ #
3
+ # Miscelaneous Utilities
4
+ #
2
5
  module ParseFunctions
3
- Position_regexp = '(?:(\d+)|(.+?)[:.#]([^.:\s]+))'
4
-
5
6
  #
6
7
  # Parse 'str' of command 'cmd' as an integer between min and max. If either
7
8
  # min or max is nil, that value has no bound.
8
9
  #
9
- def get_int(str, cmd, min = nil, max = nil, default = 1)
10
- unless str
11
- return default if default
12
- print "You need to specify an argument for \"#{cmd}\"\n"
13
- return nil
10
+ def get_int(str, cmd, min = nil, max = nil)
11
+ if str !~ /\A[0-9]+\z/
12
+ return nil, "\"#{cmd}\" argument \"#{str}\" needs to be a number"
14
13
  end
15
14
 
16
- begin
17
- int = Integer(str)
18
- if min and int < min
19
- print "\"#{cmd}\" argument \"#{str}\" needs to be at least #{min}\n"
20
- return nil
21
- elsif max and int > max
22
- print "\"#{cmd}\" argument \"#{str}\" needs to be at most #{max}\n"
23
- return nil
24
- end
25
- return int
26
- rescue
27
- print "\"#{cmd}\" argument \"#{str}\" needs to be a number\n"
28
- return nil
15
+ int = str.to_i
16
+ if min && int < min
17
+ return nil, "\"#{cmd}\" argument \"#{str}\" needs to be at least #{min}"
18
+ elsif max && int > max
19
+ return nil, "\"#{cmd}\" argument \"#{str}\" needs to be at most #{max}"
29
20
  end
21
+
22
+ int
23
+ end
24
+
25
+ #
26
+ # Fills SCRIPT_LINES__ entry for <filename> if not already filled.
27
+ #
28
+ def lines(filename)
29
+ SCRIPT_LINES__[filename] ||= File.readlines(filename)
30
30
  end
31
31
 
32
32
  #
@@ -35,21 +35,17 @@ module Byebug
35
35
  def get_lines(filename)
36
36
  return nil unless File.exist?(filename)
37
37
 
38
- unless lines = SCRIPT_LINES__[filename]
39
- lines = File.readlines(filename) rescue []
40
- SCRIPT_LINES__[filename] = lines
41
- end
42
-
43
- return lines
38
+ lines(filename)
44
39
  end
45
40
 
46
41
  #
47
42
  # Gets a single line in a source code file
48
43
  #
49
44
  def get_line(filename, lineno)
50
- return nil unless lines = get_lines(filename)
45
+ lines = get_lines(filename)
46
+ return nil unless lines
51
47
 
52
- return lines[lineno-1]
48
+ lines[lineno - 1]
53
49
  end
54
50
 
55
51
  #
@@ -60,5 +56,18 @@ module Byebug
60
56
  rescue SyntaxError
61
57
  false
62
58
  end
59
+
60
+ #
61
+ # Returns the number of steps specified in <str> as an integer or 1 if <str>
62
+ # is empty.
63
+ #
64
+ def parse_steps(str, cmd)
65
+ return 1 unless str
66
+
67
+ steps, err = get_int(str, cmd, 1)
68
+ return nil, err unless steps
69
+
70
+ steps
71
+ end
63
72
  end
64
73
  end
@@ -1,6 +1,9 @@
1
1
  require 'readline'
2
2
 
3
3
  module Byebug
4
+ #
5
+ # Handles byebug's history of commands.
6
+ #
4
7
  class History
5
8
  class << self
6
9
  def load
@@ -21,17 +24,18 @@ module Byebug
21
24
  end
22
25
 
23
26
  def to_s(size = Setting[:histsize])
24
- n_entries = Readline::HISTORY.length < size ? Readline::HISTORY.length : size
27
+ rl_size = Readline::HISTORY.length
28
+ n_entries = rl_size < size ? rl_size : size
25
29
 
26
- first = Readline::HISTORY.length - n_entries
30
+ first = rl_size - n_entries
27
31
  commands = Readline::HISTORY.to_a.last(n_entries)
28
32
 
29
33
  s = ''
30
34
  commands.each_with_index do |command, index|
31
- s += ("%5d %s\n" % [first + index + 1, command])
35
+ s += format("%5d %s\n", first + index + 1, command)
32
36
  end
33
37
 
34
- return s
38
+ s
35
39
  end
36
40
  end
37
41
  end
@@ -1,4 +1,12 @@
1
+ #
2
+ # Namespace for all of byebug's code
3
+ #
1
4
  module Byebug
5
+ #
6
+ # Main Interface class
7
+ #
8
+ # Contains common functionality to all implemented interfaces.
9
+ #
2
10
  class Interface
3
11
  attr_accessor :command_queue, :restart_file
4
12
 
@@ -6,25 +14,12 @@ module Byebug
6
14
  @command_queue, @restart_file = [], nil
7
15
  end
8
16
 
17
+ #
9
18
  # Common routine for reporting byebug error messages.
10
19
  # Derived classes may want to override this to capture output.
11
- def errmsg(*args)
12
- print '*** '
13
- print(*args)
14
- end
15
-
16
- def format(*args)
17
- if args.is_a?(Array)
18
- new_args = args.first
19
- new_args = new_args % args[1..-1] unless args[1..-1].empty?
20
- else
21
- new_args = args
22
- end
23
- new_args
24
- end
25
-
26
- def escape(msg)
27
- msg.gsub('%', '%%')
20
+ #
21
+ def errmsg(message)
22
+ print("*** #{message}\n")
28
23
  end
29
24
  end
30
25
 
@@ -1,6 +1,9 @@
1
1
  require 'byebug/history'
2
2
 
3
3
  module Byebug
4
+ #
5
+ # Interface class for standard byebug use.
6
+ #
4
7
  class LocalInterface < Interface
5
8
  attr_reader :history
6
9
 
@@ -17,8 +20,8 @@ module Byebug
17
20
  readline(prompt, false)
18
21
  end
19
22
 
20
- def print(*args)
21
- STDOUT.printf(escape(format(*args)))
23
+ def puts(*args)
24
+ STDOUT.puts(*args)
22
25
  end
23
26
 
24
27
  def close
@@ -27,11 +30,11 @@ module Byebug
27
30
 
28
31
  private
29
32
 
30
- def readline(prompt, hist)
31
- Readline::readline(prompt, hist)
32
- rescue Interrupt
33
- print "^C\n"
34
- retry
35
- end
33
+ def readline(prompt, hist)
34
+ Readline.readline(prompt, hist)
35
+ rescue Interrupt
36
+ puts '^C'
37
+ retry
38
+ end
36
39
  end
37
40
  end
@@ -1,6 +1,9 @@
1
1
  require 'byebug/history'
2
2
 
3
3
  module Byebug
4
+ #
5
+ # Interface class for remote use of byebug.
6
+ #
4
7
  class RemoteInterface < Interface
5
8
  attr_reader :history
6
9
 
@@ -23,17 +26,17 @@ module Byebug
23
26
  send_command "PROMPT #{prompt}"
24
27
  end
25
28
 
26
- def print(*args)
27
- @socket.printf(escape(format(*args)))
29
+ def puts(message)
30
+ @socket.puts(message)
28
31
  end
29
32
 
30
33
  private
31
34
 
32
- def send_command(msg)
33
- @socket.puts msg
34
- result = @socket.gets
35
- raise IOError unless result
36
- result.chomp
37
- end
35
+ def send_command(msg)
36
+ @socket.puts msg
37
+ result = @socket.gets
38
+ fail IOError unless result
39
+ result.chomp
40
+ end
38
41
  end
39
42
  end
@@ -1,13 +1,16 @@
1
1
  module Byebug
2
+ #
3
+ # Interface class for command execution from script files.
4
+ #
2
5
  class ScriptInterface < Interface
3
- def initialize(file, out, verbose=false)
6
+ def initialize(file, out, verbose = false)
4
7
  super()
5
8
  @file = file.respond_to?(:gets) ? file : open(file)
6
9
  @out, @verbose = out, verbose
7
10
  end
8
11
 
9
- def read_command(prompt)
10
- while result = @file.gets
12
+ def read_command(_prompt)
13
+ while (result = @file.gets)
11
14
  puts "# #{result}" if @verbose
12
15
  next if result =~ /^\s*#/
13
16
  next if result.strip.empty?
@@ -15,12 +18,12 @@ module Byebug
15
18
  end
16
19
  end
17
20
 
18
- def confirm(prompt)
21
+ def confirm(_prompt)
19
22
  'y'
20
23
  end
21
24
 
22
- def print(*args)
23
- @out.printf(*args)
25
+ def puts(message)
26
+ @out.printf(message)
24
27
  end
25
28
 
26
29
  def close
@@ -0,0 +1,46 @@
1
+ module Byebug
2
+ #
3
+ # Set of options that byebug's script accepts.
4
+ #
5
+ class Options
6
+ def self.parse
7
+ Slop.parse!(strict: true) do
8
+ banner <<-EOB.gsub(/^ {8}/, '')
9
+
10
+ byebug #{Byebug::VERSION}
11
+
12
+ Usage: byebug [options] <script.rb> -- <script.rb parameters>
13
+ EOB
14
+
15
+ on :d, :debug, 'Set $DEBUG=true' do
16
+ $DEBUG = true
17
+ end
18
+
19
+ on :I, :include=, 'Add to $LOAD_PATH', as: Array, delimiter: ':' do |l|
20
+ $LOAD_PATH.push(l).flatten!
21
+ end
22
+
23
+ on :q, :quit, 'Quit when script finishes', default: true
24
+
25
+ on :s, :stop, 'Stop when script is loaded', default: true
26
+
27
+ on :x, :rc, 'Run byebug initialization file', default: true
28
+
29
+ on :m, :'post-mortem', 'Run byebug in post-mortem mode', default: false
30
+
31
+ on :r, :require=, 'Require library before script' do |name|
32
+ require name
33
+ end
34
+
35
+ on :R, :remote=, '[HOST:]PORT for remote debugging',
36
+ as: Array, delimiter: ':', limit: 2
37
+
38
+ on :t, :trace, 'Turn on line tracing'
39
+
40
+ on :v, :version, 'Print program version'
41
+
42
+ on :h, :help, 'Display this message'
43
+ end
44
+ end
45
+ end
46
+ end
@@ -5,11 +5,17 @@ module Byebug
5
5
  attr_accessor :interface
6
6
 
7
7
  extend Forwardable
8
- def_delegators :@interface, :errmsg, :print
8
+ def_delegators :@interface, :errmsg, :puts
9
9
 
10
10
  def initialize(interface)
11
11
  @interface = interface
12
12
  end
13
+
14
+ def without_exceptions
15
+ yield
16
+ rescue
17
+ nil
18
+ end
13
19
  end
14
20
  end
15
21
 
@@ -1,4 +1,7 @@
1
1
  module Byebug
2
+ #
3
+ # Processes commands in regular mode
4
+ #
2
5
  class CommandProcessor < Processor
3
6
  attr_reader :display
4
7
 
@@ -41,7 +44,7 @@ module Byebug
41
44
 
42
45
  def self.protect(mname)
43
46
  alias_method "__#{mname}", mname
44
- module_eval <<-END, __FILE__, __LINE__+1
47
+ module_eval <<-END, __FILE__, __LINE__ + 1
45
48
  def #{mname}(*args)
46
49
  @mutex.synchronize do
47
50
  return unless @interface
@@ -52,24 +55,26 @@ module Byebug
52
55
  rescue SignalException
53
56
  raise
54
57
  rescue
55
- print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil
56
- print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil
58
+ without_exceptions do
59
+ puts "INTERNAL ERROR!!! #\{$!\}"
60
+ puts $!.backtrace.map{|l| "\t#\{l\}"}.join("\n")
61
+ end
57
62
  end
58
63
  END
59
64
  end
60
65
 
61
- def at_breakpoint(context, breakpoint)
66
+ def at_breakpoint(_context, breakpoint)
62
67
  n = Byebug.breakpoints.index(breakpoint) + 1
63
68
  file = self.class.canonic_file(breakpoint.source)
64
69
  line = breakpoint.pos
65
- print "Stopped by breakpoint #{n} at #{file}:#{line}\n"
70
+ puts "Stopped by breakpoint #{n} at #{file}:#{line}"
66
71
  end
67
72
  protect :at_breakpoint
68
73
 
69
74
  def at_catchpoint(context, excpt)
70
75
  file = self.class.canonic_file(context.frame_file(0))
71
76
  line = context.frame_line(0)
72
- print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
77
+ puts "Catchpoint at #{file}:#{line}: `#{excpt}' (#{excpt.class})"
73
78
  end
74
79
  protect :at_catchpoint
75
80
 
@@ -79,7 +84,7 @@ module Byebug
79
84
  if file != @last_file || line != @last_line || Setting[:tracing_plus]
80
85
  path = self.class.canonic_file(file)
81
86
  @last_file, @last_line = file, line
82
- print "Tracing: #{path}:#{line} #{get_line(file, line)}"
87
+ puts "Tracing: #{path}:#{line} #{get_line(file, line)}"
83
88
  end
84
89
  always_run(context, file, line, 2)
85
90
  end
@@ -97,152 +102,157 @@ module Byebug
97
102
  protect :at_return
98
103
 
99
104
  private
100
- #
101
- # Prompt shown before reading a command.
102
- #
103
- def prompt(context)
104
- return "(byebug#{context.dead? ? ':post-mortem' : ''}) "
105
- end
106
105
 
107
- #
108
- # Run commands everytime.
109
- #
110
- # For example display commands or possibly the list or irb in an
111
- # "autolist" or "autoirb".
112
- #
113
- # @return List of commands acceptable to run bound to the current state
114
- #
115
- def always_run(context, file, line, run_level)
116
- cmds = Command.commands
106
+ #
107
+ # Prompt shown before reading a command.
108
+ #
109
+ def prompt(context)
110
+ "(byebug#{context.dead? ? ':post-mortem' : ''}) "
111
+ end
117
112
 
118
- state = State.new(cmds, context, @display, file, @interface, line)
113
+ #
114
+ # Run commands everytime.
115
+ #
116
+ # For example display commands or possibly the list or irb in an
117
+ # "autolist" or "autoirb".
118
+ #
119
+ # @return List of commands acceptable to run bound to the current state
120
+ #
121
+ def always_run(context, file, line, run_level)
122
+ cmds = Command.commands
119
123
 
120
- # Change default when in irb or code included in command line
121
- Setting[:autolist] = false if ['(irb)', '-e'].include?(file)
124
+ state = State.new(cmds, context, @display, file, @interface, line)
122
125
 
123
- # Bind commands to the current state.
124
- commands = cmds.map { |cmd| cmd.new(state) }
126
+ # Change default when in irb or code included in command line
127
+ Setting[:autolist] = false if ['(irb)', '-e'].include?(file)
125
128
 
126
- commands.select { |cmd| cmd.class.always_run >= run_level }
127
- .each { |cmd| cmd.execute }
129
+ # Bind commands to the current state.
130
+ commands = cmds.map { |cmd| cmd.new(state) }
128
131
 
129
- return state, commands
130
- end
132
+ commands.select { |cmd| cmd.class.always_run >= run_level }
133
+ .each { |cmd| cmd.execute }
131
134
 
132
- #
133
- # Splits a command line of the form "cmd1 ; cmd2 ; ... ; cmdN" into an
134
- # array of commands: [cmd1, cmd2, ..., cmdN]
135
- #
136
- def split_commands(cmd_line)
137
- cmd_line.split(/;/).inject([]) do |m, v|
138
- if m.empty?
139
- m << v
135
+ [state, commands]
136
+ end
137
+
138
+ #
139
+ # Splits a command line of the form "cmd1 ; cmd2 ; ... ; cmdN" into an
140
+ # array of commands: [cmd1, cmd2, ..., cmdN]
141
+ #
142
+ def split_commands(cmd_line)
143
+ cmd_line.split(/;/).each_with_object([]) do |v, m|
144
+ if m.empty?
145
+ m << v
146
+ else
147
+ if m.last[-1] == '\\'
148
+ m.last[-1, 1] = ''
149
+ m.last << ';' << v
140
150
  else
141
- if m.last[-1] == ?\\
142
- m.last[-1,1] = ''
143
- m.last << ';' << v
144
- else
145
- m << v
146
- end
151
+ m << v
147
152
  end
148
- m
149
153
  end
150
154
  end
155
+ end
151
156
 
152
- #
153
- # Handle byebug commands.
154
- #
155
- def process_commands(context, file, line)
156
- state, commands = always_run(context, file, line, 1)
157
+ #
158
+ # Handle byebug commands.
159
+ #
160
+ def process_commands(context, file, line)
161
+ state, commands = always_run(context, file, line, 1)
157
162
 
158
- if Setting[:testing]
159
- Thread.current.thread_variable_set('state', state)
160
- else
161
- Thread.current.thread_variable_set('state', nil)
162
- end
163
+ if Setting[:testing]
164
+ Thread.current.thread_variable_set('state', state)
165
+ else
166
+ Thread.current.thread_variable_set('state', nil)
167
+ end
163
168
 
164
- preloop(commands, context)
165
- print state.location if Setting[:autolist] == 0
169
+ preloop(commands, context)
170
+ puts(state.location) if Setting[:autolist] == 0
166
171
 
167
- while !state.proceed?
168
- input = @interface.command_queue.empty? ?
169
- @interface.read_command(prompt(context)) :
172
+ until state.proceed?
173
+ input = if @interface.command_queue.empty?
174
+ @interface.read_command(prompt(context))
175
+ else
170
176
  @interface.command_queue.shift
171
- break unless input
172
- catch(:debug_error) do
173
- if input == ""
174
- next unless @last_cmd
175
- input = @last_cmd
176
- else
177
- @last_cmd = input
178
- end
179
- split_commands(input).each do |cmd|
180
- one_cmd(commands, context, cmd)
181
- end
182
- end
183
- end
184
- end
177
+ end
178
+ break unless input
185
179
 
186
- #
187
- # Executes a single byebug command
188
- #
189
- def one_cmd(commands, context, input)
190
- if cmd = commands.find { |c| c.match(input) }
191
- if context.dead? && !cmd.class.allow_in_post_mortem
192
- errmsg "Command unavailable in post mortem mode.\n"
193
- else
194
- cmd.execute
195
- end
180
+ if input == ''
181
+ next unless @last_cmd
182
+ input = @last_cmd
196
183
  else
197
- unknown_cmd = commands.find { |c| c.class.unknown }
198
- if unknown_cmd
199
- unknown_cmd.execute
200
- else
201
- errmsg "Unknown command: \"#{input}\". Try \"help\".\n"
202
- end
184
+ @last_cmd = input
203
185
  end
186
+ split_commands(input).each do |cmd|
187
+ one_cmd(commands, context, cmd)
188
+ end
189
+ end
190
+ end
191
+
192
+ #
193
+ # Autoevals a single command
194
+ #
195
+ def one_unknown_cmd(commands, input)
196
+ unless Setting[:autoeval]
197
+ return errmsg("Unknown command: \"#{input}\". Try \"help\"")
204
198
  end
205
199
 
206
- #
207
- # Tasks to do before processor loop
208
- #
209
- def preloop(commands, context)
210
- @context_was_dead = true if context.dead? and not @context_was_dead
200
+ commands.find { |c| c.is_a?(EvalCommand) }.execute
201
+ end
211
202
 
212
- if @context_was_dead
213
- print "The program finished.\n"
214
- @context_was_dead = false
215
- end
203
+ #
204
+ # Executes a single byebug command
205
+ #
206
+ def one_cmd(commands, context, input)
207
+ cmd = commands.find { |c| c.match(input) }
208
+ return one_unknown_cmd(commands, input) unless cmd
209
+
210
+ if context.dead? && !cmd.class.allow_in_post_mortem
211
+ return errmsg('Command unavailable in post mortem mode.')
216
212
  end
217
213
 
218
- class State
219
- attr_accessor :commands, :context, :display, :file, :frame_pos
220
- attr_accessor :interface, :line, :previous_line
214
+ cmd.execute
215
+ end
216
+
217
+ #
218
+ # Tasks to do before processor loop
219
+ #
220
+ def preloop(_commands, context)
221
+ @context_was_dead = true if context.dead? && !@context_was_dead
222
+ return unless @context_was_dead
221
223
 
222
- def initialize(commands, context, display, file, interface, line)
223
- @commands, @context, @display = commands, context, display
224
- @file, @interface, @line = file, interface, line
225
- @frame_pos, @previous_line, @proceed = 0, nil, false
226
- end
224
+ puts 'The program finished.'
225
+ @context_was_dead = false
226
+ end
227
227
 
228
- extend Forwardable
229
- def_delegators :@interface, :errmsg, :print, :confirm
228
+ class State
229
+ attr_accessor :commands, :context, :display, :file, :frame_pos
230
+ attr_accessor :interface, :line, :previous_line
230
231
 
231
- def proceed?
232
- @proceed
233
- end
232
+ def initialize(commands, context, display, file, interface, line)
233
+ @commands, @context, @display = commands, context, display
234
+ @file, @interface, @line = file, interface, line
235
+ @frame_pos, @previous_line, @proceed = 0, nil, false
236
+ end
234
237
 
235
- def proceed
236
- @proceed = true
237
- end
238
+ extend Forwardable
239
+ def_delegators :@interface, :errmsg, :puts, :confirm
238
240
 
239
- def location
240
- path = self.class.canonic_file(@file)
241
- loc = "#{path} @ #{@line}\n"
242
- loc += "#{get_line(@file, @line)}\n" unless
243
- ['(irb)', '-e'].include? @file
244
- loc
245
- end
241
+ def proceed?
242
+ @proceed
243
+ end
244
+
245
+ def proceed
246
+ @proceed = true
246
247
  end
247
- end # class CommandProcessor
248
+
249
+ def location
250
+ path = self.class.canonic_file(@file)
251
+ loc = "#{path} @ #{@line}\n"
252
+ loc += "#{get_line(@file, @line)}\n" unless
253
+ ['(irb)', '-e'].include? @file
254
+ loc
255
+ end
256
+ end
257
+ end
248
258
  end