byebug 11.0.1
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 +897 -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 +517 -0
- data/ext/byebug/byebug.c +905 -0
- data/ext/byebug/byebug.h +143 -0
- data/ext/byebug/context.c +673 -0
- data/ext/byebug/extconf.rb +12 -0
- data/ext/byebug/locker.c +96 -0
- data/ext/byebug/threads.c +230 -0
- data/lib/byebug.rb +3 -0
- data/lib/byebug/attacher.rb +48 -0
- data/lib/byebug/breakpoint.rb +111 -0
- data/lib/byebug/command.rb +111 -0
- data/lib/byebug/command_list.rb +34 -0
- data/lib/byebug/commands.rb +40 -0
- data/lib/byebug/commands/break.rb +112 -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.rb +33 -0
- data/lib/byebug/commands/disable/breakpoints.rb +42 -0
- data/lib/byebug/commands/disable/display.rb +43 -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.rb +33 -0
- data/lib/byebug/commands/enable/breakpoints.rb +42 -0
- data/lib/byebug/commands/enable/display.rb +43 -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.rb +37 -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/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.rb +34 -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/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.rb +37 -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/where.rb +53 -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 +126 -0
- data/lib/byebug/helpers/file.rb +63 -0
- data/lib/byebug/helpers/frame.rb +75 -0
- data/lib/byebug/helpers/parse.rb +75 -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 +54 -0
- data/lib/byebug/history.rb +130 -0
- data/lib/byebug/interface.rb +146 -0
- data/lib/byebug/interfaces/local_interface.rb +44 -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.rb +85 -0
- data/lib/byebug/remote/client.rb +57 -0
- data/lib/byebug/remote/server.rb +47 -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
- metadata +199 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "byebug/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,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "byebug/command"
|
4
|
+
require "byebug/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 "byebug/command"
|
5
|
+
require "byebug/helpers/frame"
|
6
|
+
require "byebug/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 "byebug/command"
|
4
|
+
require "byebug/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 "byebug/command"
|
4
|
+
require "byebug/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,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "byebug/subcommands"
|
4
|
+
|
5
|
+
require "byebug/commands/info/breakpoints"
|
6
|
+
require "byebug/commands/info/display"
|
7
|
+
require "byebug/commands/info/file"
|
8
|
+
require "byebug/commands/info/line"
|
9
|
+
require "byebug/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 several informations about the program being debugged"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
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 "byebug/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
|