byebug 11.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,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
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "byebug/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 "byebug/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 "byebug/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 "byebug/command"
|
4
|
+
require "byebug/source_file_formatter"
|
5
|
+
require "byebug/helpers/file"
|
6
|
+
require "byebug/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 "byebug/command"
|
4
|
+
require "byebug/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 "byebug/command"
|
4
|
+
require "byebug/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
|