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,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/eval"
5
+ require_relative "../helpers/file"
6
+ require_relative "../helpers/parse"
7
+ require_relative "../source_file_formatter"
8
+
9
+ module Byebug
10
+ #
11
+ # Implements breakpoint functionality
12
+ #
13
+ class BreakCommand < Command
14
+ include Helpers::EvalHelper
15
+ include Helpers::FileHelper
16
+ include Helpers::ParseHelper
17
+
18
+ self.allow_in_control = true
19
+
20
+ def self.regexp
21
+ /^\s* b(?:reak)? (?:\s+ (.+?))? (?:\s+ if \s+(.+))? \s*$/x
22
+ end
23
+
24
+ def self.description
25
+ <<-DESCRIPTION
26
+ b[reak] [[<file>:]<line> [if <expr>]]
27
+ b[reak] [<module>::...]<class>(.|#)<method> [if <expr>]
28
+
29
+ #{short_description}
30
+
31
+ They can be specified by line or method and an expression can be added
32
+ for conditionally enabled breakpoints.
33
+ for conditionally enabled breakpoints. Without arguments create a
34
+ a breakpoint in the current line.
35
+ DESCRIPTION
36
+ end
37
+
38
+ def self.short_description
39
+ "Sets breakpoints in the source code"
40
+ end
41
+
42
+ def execute
43
+ b = line_breakpoint(frame.line.to_s) unless @match[1]
44
+
45
+ b ||= line_breakpoint(@match[1]) || method_breakpoint(@match[1])
46
+ return errmsg(pr("break.errors.location")) unless b
47
+
48
+ return puts(pr("break.created", id: b.id, file: b.source, line: b.pos)) if syntax_valid?(@match[2])
49
+
50
+ errmsg(pr("break.errors.expression", expr: @match[2]))
51
+ b.enabled = false
52
+ end
53
+
54
+ private
55
+
56
+ def line_breakpoint(location)
57
+ line_match = location.match(/^(\d+)$/)
58
+ file_line_match = location.match(/^(.+):(\d+)$/)
59
+ return unless line_match || file_line_match
60
+
61
+ file = line_match ? frame.file : file_line_match[1]
62
+ line = line_match ? line_match[1].to_i : file_line_match[2].to_i
63
+
64
+ add_line_breakpoint(file, line)
65
+ end
66
+
67
+ def method_breakpoint(location)
68
+ location.match(/([^.#]+)[.#](.+)/) do |match|
69
+ klass = target_object(match[1])
70
+ method = match[2].intern
71
+
72
+ Breakpoint.add(klass, method, @match[2])
73
+ end
74
+ end
75
+
76
+ def target_object(str)
77
+ k = error_eval(str)
78
+
79
+ k&.is_a?(Module) ? k.name : str
80
+ rescue StandardError
81
+ errmsg("Warning: breakpoint source is not yet defined")
82
+ str
83
+ end
84
+
85
+ def add_line_breakpoint(file, line)
86
+ raise(pr("break.errors.source", file: file)) unless File.exist?(file)
87
+
88
+ fullpath = File.realpath(file)
89
+
90
+ raise(pr("break.errors.far_line", lines: n_lines(file), file: fullpath)) if line > n_lines(file)
91
+
92
+ unless Breakpoint.potential_line?(fullpath, line)
93
+ msg = pr(
94
+ "break.errors.line",
95
+ file: fullpath,
96
+ line: line,
97
+ valid_breakpoints: valid_breakpoints_for(fullpath, line)
98
+ )
99
+
100
+ raise(msg)
101
+ end
102
+
103
+ Breakpoint.add(fullpath, line, @match[2])
104
+ end
105
+
106
+ def valid_breakpoints_for(path, line)
107
+ potential_lines = Breakpoint.potential_lines(path)
108
+ annotator = ->(n) { potential_lines.include?(n) ? "[B]" : " " }
109
+ source_file_formatter = SourceFileFormatter.new(path, annotator)
110
+
111
+ source_file_formatter.lines_around(line).join.chomp
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/eval"
5
+
6
+ module Byebug
7
+ #
8
+ # Implements exception catching.
9
+ #
10
+ # Enables the user to catch unhandled assertion when they happen.
11
+ #
12
+ class CatchCommand < Command
13
+ include Helpers::EvalHelper
14
+
15
+ self.allow_in_post_mortem = true
16
+
17
+ def self.regexp
18
+ /^\s* cat(?:ch)? (?:\s+(\S+))? (?:\s+(off))? \s*$/x
19
+ end
20
+
21
+ def self.description
22
+ <<-DESCRIPTION
23
+ cat[ch][ (off|<exception>[ off])]
24
+
25
+ #{short_description}
26
+
27
+ catch -- lists catchpoints
28
+ catch off -- deletes all catchpoints
29
+ catch <exception> -- enables handling <exception>
30
+ catch <exception> off -- disables handling <exception>
31
+ DESCRIPTION
32
+ end
33
+
34
+ def self.short_description
35
+ "Handles exception catchpoints"
36
+ end
37
+
38
+ def execute
39
+ return info unless @match[1]
40
+
41
+ return @match[1] == "off" ? clear : add(@match[1]) unless @match[2]
42
+
43
+ return errmsg pr("catch.errors.off", off: cmd) unless @match[2] == "off"
44
+
45
+ remove(@match[1])
46
+ end
47
+
48
+ private
49
+
50
+ def remove(exception)
51
+ return errmsg pr("catch.errors.not_found", exception: exception) unless Byebug.catchpoints.member?(exception)
52
+
53
+ puts pr("catch.removed", exception: exception)
54
+ Byebug.catchpoints.delete(exception)
55
+ end
56
+
57
+ def add(exception)
58
+ errmsg pr("catch.errors.not_class", class: exception) if warning_eval(exception.is_a?(Class).to_s)
59
+
60
+ puts pr("catch.added", exception: exception)
61
+ Byebug.add_catchpoint(exception)
62
+ end
63
+
64
+ def clear
65
+ Byebug.catchpoints.clear if confirm(pr("catch.confirmations.delete_all"))
66
+ end
67
+
68
+ def info
69
+ if Byebug.catchpoints && !Byebug.catchpoints.empty?
70
+ Byebug.catchpoints.each_key do |exception|
71
+ puts("#{exception}: #{exception.is_a?(Class)}")
72
+ end
73
+ else
74
+ puts "No exceptions set to be caught."
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/parse"
5
+
6
+ module Byebug
7
+ #
8
+ # Implements conditions on breakpoints.
9
+ #
10
+ # Adds the ability to stop on breakpoints only under certain conditions.
11
+ #
12
+ class ConditionCommand < Command
13
+ include Helpers::ParseHelper
14
+
15
+ self.allow_in_post_mortem = true
16
+
17
+ def self.regexp
18
+ /^\s* cond(?:ition)? (?:\s+(\d+)(?:\s+(.*))?)? \s*$/x
19
+ end
20
+
21
+ def self.description
22
+ <<-DESCRIPTION
23
+ cond[ition] <n>[ expr]
24
+
25
+ #{short_description}
26
+
27
+ Specify breakpoint number <n> to break only if <expr> is true. <n> is
28
+ an integer and <expr> is an expression to be evaluated whenever
29
+ breakpoint <n> is reached. If no expression is specified, the condition
30
+ is removed.
31
+ DESCRIPTION
32
+ end
33
+
34
+ def self.short_description
35
+ "Sets conditions on breakpoints"
36
+ end
37
+
38
+ def execute
39
+ return puts(help) unless @match[1]
40
+
41
+ breakpoints = Byebug.breakpoints.sort_by(&:id)
42
+ return errmsg(pr("condition.errors.no_breakpoints")) if breakpoints.empty?
43
+
44
+ pos, err = get_int(@match[1], "Condition", 1)
45
+ return errmsg(err) if err
46
+
47
+ breakpoint = breakpoints.find { |b| b.id == pos }
48
+ return errmsg(pr("break.errors.no_breakpoint")) unless breakpoint
49
+
50
+ return errmsg(pr("break.errors.not_changed", expr: @match[2])) unless syntax_valid?(@match[2])
51
+
52
+ breakpoint.expr = @match[2]
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/parse"
5
+
6
+ module Byebug
7
+ #
8
+ # Implements the continue command.
9
+ #
10
+ # Allows the user to continue execution until the next stopping point, a
11
+ # specific line number or until program termination.
12
+ #
13
+ class ContinueCommand < Command
14
+ include Helpers::ParseHelper
15
+
16
+ def self.regexp
17
+ /^\s* c(?:ont(?:inue)?)? (?:(!|\s+unconditionally|\s+\S+))? \s*$/x
18
+ end
19
+
20
+ def self.description
21
+ <<-DESCRIPTION
22
+ c[ont[inue]][ <line_number>]
23
+
24
+ #{short_description}
25
+
26
+ Normally the program stops at the next breakpoint. However, if the
27
+ parameter "unconditionally" is given or the command is suffixed with
28
+ "!", the program will run until the end regardless of any enabled
29
+ breakpoints.
30
+ DESCRIPTION
31
+ end
32
+
33
+ def self.short_description
34
+ "Runs until program ends, hits a breakpoint or reaches a line"
35
+ end
36
+
37
+ def execute
38
+ if until_line?
39
+ num, err = get_int(modifier, "Continue", 0, nil)
40
+ return errmsg(err) unless num
41
+
42
+ filename = File.expand_path(frame.file)
43
+ return errmsg(pr("continue.errors.unstopped_line", line: num)) unless Breakpoint.potential_line?(filename, num)
44
+
45
+ Breakpoint.add(filename, num)
46
+ end
47
+
48
+ processor.proceed!
49
+
50
+ Byebug.mode = :off if unconditionally?
51
+ Byebug.stop if unconditionally? || Byebug.stoppable?
52
+ end
53
+
54
+ private
55
+
56
+ def until_line?
57
+ @match[1] && !["!", "unconditionally"].include?(modifier)
58
+ end
59
+
60
+ def unconditionally?
61
+ @match[1] && ["!", "unconditionally"].include?(modifier)
62
+ end
63
+
64
+ def modifier
65
+ @match[1].lstrip
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/eval"
5
+
6
+ module Byebug
7
+ #
8
+ # Spawns a subdebugger and evaluates the given expression
9
+ #
10
+ class DebugCommand < Command
11
+ include Helpers::EvalHelper
12
+
13
+ def self.regexp
14
+ /^\s* debug (?:\s+(\S+))? \s*$/x
15
+ end
16
+
17
+ def self.description
18
+ <<-DESCRIPTION
19
+ debug <expression>
20
+
21
+ #{short_description}
22
+
23
+ Allows, for example, setting breakpoints on expressions evaluated from
24
+ the debugger's prompt.
25
+ DESCRIPTION
26
+ end
27
+
28
+ def self.short_description
29
+ "Spawns a subdebugger"
30
+ end
31
+
32
+ def execute
33
+ return puts(help) unless @match[1]
34
+
35
+ puts safe_inspect(separate_thread_eval(@match[1]))
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/parse"
5
+
6
+ module Byebug
7
+ #
8
+ # Implements breakpoint deletion.
9
+ #
10
+ class DeleteCommand < Command
11
+ include Helpers::ParseHelper
12
+
13
+ self.allow_in_control = true
14
+ self.allow_in_post_mortem = true
15
+
16
+ def self.regexp
17
+ /^\s* del(?:ete)? (?:\s+(.*))?$/x
18
+ end
19
+
20
+ def self.description
21
+ <<-DESCRIPTION
22
+ del[ete][ nnn...]
23
+
24
+ #{short_description}
25
+
26
+ Without and argument, deletes all breakpoints. With integer arguments,
27
+ it deletes specific breakpoints.
28
+ DESCRIPTION
29
+ end
30
+
31
+ def self.short_description
32
+ "Deletes breakpoints"
33
+ end
34
+
35
+ def execute
36
+ unless @match[1]
37
+ Byebug.breakpoints.clear if confirm(pr("break.confirmations.delete_all"))
38
+
39
+ return
40
+ end
41
+
42
+ @match[1].split(/ +/).each do |number|
43
+ pos, err = get_int(number, "Delete", 1)
44
+
45
+ return errmsg(err) unless pos
46
+
47
+ if Breakpoint.remove(pos)
48
+ puts(pr("break.messages.breakpoint_deleted", pos: pos))
49
+ else
50
+ errmsg(pr("break.errors.no_breakpoint_delete", pos: pos))
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../helpers/toggle"
4
+
5
+ module Byebug
6
+ #
7
+ # Reopens the +disable+ command to define the +breakpoints+ subcommand
8
+ #
9
+ class DisableCommand < Command
10
+ #
11
+ # Disables 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
+ dis[able] b[reakpoints][ <id1> <id2> .. <idn>]
25
+
26
+ #{short_description}
27
+
28
+ Give breakpoint numbers (separated by spaces) as arguments or no
29
+ argument at all if you want to disable every breakpoint.
30
+ DESCRIPTION
31
+ end
32
+
33
+ def self.short_description
34
+ "Disable all or specific breakpoints."
35
+ end
36
+
37
+ def execute
38
+ enable_disable_breakpoints("disable", @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 +disable+ command to define the +display+ subcommand
8
+ #
9
+ class DisableCommand < 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
+ dis[able] d[isplay][ <id1> <id2> .. <idn>]
25
+
26
+ #{short_description}
27
+
28
+ Arguments are the code numbers of the expressions to disable. Do "info
29
+ display" to see the current list of code numbers. If no arguments are
30
+ specified, all displays are disabled.
31
+ DESCRIPTION
32
+ end
33
+
34
+ def self.short_description
35
+ "Disables expressions to be displayed when program stops."
36
+ end
37
+
38
+ def execute
39
+ enable_disable_display("disable", @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/disable/breakpoints"
6
+ require_relative "../commands/disable/display"
7
+
8
+ module Byebug
9
+ #
10
+ # Disabling custom display expressions or breakpoints.
11
+ #
12
+ class DisableCommand < Command
13
+ include Subcommands
14
+
15
+ self.allow_in_post_mortem = true
16
+
17
+ def self.regexp
18
+ /^\s* dis(?:able)? (?:\s+ (.+))? \s*$/x
19
+ end
20
+
21
+ def self.description
22
+ <<-DESCRIPTION
23
+ dis[able][[ breakpoints| display)][ n1[ n2[ ...[ nn]]]]]
24
+
25
+ #{short_description}
26
+ DESCRIPTION
27
+ end
28
+
29
+ def self.short_description
30
+ "Disables breakpoints or displays"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+ require_relative "../helpers/eval"
5
+
6
+ module Byebug
7
+ #
8
+ # Custom expressions to be displayed every time the debugger stops.
9
+ #
10
+ class DisplayCommand < Command
11
+ include Helpers::EvalHelper
12
+
13
+ self.allow_in_post_mortem = false
14
+ self.always_run = 2
15
+
16
+ def self.regexp
17
+ /^\s* disp(?:lay)? (?:\s+ (.+))? \s*$/x
18
+ end
19
+
20
+ def self.description
21
+ <<-DESCRIPTION
22
+ disp[lay][ <expression>]
23
+
24
+ #{short_description}
25
+
26
+ If <expression> specified, adds <expression> into display expression
27
+ list. Otherwise, it lists all expressions.
28
+ DESCRIPTION
29
+ end
30
+
31
+ def self.short_description
32
+ "Evaluates expressions every time the debugger stops"
33
+ end
34
+
35
+ def execute
36
+ return print_display_expressions unless @match && @match[1]
37
+
38
+ Byebug.displays.push [true, @match[1]]
39
+ display_expression(@match[1])
40
+ end
41
+
42
+ private
43
+
44
+ def display_expression(exp)
45
+ print pr("display.result", n: Byebug.displays.size,
46
+ exp: exp,
47
+ result: eval_expr(exp))
48
+ end
49
+
50
+ def print_display_expressions
51
+ result = prc("display.result", Byebug.displays) do |item, index|
52
+ active, exp = item
53
+
54
+ { n: index + 1, exp: exp, result: eval_expr(exp) } if active
55
+ end
56
+
57
+ print result
58
+ end
59
+
60
+ def eval_expr(expression)
61
+ error_eval(expression).inspect
62
+ rescue StandardError
63
+ "(undefined)"
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,45 @@
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 the current frame down in the backtrace.
11
+ #
12
+ class DownCommand < Command
13
+ include Helpers::FrameHelper
14
+ include Helpers::ParseHelper
15
+
16
+ self.allow_in_post_mortem = true
17
+
18
+ def self.regexp
19
+ /^\s* down (?:\s+(\S+))? \s*$/x
20
+ end
21
+
22
+ def self.description
23
+ <<-DESCRIPTION
24
+ down[ count]
25
+
26
+ #{short_description}
27
+
28
+ Use the "bt" command to find out where you want to go.
29
+ DESCRIPTION
30
+ end
31
+
32
+ def self.short_description
33
+ "Moves to a lower frame in the stack trace"
34
+ end
35
+
36
+ def execute
37
+ pos, err = parse_steps(@match[1], "Down")
38
+ return errmsg(err) unless pos
39
+
40
+ jump_frames(-pos)
41
+
42
+ ListCommand.new(processor).execute if Setting[:autolist]
43
+ end
44
+ end
45
+ end