byebug 3.2.0 → 3.3.0

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