runger_byebug 11.2.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 (132) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +954 -0
  3. data/CONTRIBUTING.md +58 -0
  4. data/GUIDE.md +1806 -0
  5. data/LICENSE +23 -0
  6. data/README.md +199 -0
  7. data/exe/byebug +6 -0
  8. data/ext/byebug/breakpoint.c +521 -0
  9. data/ext/byebug/byebug.c +900 -0
  10. data/ext/byebug/byebug.h +145 -0
  11. data/ext/byebug/context.c +687 -0
  12. data/ext/byebug/extconf.rb +12 -0
  13. data/ext/byebug/locker.c +96 -0
  14. data/ext/byebug/threads.c +241 -0
  15. data/lib/byebug/attacher.rb +48 -0
  16. data/lib/byebug/breakpoint.rb +94 -0
  17. data/lib/byebug/command.rb +111 -0
  18. data/lib/byebug/command_list.rb +34 -0
  19. data/lib/byebug/commands/break.rb +114 -0
  20. data/lib/byebug/commands/catch.rb +78 -0
  21. data/lib/byebug/commands/condition.rb +55 -0
  22. data/lib/byebug/commands/continue.rb +68 -0
  23. data/lib/byebug/commands/debug.rb +38 -0
  24. data/lib/byebug/commands/delete.rb +55 -0
  25. data/lib/byebug/commands/disable/breakpoints.rb +42 -0
  26. data/lib/byebug/commands/disable/display.rb +43 -0
  27. data/lib/byebug/commands/disable.rb +33 -0
  28. data/lib/byebug/commands/display.rb +66 -0
  29. data/lib/byebug/commands/down.rb +45 -0
  30. data/lib/byebug/commands/edit.rb +69 -0
  31. data/lib/byebug/commands/enable/breakpoints.rb +42 -0
  32. data/lib/byebug/commands/enable/display.rb +43 -0
  33. data/lib/byebug/commands/enable.rb +33 -0
  34. data/lib/byebug/commands/finish.rb +57 -0
  35. data/lib/byebug/commands/frame.rb +57 -0
  36. data/lib/byebug/commands/help.rb +64 -0
  37. data/lib/byebug/commands/history.rb +39 -0
  38. data/lib/byebug/commands/info/breakpoints.rb +65 -0
  39. data/lib/byebug/commands/info/display.rb +49 -0
  40. data/lib/byebug/commands/info/file.rb +80 -0
  41. data/lib/byebug/commands/info/line.rb +35 -0
  42. data/lib/byebug/commands/info/program.rb +49 -0
  43. data/lib/byebug/commands/info.rb +37 -0
  44. data/lib/byebug/commands/interrupt.rb +34 -0
  45. data/lib/byebug/commands/irb.rb +50 -0
  46. data/lib/byebug/commands/kill.rb +45 -0
  47. data/lib/byebug/commands/list.rb +159 -0
  48. data/lib/byebug/commands/method.rb +53 -0
  49. data/lib/byebug/commands/next.rb +40 -0
  50. data/lib/byebug/commands/pry.rb +41 -0
  51. data/lib/byebug/commands/quit.rb +42 -0
  52. data/lib/byebug/commands/restart.rb +64 -0
  53. data/lib/byebug/commands/save.rb +72 -0
  54. data/lib/byebug/commands/set.rb +79 -0
  55. data/lib/byebug/commands/show.rb +45 -0
  56. data/lib/byebug/commands/skip.rb +85 -0
  57. data/lib/byebug/commands/source.rb +40 -0
  58. data/lib/byebug/commands/step.rb +40 -0
  59. data/lib/byebug/commands/thread/current.rb +37 -0
  60. data/lib/byebug/commands/thread/list.rb +43 -0
  61. data/lib/byebug/commands/thread/resume.rb +45 -0
  62. data/lib/byebug/commands/thread/stop.rb +43 -0
  63. data/lib/byebug/commands/thread/switch.rb +46 -0
  64. data/lib/byebug/commands/thread.rb +34 -0
  65. data/lib/byebug/commands/tracevar.rb +54 -0
  66. data/lib/byebug/commands/undisplay.rb +51 -0
  67. data/lib/byebug/commands/untracevar.rb +36 -0
  68. data/lib/byebug/commands/up.rb +45 -0
  69. data/lib/byebug/commands/var/all.rb +41 -0
  70. data/lib/byebug/commands/var/args.rb +39 -0
  71. data/lib/byebug/commands/var/const.rb +49 -0
  72. data/lib/byebug/commands/var/global.rb +37 -0
  73. data/lib/byebug/commands/var/instance.rb +39 -0
  74. data/lib/byebug/commands/var/local.rb +39 -0
  75. data/lib/byebug/commands/var.rb +37 -0
  76. data/lib/byebug/commands/where.rb +64 -0
  77. data/lib/byebug/commands.rb +40 -0
  78. data/lib/byebug/context.rb +157 -0
  79. data/lib/byebug/core.rb +115 -0
  80. data/lib/byebug/errors.rb +29 -0
  81. data/lib/byebug/frame.rb +185 -0
  82. data/lib/byebug/helpers/bin.rb +47 -0
  83. data/lib/byebug/helpers/eval.rb +134 -0
  84. data/lib/byebug/helpers/file.rb +63 -0
  85. data/lib/byebug/helpers/frame.rb +75 -0
  86. data/lib/byebug/helpers/parse.rb +80 -0
  87. data/lib/byebug/helpers/path.rb +40 -0
  88. data/lib/byebug/helpers/reflection.rb +19 -0
  89. data/lib/byebug/helpers/string.rb +33 -0
  90. data/lib/byebug/helpers/thread.rb +67 -0
  91. data/lib/byebug/helpers/toggle.rb +62 -0
  92. data/lib/byebug/helpers/var.rb +70 -0
  93. data/lib/byebug/history.rb +130 -0
  94. data/lib/byebug/interface.rb +146 -0
  95. data/lib/byebug/interfaces/local_interface.rb +63 -0
  96. data/lib/byebug/interfaces/remote_interface.rb +50 -0
  97. data/lib/byebug/interfaces/script_interface.rb +33 -0
  98. data/lib/byebug/interfaces/test_interface.rb +67 -0
  99. data/lib/byebug/option_setter.rb +95 -0
  100. data/lib/byebug/printers/base.rb +68 -0
  101. data/lib/byebug/printers/plain.rb +44 -0
  102. data/lib/byebug/printers/texts/base.yml +115 -0
  103. data/lib/byebug/printers/texts/plain.yml +33 -0
  104. data/lib/byebug/processors/command_processor.rb +173 -0
  105. data/lib/byebug/processors/control_processor.rb +24 -0
  106. data/lib/byebug/processors/post_mortem_processor.rb +18 -0
  107. data/lib/byebug/processors/script_processor.rb +49 -0
  108. data/lib/byebug/remote/client.rb +57 -0
  109. data/lib/byebug/remote/server.rb +47 -0
  110. data/lib/byebug/remote.rb +85 -0
  111. data/lib/byebug/runner.rb +198 -0
  112. data/lib/byebug/setting.rb +79 -0
  113. data/lib/byebug/settings/autoirb.rb +29 -0
  114. data/lib/byebug/settings/autolist.rb +29 -0
  115. data/lib/byebug/settings/autopry.rb +29 -0
  116. data/lib/byebug/settings/autosave.rb +17 -0
  117. data/lib/byebug/settings/basename.rb +16 -0
  118. data/lib/byebug/settings/callstyle.rb +20 -0
  119. data/lib/byebug/settings/fullpath.rb +16 -0
  120. data/lib/byebug/settings/histfile.rb +20 -0
  121. data/lib/byebug/settings/histsize.rb +20 -0
  122. data/lib/byebug/settings/linetrace.rb +22 -0
  123. data/lib/byebug/settings/listsize.rb +21 -0
  124. data/lib/byebug/settings/post_mortem.rb +27 -0
  125. data/lib/byebug/settings/savefile.rb +20 -0
  126. data/lib/byebug/settings/stack_on_error.rb +15 -0
  127. data/lib/byebug/settings/width.rb +20 -0
  128. data/lib/byebug/source_file_formatter.rb +71 -0
  129. data/lib/byebug/subcommands.rb +54 -0
  130. data/lib/byebug/version.rb +8 -0
  131. data/lib/byebug.rb +3 -0
  132. metadata +194 -0
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Byebug
4
+ #
5
+ # Handles byebug's command line options
6
+ #
7
+ class OptionSetter
8
+ def initialize(runner, opts)
9
+ @runner = runner
10
+ @opts = opts
11
+ end
12
+
13
+ def setup
14
+ debug
15
+ include_flag
16
+ post_mortem
17
+ quit
18
+ rc
19
+ stop
20
+ require_flag
21
+ remote
22
+ trace
23
+ version
24
+ help
25
+ end
26
+
27
+ private
28
+
29
+ def debug
30
+ @opts.on "-d", "--debug", "Set $DEBUG=true" do
31
+ $DEBUG = true
32
+ end
33
+ end
34
+
35
+ def include_flag
36
+ @opts.on "-I", "--include list", "Add paths to $LOAD_PATH" do |list|
37
+ $LOAD_PATH.push(list.split(":")).flatten!
38
+ end
39
+ end
40
+
41
+ def post_mortem
42
+ @opts.on "-m", "--[no-]post-mortem", "Use post-mortem mode" do |v|
43
+ Setting[:post_mortem] = v
44
+ end
45
+ end
46
+
47
+ def quit
48
+ @opts.on "-q", "--[no-]quit", "Quit when script finishes" do |v|
49
+ @runner.quit = v
50
+ end
51
+ end
52
+
53
+ def rc
54
+ @opts.on "-x", "--[no-]rc", "Run byebug initialization file" do |v|
55
+ @runner.init_script = v
56
+ end
57
+ end
58
+
59
+ def stop
60
+ @opts.on "-s", "--[no-]stop", "Stop when script is loaded" do |v|
61
+ @runner.stop = v
62
+ end
63
+ end
64
+
65
+ def require_flag
66
+ @opts.on "-r", "--require file", "Require library before script" do |lib|
67
+ require lib
68
+ end
69
+ end
70
+
71
+ def remote
72
+ @opts.on "-R", "--remote [host:]port", "Remote debug [host:]port" do |p|
73
+ @runner.remote = p
74
+ end
75
+ end
76
+
77
+ def trace
78
+ @opts.on "-t", "--[no-]trace", "Turn on line tracing" do |v|
79
+ Setting[:linetrace] = v
80
+ end
81
+ end
82
+
83
+ def version
84
+ @opts.on "-v", "--version", "Print program version" do
85
+ @runner.version = Byebug::VERSION
86
+ end
87
+ end
88
+
89
+ def help
90
+ @opts.on "-h", "--help", "Display this message" do
91
+ @runner.help = @opts.help
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module Byebug
6
+ module Printers
7
+ #
8
+ # Base printer
9
+ #
10
+ class Base
11
+ class MissedPath < StandardError; end
12
+ class MissedArgument < StandardError; end
13
+
14
+ SEPARATOR = "."
15
+
16
+ def type
17
+ self.class.name.split("::").last.downcase
18
+ end
19
+
20
+ private
21
+
22
+ def locate(path)
23
+ result = nil
24
+ contents.each_value do |contents|
25
+ result = parts(path).reduce(contents) do |r, part|
26
+ r&.key?(part) ? r[part] : nil
27
+ end
28
+ break if result
29
+ end
30
+ raise MissedPath, "Can't find part path '#{path}'" unless result
31
+
32
+ result
33
+ end
34
+
35
+ def translate(string, args = {})
36
+ # they may contain #{} string interpolation
37
+ string.gsub(/\|\w+$/, "").gsub(/([^#]?){([^}]*)}/) do
38
+ key = Regexp.last_match[2].to_s
39
+ raise MissedArgument, "Missed argument #{key} for '#{string}'" unless args.key?(key.to_sym)
40
+
41
+ "#{Regexp.last_match[1]}#{args[key.to_sym]}"
42
+ end
43
+ end
44
+
45
+ def parts(path)
46
+ path.split(SEPARATOR)
47
+ end
48
+
49
+ def contents
50
+ @contents ||= contents_files.each_with_object({}) do |filename, hash|
51
+ hash[filename] = YAML.load_file(filename) || {}
52
+ end
53
+ end
54
+
55
+ def array_of_args(collection, &_block)
56
+ collection_with_index = collection.each.with_index
57
+ collection_with_index.each_with_object([]) do |(item, index), array|
58
+ args = yield item, index
59
+ array << args if args
60
+ end
61
+ end
62
+
63
+ def contents_files
64
+ [File.join(__dir__, "texts", "base.yml")]
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Byebug
6
+ module Printers
7
+ #
8
+ # Plain text printer
9
+ #
10
+ class Plain < Base
11
+ def print(path, args = {})
12
+ message = translate(locate(path), args)
13
+ tail = parts(path).include?("confirmations") ? " (y/n) " : "\n"
14
+ message << tail
15
+ end
16
+
17
+ def print_collection(path, collection, &block)
18
+ lines = array_of_args(collection, &block).map do |args|
19
+ print(path, args)
20
+ end
21
+
22
+ lines.join
23
+ end
24
+
25
+ def print_variables(variables, *_unused)
26
+ print_collection("variable.variable", variables) do |(key, value), _|
27
+ value = value.nil? ? "nil" : value.to_s
28
+ if "#{key} = #{value}".size > Setting[:width]
29
+ key_size = "#{key} = ".size
30
+ value = value[0..Setting[:width] - key_size - 4] + "..."
31
+ end
32
+
33
+ { key: key, value: value }
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def contents_files
40
+ [File.join(__dir__, "texts", "plain.yml")] + super
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,115 @@
1
+ base:
2
+ errors:
3
+ only_local: "Command is available only in local mode."
4
+
5
+ break:
6
+ errors:
7
+ line: "Line {line} is not a valid breakpoint in file {file}.\n\nValid break points are:\n{valid_breakpoints}"
8
+ location: "Invalid breakpoint location"
9
+ state: "We are not in a state that has an associated file"
10
+ class: "Unknown class {klass}"
11
+ far_line: "There are only {lines} lines in file {file}"
12
+ source: "No file named {file}"
13
+ expression: "Incorrect expression \"{expr}\"; breakpoint disabled"
14
+ no_breakpoint: "Invalid breakpoint id. Use \"info breakpoint\" to find out the correct id"
15
+ no_breakpoint_delete: "No breakpoint number {pos}"
16
+ not_changed: "Incorrect expression \"{expr}\", breakpoint not changed"
17
+ confirmations:
18
+ delete_all: "Delete all breakpoints?"
19
+ messages:
20
+ breakpoint_deleted: "Deleted breakpoint {pos}"
21
+
22
+ catch:
23
+ added: "Catching exception {exception}."
24
+ removed: "Catch for exception {exception} removed"
25
+ errors:
26
+ off: "Off expected. Got {off}"
27
+ not_class: "Warning {class} is not known to be a Class"
28
+ not_found: "Catch for exception {exception} not found"
29
+ confirmations:
30
+ delete_all: "Delete all catchpoints? (y or n) "
31
+
32
+ condition:
33
+ errors:
34
+ no_breakpoints: "No breakpoints have been set"
35
+
36
+ continue:
37
+ errors:
38
+ unstopped_line: "Line {line} is not a valid stopping point in file"
39
+
40
+ display:
41
+ confirmations:
42
+ clear_all: "Clear all expressions?"
43
+ errors:
44
+ undefined: "Display expression {expr} is not defined"
45
+
46
+ edit:
47
+ errors:
48
+ state: "We are not in a state that has an associated file"
49
+ file_line: "Invalid file[:line] number specification: {file_line}"
50
+ not_readable: "File {file} is not readable."
51
+ not_exist: "File {file} does not exist."
52
+
53
+ frame:
54
+ errors:
55
+ too_low: "Can't navigate beyond the oldest frame"
56
+ too_high: "Can't navigate beyond the newest frame"
57
+ c_frame: "Can't navigate to c-frame"
58
+
59
+ info:
60
+ errors:
61
+ undefined_file: "{file} is not a valid source file"
62
+
63
+ pry:
64
+ errors:
65
+ not_installed: "You need to install pry in order to run this command"
66
+
67
+ quit:
68
+ confirmations:
69
+ really: "Really quit?"
70
+
71
+ save:
72
+ messages:
73
+ done: "Saved to '{path}'"
74
+
75
+ set:
76
+ errors:
77
+ unknown_setting: "Unknown setting :{key}"
78
+ must_specify_value: "You must specify a value for setting :{key}"
79
+ on_off: "Expecting 'on', 1, true, 'off', 0, false. Got: {arg}."
80
+
81
+ show:
82
+ errors:
83
+ unknown_setting: "Unknown setting :{key}"
84
+
85
+ source:
86
+ errors:
87
+ not_found: "File \"{file}\" not found"
88
+
89
+ thread:
90
+ errors:
91
+ no_thread: "No such thread"
92
+ current_thread: "It's the current thread"
93
+ wrong_action: "Can't {subcmd} thread {arg}"
94
+ already_running: "Already running"
95
+
96
+ toggle:
97
+ errors:
98
+ no_breakpoints: "No breakpoints have been set"
99
+ no_display: "No display expressions have been set"
100
+ syntax: "\"{toggle}\" must be followed by \"display\", \"breakpoints\" or breakpoint ids"
101
+ expression: "Expression \"{expr}\" syntactically incorrect; breakpoint remains disabled."
102
+ messages:
103
+ toggled: "Breakpoint {bpnum} {endis}abled"
104
+
105
+ parse:
106
+ errors:
107
+ int:
108
+ too_low: "\"{cmd}\" argument \"{str}\" needs to be at least {min}"
109
+ too_high: "\"{cmd}\" argument \"{str}\" needs to be at most {max}"
110
+ not_number: "\"{cmd}\" argument \"{str}\" needs to be a number"
111
+
112
+ variable:
113
+ errors:
114
+ not_module: "Should be Class/Module: {object}"
115
+ cant_get_class_vars: "can't get class variables here.\n"
@@ -0,0 +1,33 @@
1
+ break:
2
+ created: "Created breakpoint {id} at {file}:{line}"
3
+
4
+ display:
5
+ result: "{n}: {exp} = {result}"
6
+
7
+ eval:
8
+ exception: "{text_message}"
9
+ result: "{result}"
10
+
11
+ frame:
12
+ line: "{mark} #{pos} {call} at {file}:{line}"
13
+
14
+ method:
15
+ methods: "{name}|c"
16
+
17
+ restart:
18
+ success: "Re exec'ing:\n {cmd}"
19
+
20
+ thread:
21
+ context: "{status_flag}{debug_flag}{id} {thread} {file_line}"
22
+
23
+ trace:
24
+ messages:
25
+ success: "Tracing global variable \"{var}\"."
26
+ on_change: "traced global variable '{name}' has value '{value}'"
27
+ undo: "Not tracing global variable \"{var}\" anymore."
28
+ errors:
29
+ var_is_not_global: "'{name}' is not a global variable."
30
+ needs_global_variable: "tracevar needs a global variable name"
31
+
32
+ variable:
33
+ variable: "{key} = {value}"
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ require_relative "../helpers/eval"
6
+ require_relative "../errors"
7
+
8
+ module Byebug
9
+ #
10
+ # Processes commands in regular mode.
11
+ #
12
+ # You can override this class to create your own command processor that, for
13
+ # example, whitelists only certain commands to be executed.
14
+ #
15
+ # @see PostMortemProcessor for a example
16
+ #
17
+ class CommandProcessor
18
+ include Helpers::EvalHelper
19
+
20
+ attr_accessor :prev_line
21
+ attr_reader :context, :interface
22
+
23
+ def initialize(context, interface = LocalInterface.new)
24
+ @context = context
25
+ @interface = interface
26
+
27
+ @proceed = false
28
+ @prev_line = nil
29
+ end
30
+
31
+ def printer
32
+ @printer ||= Printers::Plain.new
33
+ end
34
+
35
+ extend Forwardable
36
+
37
+ def_delegators :@context, :frame
38
+
39
+ def_delegator :printer, :print, :pr
40
+ def_delegator :printer, :print_collection, :prc
41
+ def_delegator :printer, :print_variables, :prv
42
+
43
+ def_delegators :interface, :errmsg, :puts, :confirm
44
+
45
+ def_delegators :Byebug, :commands
46
+
47
+ #
48
+ # Available commands
49
+ #
50
+ def command_list
51
+ @command_list ||= CommandList.new(commands)
52
+ end
53
+
54
+ def at_line
55
+ process_commands
56
+ end
57
+
58
+ def at_tracing
59
+ puts "Tracing: #{context.full_location}"
60
+
61
+ run_auto_cmds(2)
62
+ end
63
+
64
+ def at_breakpoint(brkpt)
65
+ number = Byebug.breakpoints.index(brkpt) + 1
66
+
67
+ puts "Stopped by breakpoint #{number} at #{frame.file}:#{frame.line}"
68
+ end
69
+
70
+ def at_catchpoint(exception)
71
+ puts "Catchpoint at #{context.location}: `#{exception}'"
72
+ end
73
+
74
+ def at_return(return_value)
75
+ puts "Return value is: #{safe_inspect(return_value)}"
76
+
77
+ process_commands
78
+ end
79
+
80
+ def at_end
81
+ process_commands
82
+ end
83
+
84
+ #
85
+ # Let the execution continue
86
+ #
87
+ def proceed!
88
+ @proceed = true
89
+ end
90
+
91
+ #
92
+ # Handle byebug commands.
93
+ #
94
+ def process_commands
95
+ before_repl
96
+
97
+ repl
98
+ ensure
99
+ after_repl
100
+ end
101
+
102
+ protected
103
+
104
+ #
105
+ # Prompt shown before reading a command.
106
+ #
107
+ def prompt
108
+ "(byebug) "
109
+ end
110
+
111
+ def before_repl
112
+ @proceed = false
113
+ @prev_line = nil
114
+
115
+ run_auto_cmds(1)
116
+ interface.autorestore
117
+ end
118
+
119
+ def after_repl
120
+ interface.autosave
121
+ end
122
+
123
+ #
124
+ # Main byebug's REPL
125
+ #
126
+ def repl
127
+ until @proceed
128
+ cmd = interface.read_command(prompt)
129
+ return if cmd.nil?
130
+
131
+ next if cmd == ""
132
+
133
+ run_cmd(cmd)
134
+ end
135
+ end
136
+
137
+ private
138
+
139
+ def auto_cmds_for(run_level)
140
+ command_list.select { |cmd| cmd.always_run >= run_level }
141
+ end
142
+
143
+ #
144
+ # Run permanent commands.
145
+ #
146
+ def run_auto_cmds(run_level)
147
+ safely do
148
+ auto_cmds_for(run_level).each { |cmd| cmd.new(self).execute }
149
+ end
150
+ end
151
+
152
+ #
153
+ # Executes the received input
154
+ #
155
+ # Instantiates a command matching the input and runs it. If a matching
156
+ # command is not found, it evaluates the unknown input.
157
+ #
158
+ def run_cmd(input)
159
+ safely do
160
+ command = command_list.match(input)
161
+ return command.new(self, input).execute if command
162
+
163
+ puts safe_inspect(multiple_thread_eval(input))
164
+ end
165
+ end
166
+
167
+ def safely
168
+ yield
169
+ rescue StandardError => e
170
+ errmsg(e.message)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "command_processor"
4
+
5
+ module Byebug
6
+ #
7
+ # Processes commands when there's not program running
8
+ #
9
+ class ControlProcessor < CommandProcessor
10
+ #
11
+ # Available commands
12
+ #
13
+ def commands
14
+ super.select(&:allow_in_control)
15
+ end
16
+
17
+ #
18
+ # Prompt shown before reading a command.
19
+ #
20
+ def prompt
21
+ "(byebug:ctrl) "
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "command_processor"
4
+
5
+ module Byebug
6
+ #
7
+ # Processes commands in post_mortem mode
8
+ #
9
+ class PostMortemProcessor < CommandProcessor
10
+ def commands
11
+ super.select(&:allow_in_post_mortem)
12
+ end
13
+
14
+ def prompt
15
+ "(byebug:post_mortem) "
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "command_processor"
4
+
5
+ module Byebug
6
+ #
7
+ # Processes commands from a file
8
+ #
9
+ class ScriptProcessor < CommandProcessor
10
+ #
11
+ # Available commands
12
+ #
13
+ def commands
14
+ super.select(&:allow_in_control)
15
+ end
16
+
17
+ def repl
18
+ while (input = interface.read_command(prompt))
19
+ safely do
20
+ command = command_list.match(input)
21
+ raise CommandNotFound.new(input) unless command
22
+
23
+ command.new(self, input).execute
24
+ end
25
+ end
26
+ end
27
+
28
+ def after_repl
29
+ super
30
+
31
+ interface.close
32
+ end
33
+
34
+ #
35
+ # Prompt shown before reading a command.
36
+ #
37
+ def prompt
38
+ "(byebug:ctrl) "
39
+ end
40
+
41
+ private
42
+
43
+ def without_exceptions
44
+ yield
45
+ rescue StandardError
46
+ nil
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ module Byebug
6
+ module Remote
7
+ #
8
+ # Client for remote debugging
9
+ #
10
+ class Client
11
+ attr_reader :interface, :socket
12
+
13
+ def initialize(interface)
14
+ @interface = interface
15
+ @socket = nil
16
+ end
17
+
18
+ #
19
+ # Connects to the remote byebug
20
+ #
21
+ def start(host = "localhost", port = PORT)
22
+ connect_at(host, port)
23
+
24
+ while (line = socket.gets)
25
+ case line
26
+ when /^PROMPT (.*)$/
27
+ input = interface.read_command(Regexp.last_match[1])
28
+ break unless input
29
+
30
+ socket.puts input
31
+ when /^CONFIRM (.*)$/
32
+ input = interface.readline(Regexp.last_match[1])
33
+ break unless input
34
+
35
+ socket.puts input
36
+ else
37
+ interface.puts line
38
+ end
39
+ end
40
+
41
+ socket.close
42
+ end
43
+
44
+ def started?
45
+ !socket.nil?
46
+ end
47
+
48
+ private
49
+
50
+ def connect_at(host, port)
51
+ interface.puts "Connecting to byebug server at #{host}:#{port}..."
52
+ @socket = TCPSocket.new(host, port)
53
+ interface.puts "Connected."
54
+ end
55
+ end
56
+ end
57
+ end