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,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+
5
+ module Byebug
6
+ #
7
+ # Edit a file from byebug's prompt.
8
+ #
9
+ class EditCommand < Command
10
+ self.allow_in_control = true
11
+ self.allow_in_post_mortem = true
12
+
13
+ def self.regexp
14
+ /^\s* ed(?:it)? (?:\s+(\S+))? \s*$/x
15
+ end
16
+
17
+ def self.description
18
+ <<-DESCRIPTION
19
+ edit[ file:lineno]
20
+
21
+ #{short_description}
22
+
23
+ With no argumnt, edits file containing most re line listed. Editing
24
+ targets can also be specified to start editing at a specific line in a
25
+ specific file
26
+ DESCRIPTION
27
+ end
28
+
29
+ def self.short_description
30
+ "Edits source files"
31
+ end
32
+
33
+ def execute
34
+ file, line = location(@match[1])
35
+ return edit_error("not_exist", file) unless File.exist?(file)
36
+ return edit_error("not_readable", file) unless File.readable?(file)
37
+
38
+ cmd = line ? "#{editor} +#{line} #{file}" : "#{editor} #{file}"
39
+
40
+ Kernel.system(cmd)
41
+ end
42
+
43
+ private
44
+
45
+ def location(matched)
46
+ if matched.nil?
47
+ file = frame.file
48
+ return errmsg(pr("edit.errors.state")) unless file
49
+
50
+ line = frame.line
51
+ elsif (@pos_match = /([^:]+)[:]([0-9]+)/.match(matched))
52
+ file, line = @pos_match.captures
53
+ else
54
+ file = matched
55
+ line = nil
56
+ end
57
+
58
+ [File.expand_path(file), line]
59
+ end
60
+
61
+ def editor
62
+ ENV["EDITOR"] || "vim"
63
+ end
64
+
65
+ def edit_error(type, file)
66
+ errmsg(pr("edit.errors.#{type}", file: file))
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../helpers/toggle"
4
+
5
+ module Byebug
6
+ #
7
+ # Reopens the +enable+ command to define the +breakpoints+ subcommand
8
+ #
9
+ class EnableCommand < Command
10
+ #
11
+ # Enables all or specific breakpoints
12
+ #
13
+ class BreakpointsCommand < Command
14
+ include Helpers::ToggleHelper
15
+
16
+ self.allow_in_post_mortem = true
17
+
18
+ def self.regexp
19
+ /^\s* b(?:reakpoints)? (?:\s+ (.+))? \s*$/x
20
+ end
21
+
22
+ def self.description
23
+ <<-DESCRIPTION
24
+ en[able] b[reakpoints][ <ids>]
25
+
26
+ #{short_description}
27
+
28
+ Give breakpoint numbers (separated by spaces) as arguments or no
29
+ argument at all if you want to enable every breakpoint.
30
+ DESCRIPTION
31
+ end
32
+
33
+ def self.short_description
34
+ "Enable all or specific breakpoints."
35
+ end
36
+
37
+ def execute
38
+ enable_disable_breakpoints("enable", @match[1])
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../helpers/toggle"
4
+
5
+ module Byebug
6
+ #
7
+ # Reopens the +enable+ command to define the +display+ subcommand
8
+ #
9
+ class EnableCommand < Command
10
+ #
11
+ # Enables all or specific displays
12
+ #
13
+ class DisplayCommand < Command
14
+ include Helpers::ToggleHelper
15
+
16
+ self.allow_in_post_mortem = true
17
+
18
+ def self.regexp
19
+ /^\s* d(?:isplay)? (?:\s+ (.+))? \s*$/x
20
+ end
21
+
22
+ def self.description
23
+ <<-DESCRIPTION
24
+ en[able] d[isplay][ <id1> <id2> .. <idn>]
25
+
26
+ #{short_description}
27
+
28
+ Arguments are the code numbers of the expressions to enable. Do "info
29
+ display" to see the current list of code numbers. If no arguments are
30
+ specified, all displays are enabled.
31
+ DESCRIPTION
32
+ end
33
+
34
+ def self.short_description
35
+ "Enables expressions to be displayed when program stops."
36
+ end
37
+
38
+ def execute
39
+ enable_disable_display("enable", @match[1])
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../subcommands"
4
+
5
+ require_relative "../commands/enable/breakpoints"
6
+ require_relative "../commands/enable/display"
7
+
8
+ module Byebug
9
+ #
10
+ # Enabling custom display expressions or breakpoints.
11
+ #
12
+ class EnableCommand < Command
13
+ include Subcommands
14
+
15
+ self.allow_in_post_mortem = true
16
+
17
+ def self.regexp
18
+ /^\s* en(?:able)? (?:\s+ (.+))? \s*$/x
19
+ end
20
+
21
+ def self.description
22
+ <<-DESCRIPTION
23
+ en[able][[ b[reakpoints]| d[isplay])][ n1[ n2[ ...[ nn]]]]]
24
+
25
+ #{short_description}
26
+ DESCRIPTION
27
+ end
28
+
29
+ def self.short_description
30
+ "Enables breakpoints or displays"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/parse"
5
+
6
+ module Byebug
7
+ #
8
+ # Implements the finish functionality.
9
+ #
10
+ # Allows the user to continue execution until certain frames are finished.
11
+ #
12
+ class FinishCommand < Command
13
+ include Helpers::ParseHelper
14
+
15
+ self.allow_in_post_mortem = false
16
+
17
+ def self.regexp
18
+ /^\s* fin(?:ish)? (?:\s+(\S+))? \s*$/x
19
+ end
20
+
21
+ def self.description
22
+ <<-DESCRIPTION
23
+ fin[ish][ n_frames]
24
+
25
+ #{short_description}
26
+
27
+ If no number is given, we run until the current frame returns. If a
28
+ number of frames `n_frames` is given, then we run until `n_frames`
29
+ return from the current position.
30
+ DESCRIPTION
31
+ end
32
+
33
+ def self.short_description
34
+ "Runs the program until frame returns"
35
+ end
36
+
37
+ def execute
38
+ if @match[1]
39
+ n_frames, err = get_int(@match[1], "finish", 0, max_frames - 1)
40
+ return errmsg(err) unless n_frames
41
+ else
42
+ n_frames = 1
43
+ end
44
+
45
+ force = n_frames.zero? ? true : false
46
+ context.step_out(context.frame.pos + n_frames, force)
47
+ context.frame = 0
48
+ processor.proceed!
49
+ end
50
+
51
+ private
52
+
53
+ def max_frames
54
+ context.stack_size - context.frame.pos
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require_relative "../command"
5
+ require_relative "../helpers/frame"
6
+ require_relative "../helpers/parse"
7
+
8
+ module Byebug
9
+ #
10
+ # Move to specific frames in the backtrace.
11
+ #
12
+ class FrameCommand < Command
13
+ include Helpers::FrameHelper
14
+ include Helpers::ParseHelper
15
+
16
+ self.allow_in_post_mortem = true
17
+
18
+ def self.regexp
19
+ /^\s* f(?:rame)? (?:\s+(\S+))? \s*$/x
20
+ end
21
+
22
+ def self.description
23
+ <<-DESCRIPTION
24
+ f[rame][ frame-number]
25
+
26
+ #{short_description}
27
+
28
+ If a frame number has been specified, to moves to that frame. Otherwise
29
+ it moves to the newest frame.
30
+
31
+ A negative number indicates position from the other end, so "frame -1"
32
+ moves to the oldest frame, and "frame 0" moves to the newest frame.
33
+
34
+ Without an argument, the command prints the current stack frame. Since
35
+ the current position is redisplayed, it may trigger a resyncronization
36
+ if there is a front end also watching over things.
37
+
38
+ Use the "bt" command to find out where you want to go.
39
+ DESCRIPTION
40
+ end
41
+
42
+ def self.short_description
43
+ "Moves to a frame in the call stack"
44
+ end
45
+
46
+ def execute
47
+ return print(pr("frame.line", context.frame.to_hash)) unless @match[1]
48
+
49
+ pos, err = get_int(@match[1], "Frame")
50
+ return errmsg(err) unless pos
51
+
52
+ switch_to_frame(pos)
53
+
54
+ ListCommand.new(processor).execute if Setting[:autolist]
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../errors"
5
+
6
+ module Byebug
7
+ #
8
+ # Ask for help from byebug's prompt.
9
+ #
10
+ class HelpCommand < Command
11
+ self.allow_in_control = true
12
+ self.allow_in_post_mortem = true
13
+
14
+ def self.regexp
15
+ /^\s* h(?:elp)? (?:\s+(\S+))? (?:\s+(\S+))? \s*$/x
16
+ end
17
+
18
+ def self.description
19
+ <<-DESCRIPTION
20
+ h[elp][ <cmd>[ <subcmd>]]
21
+
22
+ #{short_description}
23
+
24
+ help -- prints a summary of all commands
25
+ help <cmd> -- prints help on command <cmd>
26
+ help <cmd> <subcmd> -- prints help on <cmd>'s subcommand <subcmd>
27
+ DESCRIPTION
28
+ end
29
+
30
+ def self.short_description
31
+ "Helps you using byebug"
32
+ end
33
+
34
+ def execute
35
+ return help_for_all unless @match[1]
36
+
37
+ return help_for(@match[1], command) unless @match[2]
38
+
39
+ help_for(@match[2], subcommand)
40
+ end
41
+
42
+ private
43
+
44
+ def help_for_all
45
+ puts(processor.command_list.to_s)
46
+ end
47
+
48
+ def help_for(input, cmd)
49
+ raise CommandNotFound.new(input, command) unless cmd
50
+
51
+ puts(cmd.help)
52
+ end
53
+
54
+ def command
55
+ @command ||= processor.command_list.match(@match[1])
56
+ end
57
+
58
+ def subcommand
59
+ return unless command
60
+
61
+ @subcommand ||= command.subcommand_list.match(@match[2])
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/parse"
5
+
6
+ module Byebug
7
+ #
8
+ # Show history of byebug commands.
9
+ #
10
+ class HistoryCommand < Command
11
+ include Helpers::ParseHelper
12
+
13
+ self.allow_in_post_mortem = true
14
+
15
+ def self.regexp
16
+ /^\s* hist(?:ory)? (?:\s+(?<num_cmds>.+))? \s*$/x
17
+ end
18
+
19
+ def self.description
20
+ <<-DESCRIPTION
21
+ hist[ory][ num_cmds]
22
+
23
+ #{short_description}
24
+ DESCRIPTION
25
+ end
26
+
27
+ def self.short_description
28
+ "Shows byebug's history of commands"
29
+ end
30
+
31
+ def execute
32
+ history = processor.interface.history
33
+
34
+ size, = get_int(@match[:num_cmds], "history", 1) if @match[:num_cmds]
35
+
36
+ puts history.to_s(size)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Byebug
4
+ #
5
+ # Reopens the +info+ command to define the +breakpoints+ subcommand
6
+ #
7
+ class InfoCommand < Command
8
+ #
9
+ # Information about current breakpoints
10
+ #
11
+ class BreakpointsCommand < Command
12
+ self.allow_in_post_mortem = true
13
+
14
+ def self.regexp
15
+ /^\s* b(?:reakpoints)? (?:\s+ (.+))? \s*$/x
16
+ end
17
+
18
+ def self.description
19
+ <<-DESCRIPTION
20
+ inf[o] b[reakpoints]
21
+
22
+ #{short_description}
23
+ DESCRIPTION
24
+ end
25
+
26
+ def self.short_description
27
+ "Status of user settable breakpoints"
28
+ end
29
+
30
+ def execute
31
+ return puts("No breakpoints.") if Byebug.breakpoints.empty?
32
+
33
+ breakpoints = Byebug.breakpoints.sort_by(&:id)
34
+
35
+ if @match[1]
36
+ indices = @match[1].split(/ +/).map(&:to_i)
37
+ breakpoints = breakpoints.select { |b| indices.member?(b.id) }
38
+ return errmsg("No breakpoints found among list given") if breakpoints.empty?
39
+ end
40
+
41
+ puts "Num Enb What"
42
+ breakpoints.each { |b| info_breakpoint(b) }
43
+ end
44
+
45
+ private
46
+
47
+ def info_breakpoint(brkpt)
48
+ interp = format(
49
+ "%-<id>3d %-<status>3s at %<file>s:%<line>s%<expression>s",
50
+ id: brkpt.id,
51
+ status: brkpt.enabled? ? "y" : "n",
52
+ file: brkpt.source,
53
+ line: brkpt.pos,
54
+ expression: brkpt.expr.nil? ? "" : " if #{brkpt.expr}"
55
+ )
56
+ puts interp
57
+ hits = brkpt.hit_count
58
+ return unless hits.positive?
59
+
60
+ s = hits > 1 ? "s" : ""
61
+ puts " breakpoint already hit #{hits} time#{s}"
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Byebug
4
+ #
5
+ # Reopens the +info+ command to define the +display+ subcommand
6
+ #
7
+ class InfoCommand < Command
8
+ #
9
+ # Information about display expressions
10
+ #
11
+ class DisplayCommand < Command
12
+ self.allow_in_post_mortem = true
13
+
14
+ def self.regexp
15
+ /^\s* d(?:isplay)? \s*$/x
16
+ end
17
+
18
+ def self.description
19
+ <<-DESCRIPTION
20
+ inf[o] d[display]
21
+
22
+ #{short_description}
23
+ DESCRIPTION
24
+ end
25
+
26
+ def self.short_description
27
+ "List of expressions to display when program stops"
28
+ end
29
+
30
+ def execute
31
+ return puts("There are no auto-display expressions now.") unless Byebug.displays.find { |d| d[0] }
32
+
33
+ puts "Auto-display expressions now in effect:"
34
+ puts "Num Enb Expression"
35
+
36
+ Byebug.displays.each_with_index do |d, i|
37
+ interp = format(
38
+ "%<number>3d: %<status>s %<expression>s",
39
+ number: i + 1,
40
+ status: d[0] ? "y" : "n",
41
+ expression: d[1]
42
+ )
43
+
44
+ puts(interp)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../helpers/file"
4
+
5
+ module Byebug
6
+ #
7
+ # Reopens the +info+ command to define the +file+ subcommand
8
+ #
9
+ class InfoCommand < Command
10
+ #
11
+ # Information about a particular source file
12
+ #
13
+ class FileCommand < Command
14
+ include Helpers::FileHelper
15
+ include Helpers::StringHelper
16
+
17
+ self.allow_in_post_mortem = true
18
+
19
+ def self.regexp
20
+ /^\s* f(?:ile)? (?:\s+ (.+))? \s*$/x
21
+ end
22
+
23
+ def self.description
24
+ <<-DESCRIPTION
25
+ inf[o] f[ile]
26
+
27
+ #{short_description}
28
+
29
+ It informs about file name, number of lines, possible breakpoints in
30
+ the file, last modification time and sha1 digest.
31
+ DESCRIPTION
32
+ end
33
+
34
+ def self.short_description
35
+ "Information about a particular source file."
36
+ end
37
+
38
+ def execute
39
+ file = @match[1] || frame.file
40
+ return errmsg(pr("info.errors.undefined_file", file: file)) unless File.exist?(file)
41
+
42
+ puts prettify <<-RUBY
43
+ File #{info_file_basic(file)}
44
+
45
+ Breakpoint line numbers: #{info_file_breakpoints(file)}
46
+
47
+ Modification time: #{info_file_mtime(file)}
48
+
49
+ Sha1 Signature: #{info_file_sha1(file)}
50
+ RUBY
51
+ end
52
+
53
+ private
54
+
55
+ def info_file_basic(file)
56
+ path = File.expand_path(file)
57
+ return unless File.exist?(path)
58
+
59
+ s = n_lines(path) == 1 ? "" : "s"
60
+ "#{path} (#{n_lines(path)} line#{s})"
61
+ end
62
+
63
+ def info_file_breakpoints(file)
64
+ breakpoints = Breakpoint.potential_lines(file)
65
+ return unless breakpoints
66
+
67
+ breakpoints.to_a.sort.join(" ")
68
+ end
69
+
70
+ def info_file_mtime(file)
71
+ File.stat(file).mtime
72
+ end
73
+
74
+ def info_file_sha1(file)
75
+ require "digest/sha1"
76
+ Digest::SHA1.hexdigest(file)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Byebug
4
+ #
5
+ # Reopens the +info+ command to define the +line+ subcommand
6
+ #
7
+ class InfoCommand < Command
8
+ #
9
+ # Information about current location
10
+ #
11
+ class LineCommand < Command
12
+ self.allow_in_post_mortem = true
13
+
14
+ def self.regexp
15
+ /^\s* l(?:ine)? \s*$/x
16
+ end
17
+
18
+ def self.description
19
+ <<-DESCRIPTION
20
+ inf[o] l[ine]
21
+
22
+ #{short_description}
23
+ DESCRIPTION
24
+ end
25
+
26
+ def self.short_description
27
+ "Line number and file name of current position in source file."
28
+ end
29
+
30
+ def execute
31
+ puts "Line #{frame.line} of \"#{frame.file}\""
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Byebug
4
+ #
5
+ # Reopens the +info+ command to define the +args+ subcommand
6
+ #
7
+ class InfoCommand < Command
8
+ #
9
+ # Information about arguments of the current method/block
10
+ #
11
+ class ProgramCommand < Command
12
+ self.allow_in_post_mortem = true
13
+
14
+ def self.regexp
15
+ /^\s* p(?:rogram)? \s*$/x
16
+ end
17
+
18
+ def self.description
19
+ <<-DESCRIPTION
20
+ inf[o] p[rogram]
21
+
22
+ #{short_description}
23
+ DESCRIPTION
24
+ end
25
+
26
+ def self.short_description
27
+ "Information about the current status of the debugged program."
28
+ end
29
+
30
+ def execute
31
+ puts "Program stopped. "
32
+ format_stop_reason context.stop_reason
33
+ end
34
+
35
+ private
36
+
37
+ def format_stop_reason(stop_reason)
38
+ case stop_reason
39
+ when :step
40
+ puts "It stopped after stepping, next'ing or initial start."
41
+ when :breakpoint
42
+ puts "It stopped at a breakpoint."
43
+ when :catchpoint
44
+ puts "It stopped at a catchpoint."
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end