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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +954 -0
- data/CONTRIBUTING.md +58 -0
- data/GUIDE.md +1806 -0
- data/LICENSE +23 -0
- data/README.md +199 -0
- data/exe/byebug +6 -0
- data/ext/byebug/breakpoint.c +521 -0
- data/ext/byebug/byebug.c +900 -0
- data/ext/byebug/byebug.h +145 -0
- data/ext/byebug/context.c +687 -0
- data/ext/byebug/extconf.rb +12 -0
- data/ext/byebug/locker.c +96 -0
- data/ext/byebug/threads.c +241 -0
- data/lib/byebug/attacher.rb +48 -0
- data/lib/byebug/breakpoint.rb +94 -0
- data/lib/byebug/command.rb +111 -0
- data/lib/byebug/command_list.rb +34 -0
- data/lib/byebug/commands/break.rb +114 -0
- data/lib/byebug/commands/catch.rb +78 -0
- data/lib/byebug/commands/condition.rb +55 -0
- data/lib/byebug/commands/continue.rb +68 -0
- data/lib/byebug/commands/debug.rb +38 -0
- data/lib/byebug/commands/delete.rb +55 -0
- data/lib/byebug/commands/disable/breakpoints.rb +42 -0
- data/lib/byebug/commands/disable/display.rb +43 -0
- data/lib/byebug/commands/disable.rb +33 -0
- data/lib/byebug/commands/display.rb +66 -0
- data/lib/byebug/commands/down.rb +45 -0
- data/lib/byebug/commands/edit.rb +69 -0
- data/lib/byebug/commands/enable/breakpoints.rb +42 -0
- data/lib/byebug/commands/enable/display.rb +43 -0
- data/lib/byebug/commands/enable.rb +33 -0
- data/lib/byebug/commands/finish.rb +57 -0
- data/lib/byebug/commands/frame.rb +57 -0
- data/lib/byebug/commands/help.rb +64 -0
- data/lib/byebug/commands/history.rb +39 -0
- data/lib/byebug/commands/info/breakpoints.rb +65 -0
- data/lib/byebug/commands/info/display.rb +49 -0
- data/lib/byebug/commands/info/file.rb +80 -0
- data/lib/byebug/commands/info/line.rb +35 -0
- data/lib/byebug/commands/info/program.rb +49 -0
- data/lib/byebug/commands/info.rb +37 -0
- data/lib/byebug/commands/interrupt.rb +34 -0
- data/lib/byebug/commands/irb.rb +50 -0
- data/lib/byebug/commands/kill.rb +45 -0
- data/lib/byebug/commands/list.rb +159 -0
- data/lib/byebug/commands/method.rb +53 -0
- data/lib/byebug/commands/next.rb +40 -0
- data/lib/byebug/commands/pry.rb +41 -0
- data/lib/byebug/commands/quit.rb +42 -0
- data/lib/byebug/commands/restart.rb +64 -0
- data/lib/byebug/commands/save.rb +72 -0
- data/lib/byebug/commands/set.rb +79 -0
- data/lib/byebug/commands/show.rb +45 -0
- data/lib/byebug/commands/skip.rb +85 -0
- data/lib/byebug/commands/source.rb +40 -0
- data/lib/byebug/commands/step.rb +40 -0
- data/lib/byebug/commands/thread/current.rb +37 -0
- data/lib/byebug/commands/thread/list.rb +43 -0
- data/lib/byebug/commands/thread/resume.rb +45 -0
- data/lib/byebug/commands/thread/stop.rb +43 -0
- data/lib/byebug/commands/thread/switch.rb +46 -0
- data/lib/byebug/commands/thread.rb +34 -0
- data/lib/byebug/commands/tracevar.rb +54 -0
- data/lib/byebug/commands/undisplay.rb +51 -0
- data/lib/byebug/commands/untracevar.rb +36 -0
- data/lib/byebug/commands/up.rb +45 -0
- data/lib/byebug/commands/var/all.rb +41 -0
- data/lib/byebug/commands/var/args.rb +39 -0
- data/lib/byebug/commands/var/const.rb +49 -0
- data/lib/byebug/commands/var/global.rb +37 -0
- data/lib/byebug/commands/var/instance.rb +39 -0
- data/lib/byebug/commands/var/local.rb +39 -0
- data/lib/byebug/commands/var.rb +37 -0
- data/lib/byebug/commands/where.rb +64 -0
- data/lib/byebug/commands.rb +40 -0
- data/lib/byebug/context.rb +157 -0
- data/lib/byebug/core.rb +115 -0
- data/lib/byebug/errors.rb +29 -0
- data/lib/byebug/frame.rb +185 -0
- data/lib/byebug/helpers/bin.rb +47 -0
- data/lib/byebug/helpers/eval.rb +134 -0
- data/lib/byebug/helpers/file.rb +63 -0
- data/lib/byebug/helpers/frame.rb +75 -0
- data/lib/byebug/helpers/parse.rb +80 -0
- data/lib/byebug/helpers/path.rb +40 -0
- data/lib/byebug/helpers/reflection.rb +19 -0
- data/lib/byebug/helpers/string.rb +33 -0
- data/lib/byebug/helpers/thread.rb +67 -0
- data/lib/byebug/helpers/toggle.rb +62 -0
- data/lib/byebug/helpers/var.rb +70 -0
- data/lib/byebug/history.rb +130 -0
- data/lib/byebug/interface.rb +146 -0
- data/lib/byebug/interfaces/local_interface.rb +63 -0
- data/lib/byebug/interfaces/remote_interface.rb +50 -0
- data/lib/byebug/interfaces/script_interface.rb +33 -0
- data/lib/byebug/interfaces/test_interface.rb +67 -0
- data/lib/byebug/option_setter.rb +95 -0
- data/lib/byebug/printers/base.rb +68 -0
- data/lib/byebug/printers/plain.rb +44 -0
- data/lib/byebug/printers/texts/base.yml +115 -0
- data/lib/byebug/printers/texts/plain.yml +33 -0
- data/lib/byebug/processors/command_processor.rb +173 -0
- data/lib/byebug/processors/control_processor.rb +24 -0
- data/lib/byebug/processors/post_mortem_processor.rb +18 -0
- data/lib/byebug/processors/script_processor.rb +49 -0
- data/lib/byebug/remote/client.rb +57 -0
- data/lib/byebug/remote/server.rb +47 -0
- data/lib/byebug/remote.rb +85 -0
- data/lib/byebug/runner.rb +198 -0
- data/lib/byebug/setting.rb +79 -0
- data/lib/byebug/settings/autoirb.rb +29 -0
- data/lib/byebug/settings/autolist.rb +29 -0
- data/lib/byebug/settings/autopry.rb +29 -0
- data/lib/byebug/settings/autosave.rb +17 -0
- data/lib/byebug/settings/basename.rb +16 -0
- data/lib/byebug/settings/callstyle.rb +20 -0
- data/lib/byebug/settings/fullpath.rb +16 -0
- data/lib/byebug/settings/histfile.rb +20 -0
- data/lib/byebug/settings/histsize.rb +20 -0
- data/lib/byebug/settings/linetrace.rb +22 -0
- data/lib/byebug/settings/listsize.rb +21 -0
- data/lib/byebug/settings/post_mortem.rb +27 -0
- data/lib/byebug/settings/savefile.rb +20 -0
- data/lib/byebug/settings/stack_on_error.rb +15 -0
- data/lib/byebug/settings/width.rb +20 -0
- data/lib/byebug/source_file_formatter.rb +71 -0
- data/lib/byebug/subcommands.rb +54 -0
- data/lib/byebug/version.rb +8 -0
- data/lib/byebug.rb +3 -0
- metadata +194 -0
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../subcommands"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require_relative "../commands/info/breakpoints"
         | 
| 6 | 
            +
            require_relative "../commands/info/display"
         | 
| 7 | 
            +
            require_relative "../commands/info/file"
         | 
| 8 | 
            +
            require_relative "../commands/info/line"
         | 
| 9 | 
            +
            require_relative "../commands/info/program"
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            module Byebug
         | 
| 12 | 
            +
              #
         | 
| 13 | 
            +
              # Shows info about different aspects of the debugger.
         | 
| 14 | 
            +
              #
         | 
| 15 | 
            +
              class InfoCommand < Command
         | 
| 16 | 
            +
                include Subcommands
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                self.allow_in_control = true
         | 
| 19 | 
            +
                self.allow_in_post_mortem = true
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def self.regexp
         | 
| 22 | 
            +
                  /^\s* i(?:nfo)? (?:\s+ (.+))? \s*$/x
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def self.description
         | 
| 26 | 
            +
                  <<-DESCRIPTION
         | 
| 27 | 
            +
                    info[ subcommand]
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    #{short_description}
         | 
| 30 | 
            +
                  DESCRIPTION
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def self.short_description
         | 
| 34 | 
            +
                  "Shows short description and information about the program being debugged"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Byebug
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              # Interrupting execution of current thread.
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              class InterruptCommand < Command
         | 
| 10 | 
            +
                self.allow_in_control = true
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def self.regexp
         | 
| 13 | 
            +
                  /^\s*int(?:errupt)?\s*$/
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def self.description
         | 
| 17 | 
            +
                  <<-DESCRIPTION
         | 
| 18 | 
            +
                    int[errupt]
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    #{short_description}
         | 
| 21 | 
            +
                  DESCRIPTION
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def self.short_description
         | 
| 25 | 
            +
                  "Interrupts the program"
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def execute
         | 
| 29 | 
            +
                  Byebug.start
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  Byebug.thread_context(Thread.main).interrupt
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
            require "irb"
         | 
| 5 | 
            +
            require "English"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module Byebug
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              # Enter IRB from byebug's prompt
         | 
| 10 | 
            +
              #
         | 
| 11 | 
            +
              class IrbCommand < Command
         | 
| 12 | 
            +
                self.allow_in_post_mortem = true
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def self.regexp
         | 
| 15 | 
            +
                  /^\s* irb \s*$/x
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def self.description
         | 
| 19 | 
            +
                  <<-DESCRIPTION
         | 
| 20 | 
            +
                    irb
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    #{short_description}
         | 
| 23 | 
            +
                  DESCRIPTION
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def self.short_description
         | 
| 27 | 
            +
                  "Starts an IRB session"
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def execute
         | 
| 31 | 
            +
                  return errmsg(pr("base.errors.only_local")) unless processor.interface.instance_of?(LocalInterface)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  # @todo IRB tries to parse $ARGV so we must clear it (see #197). Add a
         | 
| 34 | 
            +
                  #   test case for it so we can remove this comment.
         | 
| 35 | 
            +
                  with_clean_argv { IRB.start }
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                private
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def with_clean_argv
         | 
| 41 | 
            +
                  saved_argv = $ARGV.dup
         | 
| 42 | 
            +
                  $ARGV.clear
         | 
| 43 | 
            +
                  begin
         | 
| 44 | 
            +
                    yield
         | 
| 45 | 
            +
                  ensure
         | 
| 46 | 
            +
                    $ARGV.concat(saved_argv)
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Byebug
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              # Send custom signals to the debugged program.
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              class KillCommand < Command
         | 
| 10 | 
            +
                self.allow_in_control = true
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def self.regexp
         | 
| 13 | 
            +
                  /^\s* kill \s* (?:\s+(\S+))? \s*$/x
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def self.description
         | 
| 17 | 
            +
                  <<-DESCRIPTION
         | 
| 18 | 
            +
                    kill[ signal]
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    #{short_description}
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    Equivalent of Process.kill(Process.pid)
         | 
| 23 | 
            +
                  DESCRIPTION
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def self.short_description
         | 
| 27 | 
            +
                  "Sends a signal to the current process"
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def execute
         | 
| 31 | 
            +
                  if @match[1]
         | 
| 32 | 
            +
                    signame = @match[1]
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    return errmsg("signal name #{signame} is not a signal I know about\n") unless Signal.list.member?(signame)
         | 
| 35 | 
            +
                  else
         | 
| 36 | 
            +
                    return unless confirm("Really kill? (y/n) ")
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    signame = "KILL"
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  processor.interface.close if signame == "KILL"
         | 
| 42 | 
            +
                  Process.kill(signame, Process.pid)
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -0,0 +1,159 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
            require_relative "../source_file_formatter"
         | 
| 5 | 
            +
            require_relative "../helpers/file"
         | 
| 6 | 
            +
            require_relative "../helpers/parse"
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            module Byebug
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              # List parts of the source code.
         | 
| 11 | 
            +
              #
         | 
| 12 | 
            +
              class ListCommand < Command
         | 
| 13 | 
            +
                include Helpers::FileHelper
         | 
| 14 | 
            +
                include Helpers::ParseHelper
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                self.allow_in_post_mortem = true
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def self.regexp
         | 
| 19 | 
            +
                  /^\s* l(?:ist)? (?:\s*([-=])|\s+(\S+))? \s*$/x
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def self.description
         | 
| 23 | 
            +
                  <<-DESCRIPTION
         | 
| 24 | 
            +
                    l[ist][[-=]][ nn-mm]
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    #{short_description}
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    Lists lines forward from current line or from the place where code was
         | 
| 29 | 
            +
                    last listed. If "list-" is specified, lists backwards instead. If
         | 
| 30 | 
            +
                    "list=" is specified, lists from current line regardless of where code
         | 
| 31 | 
            +
                    was last listed. A line range can also be specified to list specific
         | 
| 32 | 
            +
                    sections of code.
         | 
| 33 | 
            +
                  DESCRIPTION
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def self.short_description
         | 
| 37 | 
            +
                  "Lists lines of source code"
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def execute
         | 
| 41 | 
            +
                  msg = "No sourcefile available for #{frame.file}"
         | 
| 42 | 
            +
                  raise(msg) unless File.exist?(frame.file)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  b, e = range(@match[2])
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  display_lines(b, e)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  processor.prev_line = b
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                private
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                #
         | 
| 54 | 
            +
                # Line range to be printed by `list`.
         | 
| 55 | 
            +
                #
         | 
| 56 | 
            +
                # If <input> is set, range is parsed from it.
         | 
| 57 | 
            +
                #
         | 
| 58 | 
            +
                # Otherwise it's automatically chosen.
         | 
| 59 | 
            +
                #
         | 
| 60 | 
            +
                def range(input)
         | 
| 61 | 
            +
                  return auto_range(@match[1] || "+") unless input
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  b, e = parse_range(input)
         | 
| 64 | 
            +
                  raise("Invalid line range") unless valid_range?(b, e)
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  [b, e]
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def valid_range?(first, last)
         | 
| 70 | 
            +
                  first <= last && (1..max_line).cover?(first) && (1..max_line).cover?(last)
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                #
         | 
| 74 | 
            +
                # Set line range to be printed by list
         | 
| 75 | 
            +
                #
         | 
| 76 | 
            +
                # @return first line number to list
         | 
| 77 | 
            +
                # @return last line number to list
         | 
| 78 | 
            +
                #
         | 
| 79 | 
            +
                def auto_range(direction)
         | 
| 80 | 
            +
                  prev_line = processor.prev_line
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  if direction == "=" || prev_line.nil?
         | 
| 83 | 
            +
                    source_file_formatter.range_around(frame.line)
         | 
| 84 | 
            +
                  else
         | 
| 85 | 
            +
                    source_file_formatter.range_from(move(prev_line, size, direction))
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                def parse_range(input)
         | 
| 90 | 
            +
                  first, err = get_int(lower_bound(input), "List", 1, max_line)
         | 
| 91 | 
            +
                  raise(err) unless first
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  if upper_bound(input)
         | 
| 94 | 
            +
                    last, err = get_int(upper_bound(input), "List", 1, max_line)
         | 
| 95 | 
            +
                    raise(err) unless last
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                    last = amend_final(last)
         | 
| 98 | 
            +
                  else
         | 
| 99 | 
            +
                    first -= (size / 2)
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  [first, last || move(first, size - 1)]
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                def move(line, size, direction = "+")
         | 
| 106 | 
            +
                  line.send(direction, size)
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                #
         | 
| 110 | 
            +
                # Show a range of lines in the current file.
         | 
| 111 | 
            +
                #
         | 
| 112 | 
            +
                # @param min [Integer] Lower bound
         | 
| 113 | 
            +
                # @param max [Integer] Upper bound
         | 
| 114 | 
            +
                #
         | 
| 115 | 
            +
                def display_lines(min, max)
         | 
| 116 | 
            +
                  puts "\n[#{min}, #{max}] in #{frame.file}"
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  puts source_file_formatter.lines(min, max).join
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                #
         | 
| 122 | 
            +
                # @param range [String] A string with an integer range format
         | 
| 123 | 
            +
                #
         | 
| 124 | 
            +
                # @return [String] The lower bound of the given range
         | 
| 125 | 
            +
                #
         | 
| 126 | 
            +
                def lower_bound(range)
         | 
| 127 | 
            +
                  split_range(range)[0]
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                #
         | 
| 131 | 
            +
                # @param range [String] A string with an integer range format
         | 
| 132 | 
            +
                #
         | 
| 133 | 
            +
                # @return [String] The upper bound of the given range
         | 
| 134 | 
            +
                #
         | 
| 135 | 
            +
                def upper_bound(range)
         | 
| 136 | 
            +
                  split_range(range)[1]
         | 
| 137 | 
            +
                end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                #
         | 
| 140 | 
            +
                # @param str [String] A string with an integer range format
         | 
| 141 | 
            +
                #
         | 
| 142 | 
            +
                # @return [Array] The upper & lower bounds of the given range
         | 
| 143 | 
            +
                #
         | 
| 144 | 
            +
                def split_range(str)
         | 
| 145 | 
            +
                  str.split(/[-,]/)
         | 
| 146 | 
            +
                end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                extend Forwardable
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                def_delegators :source_file_formatter, :amend_final, :size, :max_line
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                def source_file_formatter
         | 
| 153 | 
            +
                  @source_file_formatter ||= SourceFileFormatter.new(
         | 
| 154 | 
            +
                    frame.file,
         | 
| 155 | 
            +
                    ->(n) { n == frame.line ? "=>" : "  " }
         | 
| 156 | 
            +
                  )
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
              end
         | 
| 159 | 
            +
            end
         | 
| @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
            require_relative "../helpers/eval"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Byebug
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              # Show methods of specific classes/modules/objects.
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              class MethodCommand < Command
         | 
| 11 | 
            +
                include Helpers::EvalHelper
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                self.allow_in_post_mortem = true
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def self.regexp
         | 
| 16 | 
            +
                  /^\s* m(?:ethod)? \s+ (i(:?nstance)?\s+)?/x
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def self.description
         | 
| 20 | 
            +
                  <<-DESCRIPTION
         | 
| 21 | 
            +
                    m[ethod] (i[nstance][ <obj>]|<class|module>)
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    #{short_description}
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    When invoked with "instance", shows instance methods of the object
         | 
| 26 | 
            +
                    specified as argument or of self no object was specified.
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    When invoked only with a class or module, shows class methods of the
         | 
| 29 | 
            +
                    class or module specified as argument.
         | 
| 30 | 
            +
                  DESCRIPTION
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def self.short_description
         | 
| 34 | 
            +
                  "Shows methods of an object, class or module"
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def execute
         | 
| 38 | 
            +
                  obj = warning_eval(@match.post_match)
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  result =
         | 
| 41 | 
            +
                    if @match[1]
         | 
| 42 | 
            +
                      prc("method.methods", obj.methods.sort) { |item, _| { name: item } }
         | 
| 43 | 
            +
                    elsif !obj.is_a?(Module)
         | 
| 44 | 
            +
                      pr("variable.errors.not_module", object: @match.post_match)
         | 
| 45 | 
            +
                    else
         | 
| 46 | 
            +
                      prc("method.methods", obj.instance_methods(false).sort) do |item, _|
         | 
| 47 | 
            +
                        { name: item }
         | 
| 48 | 
            +
                      end
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
                  puts result
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
            require_relative "../helpers/parse"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Byebug
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              # Implements the next functionality.
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              # Allows the user the continue execution until the next instruction in the
         | 
| 11 | 
            +
              # current frame.
         | 
| 12 | 
            +
              #
         | 
| 13 | 
            +
              class NextCommand < Command
         | 
| 14 | 
            +
                include Helpers::ParseHelper
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def self.regexp
         | 
| 17 | 
            +
                  /^\s* n(?:ext)? (?:\s+(\S+))? \s*$/x
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def self.description
         | 
| 21 | 
            +
                  <<-DESCRIPTION
         | 
| 22 | 
            +
                    n[ext][ nnn]
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    #{short_description}
         | 
| 25 | 
            +
                  DESCRIPTION
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def self.short_description
         | 
| 29 | 
            +
                  "Runs one or more lines of code"
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def execute
         | 
| 33 | 
            +
                  steps, err = parse_steps(@match[1], "Next")
         | 
| 34 | 
            +
                  return errmsg(err) unless steps
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  context.step_over(steps, context.frame.pos)
         | 
| 37 | 
            +
                  processor.proceed!
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
            require_relative "../helpers/eval"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Byebug
         | 
| 7 | 
            +
              #
         | 
| 8 | 
            +
              # Enter Pry from byebug's prompt
         | 
| 9 | 
            +
              #
         | 
| 10 | 
            +
              class PryCommand < Command
         | 
| 11 | 
            +
                self.allow_in_post_mortem = true
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def self.regexp
         | 
| 14 | 
            +
                  /^\s* pry \s*$/x
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def self.description
         | 
| 18 | 
            +
                  <<-DESCRIPTION
         | 
| 19 | 
            +
                    pry
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    #{short_description}
         | 
| 22 | 
            +
                  DESCRIPTION
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def self.short_description
         | 
| 26 | 
            +
                  "Starts a Pry session"
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def execute
         | 
| 30 | 
            +
                  return errmsg(pr("base.errors.only_local")) unless processor.interface.instance_of?(LocalInterface)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  begin
         | 
| 33 | 
            +
                    require "pry"
         | 
| 34 | 
            +
                  rescue LoadError
         | 
| 35 | 
            +
                    return errmsg(pr("pry.errors.not_installed"))
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  Pry.start(context.frame._binding)
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Byebug
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              # Exit from byebug.
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              class QuitCommand < Command
         | 
| 10 | 
            +
                self.allow_in_control = true
         | 
| 11 | 
            +
                self.allow_in_post_mortem = true
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def self.regexp
         | 
| 14 | 
            +
                  /^\s* q(?:uit)? \s* (?:(!|\s+unconditionally))? \s*$/x
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def self.description
         | 
| 18 | 
            +
                  <<-DESCRIPTION
         | 
| 19 | 
            +
                    q[uit][!| unconditionally]
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    #{short_description}
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    Normally we prompt before exiting. However, if the parameter
         | 
| 24 | 
            +
                    "unconditionally" is given or command is suffixed with "!", we exit
         | 
| 25 | 
            +
                    without asking further questions.
         | 
| 26 | 
            +
                  DESCRIPTION
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def self.short_description
         | 
| 30 | 
            +
                  "Exits byebug"
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def execute
         | 
| 34 | 
            +
                  return unless @match[1] || confirm(pr("quit.confirmations.really"))
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  processor.interface.autosave
         | 
| 37 | 
            +
                  processor.interface.close
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  Process.exit!
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
            require_relative "../helpers/bin"
         | 
| 5 | 
            +
            require_relative "../helpers/path"
         | 
| 6 | 
            +
            require "shellwords"
         | 
| 7 | 
            +
            require "English"
         | 
| 8 | 
            +
            require "rbconfig"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            module Byebug
         | 
| 11 | 
            +
              #
         | 
| 12 | 
            +
              # Restart debugged program from within byebug.
         | 
| 13 | 
            +
              #
         | 
| 14 | 
            +
              class RestartCommand < Command
         | 
| 15 | 
            +
                include Helpers::BinHelper
         | 
| 16 | 
            +
                include Helpers::PathHelper
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                self.allow_in_control = true
         | 
| 19 | 
            +
                self.allow_in_post_mortem = true
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def self.regexp
         | 
| 22 | 
            +
                  /^\s* restart (?:\s+(?<args>.+))? \s*$/x
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def self.description
         | 
| 26 | 
            +
                  <<-DESCRIPTION
         | 
| 27 | 
            +
                    restart [args]
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    #{short_description}
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    This is a re-exec - all byebug state is lost. If command arguments are
         | 
| 32 | 
            +
                    passed those are used.
         | 
| 33 | 
            +
                  DESCRIPTION
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def self.short_description
         | 
| 37 | 
            +
                  "Restarts the debugged program"
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def execute
         | 
| 41 | 
            +
                  cmd = [$PROGRAM_NAME]
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  cmd = prepend_byebug_bin(cmd)
         | 
| 44 | 
            +
                  cmd = prepend_ruby_bin(cmd)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  cmd += (@match[:args] ? @match[:args].shellsplit : $ARGV)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  puts pr("restart.success", cmd: cmd.shelljoin)
         | 
| 49 | 
            +
                  Kernel.exec(*cmd)
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                private
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def prepend_byebug_bin(cmd)
         | 
| 55 | 
            +
                  cmd.unshift(bin_file) if Byebug.mode == :standalone
         | 
| 56 | 
            +
                  cmd
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def prepend_ruby_bin(cmd)
         | 
| 60 | 
            +
                  cmd.unshift(RbConfig.ruby) if which("ruby") != which(cmd.first)
         | 
| 61 | 
            +
                  cmd
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
            end
         | 
| @@ -0,0 +1,72 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative "../command"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Byebug
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              # Save current settings to use them in another debug session.
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              class SaveCommand < Command
         | 
| 10 | 
            +
                self.allow_in_control = true
         | 
| 11 | 
            +
                self.allow_in_post_mortem = true
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def self.regexp
         | 
| 14 | 
            +
                  /^\s* sa(?:ve)? (?:\s+(\S+))? \s*$/x
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def self.description
         | 
| 18 | 
            +
                  <<-DESCRIPTION
         | 
| 19 | 
            +
                    save[ FILE]
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    #{short_description}
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    Byebug state is saved as a script file. This includes breakpoints,
         | 
| 24 | 
            +
                    catchpoints, display expressions and some settings. If no filename is
         | 
| 25 | 
            +
                    given, byebug will fabricate one.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    Use the "source" command in another debug session to restore the saved
         | 
| 28 | 
            +
                    file.
         | 
| 29 | 
            +
                  DESCRIPTION
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def self.short_description
         | 
| 33 | 
            +
                  "Saves current byebug session to a file"
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def execute
         | 
| 37 | 
            +
                  file = File.open(@match[1] || Setting[:savefile], "w")
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  save_breakpoints(file)
         | 
| 40 | 
            +
                  save_catchpoints(file)
         | 
| 41 | 
            +
                  save_displays(file)
         | 
| 42 | 
            +
                  save_settings(file)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  print pr("save.messages.done", path: file.path)
         | 
| 45 | 
            +
                  file.close
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                private
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def save_breakpoints(file)
         | 
| 51 | 
            +
                  Byebug.breakpoints.each do |b|
         | 
| 52 | 
            +
                    file.puts "break #{b.source}:#{b.pos}#{" if #{b.expr}" if b.expr}"
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def save_catchpoints(file)
         | 
| 57 | 
            +
                  Byebug.catchpoints.each_key do |c|
         | 
| 58 | 
            +
                    file.puts "catch #{c}"
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def save_displays(file)
         | 
| 63 | 
            +
                  Byebug.displays.each { |d| file.puts "display #{d[1]}" if d[0] }
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def save_settings(file)
         | 
| 67 | 
            +
                  %w[autoirb autolist basename].each do |setting|
         | 
| 68 | 
            +
                    file.puts "set #{setting} #{Setting[setting.to_sym]}"
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
            end
         |