ruby-debug-ide19 0.4.10
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.
- data/CHANGES +75 -0
- data/ChangeLog +465 -0
- data/ChangeLog.archive +1073 -0
- data/MIT-LICENSE +24 -0
- data/Rakefile +110 -0
- data/bin/rdebug-ide +88 -0
- data/ext/mkrf_conf.rb +28 -0
- data/lib/ruby-debug-ide.rb +172 -0
- data/lib/ruby-debug/command.rb +169 -0
- data/lib/ruby-debug/commands/breakpoints.rb +129 -0
- data/lib/ruby-debug/commands/catchpoint.rb +52 -0
- data/lib/ruby-debug/commands/condition.rb +51 -0
- data/lib/ruby-debug/commands/control.rb +129 -0
- data/lib/ruby-debug/commands/enable.rb +203 -0
- data/lib/ruby-debug/commands/eval.rb +64 -0
- data/lib/ruby-debug/commands/frame.rb +155 -0
- data/lib/ruby-debug/commands/inspect.rb +24 -0
- data/lib/ruby-debug/commands/jump.rb +73 -0
- data/lib/ruby-debug/commands/load.rb +18 -0
- data/lib/ruby-debug/commands/stepping.rb +108 -0
- data/lib/ruby-debug/commands/threads.rb +153 -0
- data/lib/ruby-debug/commands/variables.rb +136 -0
- data/lib/ruby-debug/event_processor.rb +74 -0
- data/lib/ruby-debug/helper.rb +33 -0
- data/lib/ruby-debug/interface.rb +39 -0
- data/lib/ruby-debug/printers.rb +2 -0
- data/lib/ruby-debug/processor.rb +152 -0
- data/lib/ruby-debug/xml_printer.rb +268 -0
- data/test/rd_basic_test.rb +10 -0
- data/test/rd_catchpoint_test.rb +20 -0
- data/test/rd_condition_test.rb +11 -0
- data/test/rd_enable_disable_test.rb +43 -0
- data/test/rd_inspect_test.rb +11 -0
- data/test/rd_stepping_breakpoints_test.rb +36 -0
- data/test/rd_test_base.rb +44 -0
- data/test/rd_threads_and_frames_test.rb +11 -0
- data/test/rd_variables_test.rb +11 -0
- data/test/ruby-debug/xml_printer_test.rb +105 -0
- metadata +103 -0
@@ -0,0 +1,129 @@
|
|
1
|
+
module Debugger
|
2
|
+
class AddBreakpoint < Command # :nodoc:
|
3
|
+
self.control = true
|
4
|
+
|
5
|
+
def regexp
|
6
|
+
/ ^\s*
|
7
|
+
b(?:reak)?
|
8
|
+
(?: \s+
|
9
|
+
(?:
|
10
|
+
(\d+) |
|
11
|
+
(.+?)[:.#]([^.:\s]+)
|
12
|
+
))?
|
13
|
+
(?:\s+
|
14
|
+
if\s+(.+)
|
15
|
+
)?
|
16
|
+
$
|
17
|
+
/x
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute
|
21
|
+
if @match[1]
|
22
|
+
line, _, _, expr = @match.captures
|
23
|
+
else
|
24
|
+
_, file, line, expr = @match.captures
|
25
|
+
end
|
26
|
+
|
27
|
+
if file.nil?
|
28
|
+
file = File.basename(@state.file)
|
29
|
+
else
|
30
|
+
if line !~ /^\d+$/
|
31
|
+
klass = debug_silent_eval(file)
|
32
|
+
if klass && !klass.kind_of?(Module)
|
33
|
+
print_error "Unknown class #{file}"
|
34
|
+
throw :debug_error
|
35
|
+
end
|
36
|
+
file = klass.name if klass
|
37
|
+
else
|
38
|
+
file = File.expand_path(file) if file.index(File::SEPARATOR) || \
|
39
|
+
File::ALT_SEPARATOR && file.index(File::ALT_SEPARATOR)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if line =~ /^\d+$/
|
44
|
+
line = line.to_i
|
45
|
+
else
|
46
|
+
line = line.intern.id2name
|
47
|
+
end
|
48
|
+
|
49
|
+
b = Debugger.add_breakpoint file, line, expr
|
50
|
+
print_breakpoint_added b
|
51
|
+
end
|
52
|
+
|
53
|
+
class << self
|
54
|
+
def help_command
|
55
|
+
'break'
|
56
|
+
end
|
57
|
+
|
58
|
+
def help(cmd)
|
59
|
+
%{
|
60
|
+
b[reak] file:line [if expr]
|
61
|
+
b[reak] [file|class(:|.|#)]<line|method> [if expr] -
|
62
|
+
\tset breakpoint to some position, (optionally) if expr == true
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class BreakpointsCommand < Command # :nodoc:
|
69
|
+
self.control = true
|
70
|
+
|
71
|
+
def regexp
|
72
|
+
/^\s*b(?:reak)?$/
|
73
|
+
end
|
74
|
+
|
75
|
+
def execute
|
76
|
+
print_breakpoints Debugger.breakpoints
|
77
|
+
end
|
78
|
+
|
79
|
+
class << self
|
80
|
+
def help_command
|
81
|
+
'break'
|
82
|
+
end
|
83
|
+
|
84
|
+
def help(cmd)
|
85
|
+
%{
|
86
|
+
b[reak]\tlist breakpoints
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class DeleteBreakpointCommand < Command # :nodoc:
|
93
|
+
self.control = true
|
94
|
+
|
95
|
+
def regexp
|
96
|
+
/^\s*del(?:ete)?(?:\s+(.*))?$/
|
97
|
+
end
|
98
|
+
|
99
|
+
def execute
|
100
|
+
brkpts = @match[1]
|
101
|
+
unless brkpts
|
102
|
+
Debugger.breakpoints.clear
|
103
|
+
else
|
104
|
+
brkpts.split(/[ \t]+/).each do |pos|
|
105
|
+
pos = get_int(pos, "Delete", 1)
|
106
|
+
return unless pos
|
107
|
+
b = Debugger.remove_breakpoint(pos)
|
108
|
+
if b
|
109
|
+
print_breakpoint_deleted b
|
110
|
+
else
|
111
|
+
print_error "No breakpoint number %d\n", pos
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class << self
|
118
|
+
def help_command
|
119
|
+
'delete'
|
120
|
+
end
|
121
|
+
|
122
|
+
def help(cmd)
|
123
|
+
%{
|
124
|
+
del[ete][ nnn...]\tdelete some or all breakpoints
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Debugger
|
2
|
+
class CatchCommand < Command # :nodoc:
|
3
|
+
self.control = true
|
4
|
+
|
5
|
+
def regexp
|
6
|
+
/^\s* cat(?:ch)?
|
7
|
+
(?:\s+ (\S+))?
|
8
|
+
(?:\s+ (off))? \s* $/ix
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
excn = @match[1]
|
13
|
+
if not excn
|
14
|
+
# No args given.
|
15
|
+
errmsg "Exception class must be specified for 'catch' command"
|
16
|
+
elsif not @match[2]
|
17
|
+
# One arg given.
|
18
|
+
if 'off' == excn
|
19
|
+
Debugger.catchpoints.clear
|
20
|
+
else
|
21
|
+
binding = @state.context ? get_binding : TOPLEVEL_BINDING
|
22
|
+
unless debug_eval("#{excn}.is_a?(Class)", binding)
|
23
|
+
print_msg "Warning #{excn} is not known to be a Class"
|
24
|
+
end
|
25
|
+
Debugger.add_catchpoint(excn)
|
26
|
+
print_catchpoint_set(excn)
|
27
|
+
end
|
28
|
+
elsif @match[2] != 'off'
|
29
|
+
errmsg "Off expected. Got %s\n", @match[2]
|
30
|
+
elsif Debugger.catchpoints.member?(excn)
|
31
|
+
Debugger.catchpoints.delete(excn)
|
32
|
+
print_catchpoint_set(excn)
|
33
|
+
#print "Catch for exception %s removed.\n", excn
|
34
|
+
else
|
35
|
+
errmsg "Catch for exception %s not found.\n", excn
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def help_command
|
41
|
+
'catch'
|
42
|
+
end
|
43
|
+
|
44
|
+
def help(cmd)
|
45
|
+
%{
|
46
|
+
cat[ch]\t\t\tshow catchpoint
|
47
|
+
cat[ch] <an Exception>\tset catchpoint to an exception
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Debugger
|
2
|
+
|
3
|
+
class ConditionCommand < Command # :nodoc:
|
4
|
+
self.control = true
|
5
|
+
|
6
|
+
def regexp
|
7
|
+
/^\s* cond(?:ition)? (?:\s+(\d+)\s*(.*))?$/ix
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
if not @match[1]
|
12
|
+
errmsg "\"condition\" must be followed a breakpoint number and expression\n"
|
13
|
+
else
|
14
|
+
breakpoints = Debugger.breakpoints.sort_by{|b| b.id }
|
15
|
+
largest = breakpoints.inject(0) do |largest, b|
|
16
|
+
largest = b.id if b.id > largest
|
17
|
+
end
|
18
|
+
if 0 == largest
|
19
|
+
print "No breakpoints have been set.\n"
|
20
|
+
return
|
21
|
+
end
|
22
|
+
pos = get_int(@match[1], "Condition", 1, largest)
|
23
|
+
return unless pos
|
24
|
+
breakpoints.each do |b|
|
25
|
+
if b.id == pos
|
26
|
+
b.expr = @match[2].empty? ? nil : @match[2]
|
27
|
+
print_contdition_set(b.id)
|
28
|
+
break
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class << self
|
36
|
+
def help_command
|
37
|
+
'condition'
|
38
|
+
end
|
39
|
+
|
40
|
+
def help(cmd)
|
41
|
+
%{
|
42
|
+
Condition breakpoint-number expression
|
43
|
+
Specify breakpoint number N to break only if COND is true.
|
44
|
+
N is an integer and COND is an expression to be evaluated whenever
|
45
|
+
breakpoint N is reached. If the empty string is used, the condition is removed.
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end # module Debugger
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module Debugger
|
2
|
+
class QuitCommand < Command # :nodoc:
|
3
|
+
self.control = true
|
4
|
+
|
5
|
+
def regexp
|
6
|
+
/^\s*(?:q(?:uit)?|exit)\s*$/
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute
|
10
|
+
begin
|
11
|
+
@printer.print_msg("finished")
|
12
|
+
@printer.print_debug("Exiting debugger.")
|
13
|
+
ensure
|
14
|
+
exit! # exit -> exit!: No graceful way to stop threads...
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def help_command
|
20
|
+
%w[quit exit]
|
21
|
+
end
|
22
|
+
|
23
|
+
def help(cmd)
|
24
|
+
%{
|
25
|
+
q[uit]\texit from debugger,
|
26
|
+
exit\talias to quit
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class RestartCommand < Command # :nodoc:
|
33
|
+
self.control = true
|
34
|
+
|
35
|
+
def regexp
|
36
|
+
/ ^\s*
|
37
|
+
(restart|R)
|
38
|
+
(\s+ \S+ .*)?
|
39
|
+
$
|
40
|
+
/x
|
41
|
+
end
|
42
|
+
|
43
|
+
def execute
|
44
|
+
if not defined? Debugger::RDEBUG_SCRIPT or not defined? Debugger::ARGV
|
45
|
+
print "We are not in a context we can restart from.\n"
|
46
|
+
return
|
47
|
+
end
|
48
|
+
if @match[2]
|
49
|
+
args = Debugger::PROG_SCRIPT + " " + @match[2]
|
50
|
+
else
|
51
|
+
args = Debugger::ARGV.join(" ")
|
52
|
+
end
|
53
|
+
|
54
|
+
# An execv would be preferable to the "exec" below.
|
55
|
+
cmd = Debugger::RDEBUG_SCRIPT + " " + args
|
56
|
+
print "Re exec'ing:\n\t#{cmd}\n"
|
57
|
+
exec cmd
|
58
|
+
end
|
59
|
+
|
60
|
+
class << self
|
61
|
+
def help_command
|
62
|
+
'restart'
|
63
|
+
end
|
64
|
+
|
65
|
+
def help(cmd)
|
66
|
+
%{
|
67
|
+
restart|R [args]
|
68
|
+
Restart the program. This is is a re-exec - all debugger state
|
69
|
+
is lost. If command arguments are passed those are used.
|
70
|
+
}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class StartCommand < Command # :nodoc:
|
76
|
+
self.control = true
|
77
|
+
|
78
|
+
def regexp
|
79
|
+
/^\s*(start)(\s+ \S+ .*)?$/x
|
80
|
+
end
|
81
|
+
|
82
|
+
def execute
|
83
|
+
@printer.print_debug("Starting: running program script")
|
84
|
+
Debugger.run_prog_script #Debugger.prog_script_running?
|
85
|
+
end
|
86
|
+
|
87
|
+
class << self
|
88
|
+
def help_command
|
89
|
+
'start'
|
90
|
+
end
|
91
|
+
|
92
|
+
def help(cmd)
|
93
|
+
%{
|
94
|
+
run prog script
|
95
|
+
}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
class InterruptCommand < Command # :nodoc:
|
102
|
+
self.event = false
|
103
|
+
self.control = true
|
104
|
+
self.need_context = true
|
105
|
+
|
106
|
+
def regexp
|
107
|
+
/^\s*i(?:nterrupt)?\s*$/
|
108
|
+
end
|
109
|
+
|
110
|
+
def execute
|
111
|
+
unless Debugger.interrupt_last
|
112
|
+
context = Debugger.thread_context(Thread.main)
|
113
|
+
context.interrupt
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class << self
|
118
|
+
def help_command
|
119
|
+
'interrupt'
|
120
|
+
end
|
121
|
+
|
122
|
+
def help(cmd)
|
123
|
+
%{
|
124
|
+
i[nterrupt]\tinterrupt the program
|
125
|
+
}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
module Debugger
|
2
|
+
# Mix-in module to assist in command parsing.
|
3
|
+
module EnableDisableFunctions # :nodoc:
|
4
|
+
def enable_disable_breakpoints(is_enable, args)
|
5
|
+
breakpoints = Debugger.breakpoints.sort_by{|b| b.id }
|
6
|
+
largest = breakpoints.inject(0) do |largest, b|
|
7
|
+
largest = b.id if b.id > largest
|
8
|
+
end
|
9
|
+
if 0 == largest
|
10
|
+
errmsg "No breakpoints have been set.\n"
|
11
|
+
return
|
12
|
+
end
|
13
|
+
args.each do |pos|
|
14
|
+
pos = get_int(pos, "#{is_enable} breakpoints", 1, largest)
|
15
|
+
return nil unless pos
|
16
|
+
breakpoints.each do |b|
|
17
|
+
if b.id == pos
|
18
|
+
enabled = ("Enable" == is_enable)
|
19
|
+
if enabled
|
20
|
+
unless syntax_valid?(b.expr)
|
21
|
+
errmsg("Expression \"#{b.expr}\" syntactically incorrect; breakpoint remains disabled.\n")
|
22
|
+
break
|
23
|
+
end
|
24
|
+
end
|
25
|
+
b.enabled = enabled
|
26
|
+
enabled ? print_breakpoint_enabled(b) : print_breakpoint_disabled(b)
|
27
|
+
break
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def enable_disable_display(is_enable, args)
|
34
|
+
if 0 == @state.display.size
|
35
|
+
errmsg "No display expressions have been set.\n"
|
36
|
+
return
|
37
|
+
end
|
38
|
+
args.each do |pos|
|
39
|
+
pos = get_int(pos, "#{is_enable} display", 1, @state.display.size)
|
40
|
+
return nil unless pos
|
41
|
+
@state.display[pos-1][0] = ("Enable" == is_enable)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
class EnableCommand < Command # :nodoc:
|
48
|
+
Subcommands =
|
49
|
+
[
|
50
|
+
['breakpoints', 2, "Enable specified breakpoints",
|
51
|
+
"Give breakpoint numbers (separated by spaces) as arguments.
|
52
|
+
This is used to cancel the effect of the \"disable\" command."
|
53
|
+
],
|
54
|
+
['display', 2,
|
55
|
+
"Enable some expressions to be displayed when program stops",
|
56
|
+
"Arguments are the code numbers of the expressions to resume displaying.
|
57
|
+
Do \"info display\" to see current list of code numbers."],
|
58
|
+
].map do |name, min, short_help, long_help|
|
59
|
+
SubcmdStruct.new(name, min, short_help, long_help)
|
60
|
+
end unless defined?(Subcommands)
|
61
|
+
|
62
|
+
def regexp
|
63
|
+
/^\s* en(?:able)? (?:\s+(.*))?$/ix
|
64
|
+
end
|
65
|
+
|
66
|
+
def execute
|
67
|
+
if not @match[1]
|
68
|
+
errmsg "\"enable\" must be followed \"display\", \"breakpoints\"" +
|
69
|
+
" or breakpoint numbers.\n"
|
70
|
+
else
|
71
|
+
args = @match[1].split(/[ \t]+/)
|
72
|
+
param = args.shift
|
73
|
+
subcmd = find(Subcommands, param)
|
74
|
+
if subcmd
|
75
|
+
send("enable_#{subcmd.name}", args)
|
76
|
+
else
|
77
|
+
send("enable_breakpoints", args.unshift(param))
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def enable_breakpoints(args)
|
83
|
+
enable_disable_breakpoints("Enable", args)
|
84
|
+
end
|
85
|
+
|
86
|
+
def enable_display(args)
|
87
|
+
enable_disable_display("Enable", args)
|
88
|
+
end
|
89
|
+
|
90
|
+
class << self
|
91
|
+
def help_command
|
92
|
+
'enable'
|
93
|
+
end
|
94
|
+
|
95
|
+
def help(args)
|
96
|
+
if args[1]
|
97
|
+
s = args[1]
|
98
|
+
subcmd = Subcommands.find do |try_subcmd|
|
99
|
+
(s.size >= try_subcmd.min) and
|
100
|
+
(try_subcmd.name[0..s.size-1] == s)
|
101
|
+
end
|
102
|
+
if subcmd
|
103
|
+
str = subcmd.short_help + '.'
|
104
|
+
str += "\n" + subcmd.long_help if subcmd.long_help
|
105
|
+
return str
|
106
|
+
else
|
107
|
+
return "Invalid 'enable' subcommand '#{args[1]}'."
|
108
|
+
end
|
109
|
+
end
|
110
|
+
s = %{
|
111
|
+
Enable some things.
|
112
|
+
This is used to cancel the effect of the "disable" command.
|
113
|
+
--
|
114
|
+
List of enable subcommands:
|
115
|
+
--
|
116
|
+
}
|
117
|
+
for subcmd in Subcommands do
|
118
|
+
s += "enable #{subcmd.name} -- #{subcmd.short_help}\n"
|
119
|
+
end
|
120
|
+
return s
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class DisableCommand < Command # :nodoc:
|
126
|
+
Subcommands =
|
127
|
+
[
|
128
|
+
['breakpoints', 1, "Disable some breakpoints",
|
129
|
+
"Arguments are breakpoint numbers with spaces in between.
|
130
|
+
A disabled breakpoint is not forgotten, but has no effect until reenabled."],
|
131
|
+
['display', 1, "Disable some display expressions when program stops",
|
132
|
+
"Arguments are the code numbers of the expressions to stop displaying.
|
133
|
+
Do \"info display\" to see current list of code numbers."],
|
134
|
+
].map do |name, min, short_help, long_help|
|
135
|
+
SubcmdStruct.new(name, min, short_help, long_help)
|
136
|
+
end unless defined?(Subcommands)
|
137
|
+
|
138
|
+
def regexp
|
139
|
+
/^\s* dis(?:able)? (?:\s+(.*))?$/ix
|
140
|
+
end
|
141
|
+
|
142
|
+
def execute
|
143
|
+
if not @match[1]
|
144
|
+
errmsg "\"disable\" must be followed \"display\", \"breakpoints\"" +
|
145
|
+
" or breakpoint numbers.\n"
|
146
|
+
else
|
147
|
+
args = @match[1].split(/[ \t]+/)
|
148
|
+
param = args.shift
|
149
|
+
subcmd = find(Subcommands, param)
|
150
|
+
if subcmd
|
151
|
+
send("disable_#{subcmd.name}", args)
|
152
|
+
else
|
153
|
+
send("disable_breakpoints", args.unshift(param))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def disable_breakpoints(args)
|
159
|
+
enable_disable_breakpoints("Disable", args)
|
160
|
+
end
|
161
|
+
|
162
|
+
def disable_display(args)
|
163
|
+
enable_disable_display("Disable", args)
|
164
|
+
end
|
165
|
+
|
166
|
+
class << self
|
167
|
+
def help_command
|
168
|
+
'disable'
|
169
|
+
end
|
170
|
+
|
171
|
+
def help(args)
|
172
|
+
if args[1]
|
173
|
+
s = args[1]
|
174
|
+
subcmd = Subcommands.find do |try_subcmd|
|
175
|
+
(s.size >= try_subcmd.min) and
|
176
|
+
(try_subcmd.name[0..s.size-1] == s)
|
177
|
+
end
|
178
|
+
if subcmd
|
179
|
+
str = subcmd.short_help + '.'
|
180
|
+
str += "\n" + subcmd.long_help if subcmd.long_help
|
181
|
+
return str
|
182
|
+
else
|
183
|
+
return "Invalid 'disable' subcommand '#{args[1]}'."
|
184
|
+
end
|
185
|
+
end
|
186
|
+
s = %{
|
187
|
+
Disable some things.
|
188
|
+
|
189
|
+
A disabled item is not forgotten, but has no effect until reenabled.
|
190
|
+
Use the "enable" command to have it take effect again.
|
191
|
+
--
|
192
|
+
List of disable subcommands:
|
193
|
+
--
|
194
|
+
}
|
195
|
+
for subcmd in Subcommands do
|
196
|
+
s += "disable #{subcmd.name} -- #{subcmd.short_help}\n"
|
197
|
+
end
|
198
|
+
return s
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end # module Debugger
|