ruby-debug193 0.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.
Files changed (40) hide show
  1. data/AUTHORS +10 -0
  2. data/LICENSE +23 -0
  3. data/bin/rdebug +398 -0
  4. data/cli/ruby-debug.rb +173 -0
  5. data/cli/ruby-debug/command.rb +228 -0
  6. data/cli/ruby-debug/commands/breakpoints.rb +153 -0
  7. data/cli/ruby-debug/commands/catchpoint.rb +55 -0
  8. data/cli/ruby-debug/commands/condition.rb +49 -0
  9. data/cli/ruby-debug/commands/continue.rb +38 -0
  10. data/cli/ruby-debug/commands/control.rb +107 -0
  11. data/cli/ruby-debug/commands/display.rb +120 -0
  12. data/cli/ruby-debug/commands/edit.rb +48 -0
  13. data/cli/ruby-debug/commands/enable.rb +202 -0
  14. data/cli/ruby-debug/commands/eval.rb +176 -0
  15. data/cli/ruby-debug/commands/finish.rb +42 -0
  16. data/cli/ruby-debug/commands/frame.rb +301 -0
  17. data/cli/ruby-debug/commands/help.rb +56 -0
  18. data/cli/ruby-debug/commands/info.rb +469 -0
  19. data/cli/ruby-debug/commands/irb.rb +123 -0
  20. data/cli/ruby-debug/commands/jump.rb +66 -0
  21. data/cli/ruby-debug/commands/kill.rb +51 -0
  22. data/cli/ruby-debug/commands/list.rb +94 -0
  23. data/cli/ruby-debug/commands/method.rb +84 -0
  24. data/cli/ruby-debug/commands/quit.rb +39 -0
  25. data/cli/ruby-debug/commands/reload.rb +40 -0
  26. data/cli/ruby-debug/commands/save.rb +90 -0
  27. data/cli/ruby-debug/commands/set.rb +237 -0
  28. data/cli/ruby-debug/commands/show.rb +253 -0
  29. data/cli/ruby-debug/commands/source.rb +36 -0
  30. data/cli/ruby-debug/commands/stepping.rb +81 -0
  31. data/cli/ruby-debug/commands/threads.rb +189 -0
  32. data/cli/ruby-debug/commands/tmate.rb +36 -0
  33. data/cli/ruby-debug/commands/trace.rb +57 -0
  34. data/cli/ruby-debug/commands/variables.rb +199 -0
  35. data/cli/ruby-debug/debugger.rb +5 -0
  36. data/cli/ruby-debug/helper.rb +69 -0
  37. data/cli/ruby-debug/interface.rb +232 -0
  38. data/cli/ruby-debug/processor.rb +474 -0
  39. data/rdbg.rb +33 -0
  40. metadata +144 -0
@@ -0,0 +1,40 @@
1
+ module Debugger
2
+ # Implements debugger "reload" command.
3
+ class ReloadCommand < Command
4
+ self.allow_in_control = true
5
+
6
+ register_setting_get(:reload_source_on_change) do
7
+ Debugger.reload_source_on_change
8
+ end
9
+ register_setting_set(:reload_source_on_change) do |value|
10
+ Debugger.reload_source_on_change = value
11
+ end
12
+
13
+ def regexp
14
+ /^\s*r(?:eload)?$/
15
+ end
16
+
17
+ def execute
18
+ Debugger.source_reload
19
+ print "Source code is reloaded. Automatic reloading is #{source_reloading}.\n"
20
+ end
21
+
22
+ private
23
+
24
+ def source_reloading
25
+ Debugger.reload_source_on_change ? 'on' : 'off'
26
+ end
27
+
28
+ class << self
29
+ def help_command
30
+ 'reload'
31
+ end
32
+
33
+ def help(cmd)
34
+ %{
35
+ r[eload]\tforces source code reloading
36
+ }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,90 @@
1
+ module Debugger
2
+ module SaveFunctions # :nodoc:
3
+
4
+ # Create a temporary file to write in if file is nil
5
+ def open_save
6
+ require "tempfile"
7
+ file = Tempfile.new("rdebug-save")
8
+ # We want close to not unlink, so redefine.
9
+ def file.close
10
+ @tmpfile.close if @tmpfile
11
+ end
12
+ return file
13
+ end
14
+ end
15
+
16
+ class SaveCommand < Command # :nodoc:
17
+ self.allow_in_control = true
18
+
19
+ def save_breakpoints(file)
20
+ Debugger.breakpoints.each do |b|
21
+ file.puts "break #{b.source}:#{b.pos}#{" if #{b.expr}" if b.expr}"
22
+ end
23
+ end
24
+
25
+ def save_catchpoints(file)
26
+ Debugger.catchpoints.keys.each do |c|
27
+ file.puts "catch #{c}"
28
+ end
29
+ end
30
+
31
+ def save_displays(file)
32
+ for d in @state.display
33
+ if d[0]
34
+ file.puts "display #{d[1]}"
35
+ end
36
+ end
37
+ end
38
+
39
+ def save_settings(file)
40
+ # FIXME put routine in set
41
+ %w(autoeval basename debuggertesting).each do |setting|
42
+ on_off = show_onoff(Command.settings[setting.to_sym])
43
+ file.puts "set #{setting} #{on_off}"
44
+ end
45
+ %w(autolist autoirb).each do |setting|
46
+ on_off = show_onoff(Command.settings[setting.to_sym] > 0)
47
+ file.puts "set #{setting} #{on_off}"
48
+ end
49
+ end
50
+
51
+ def regexp
52
+ /^\s* sa(?:ve)?
53
+ (?:\s+(.+))?
54
+ \s*$/ix
55
+ end
56
+
57
+ def execute
58
+ if not @match[1] or @match[1].strip.empty?
59
+ file = open_save()
60
+ else
61
+ file = open(@match[1], 'w')
62
+ end
63
+ save_breakpoints(file)
64
+ save_catchpoints(file)
65
+ # save_displays(file)
66
+ save_settings(file)
67
+ print "Saved to '#{file.path}'\n"
68
+ if @state and @state.interface
69
+ @state.interface.restart_file = file.path
70
+ end
71
+ file.close
72
+ end
73
+
74
+ class << self
75
+ def help_command
76
+ 'save'
77
+ end
78
+
79
+ def help(cmd)
80
+ %{
81
+ save [FILE]
82
+ Saves current debugger state to FILE as a script file.
83
+ This includes breakpoints, catchpoints, display expressions and some settings.
84
+ If no filename is given, we will fabricate one.
85
+
86
+ Use the 'source' command in another debug session to restore them.}
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,237 @@
1
+ module Debugger
2
+ # Implements debugger "set" command.
3
+ class SetCommand < Command
4
+ SubcmdStruct2=Struct.new(:name, :min, :is_bool, :short_help,
5
+ :long_help) unless defined?(SubcmdStruct2)
6
+ Subcommands =
7
+ [
8
+ ['annotate', 2, false,
9
+ "Set annotation level",
10
+ "0 == normal;
11
+ 2 == output annotated suitably for use by programs that control
12
+ ruby-debug."],
13
+ ['args', 2, false,
14
+ "Set argument list to give program being debugged when it is started",
15
+ "Follow this command with any number of args, to be passed to the program."],
16
+ ['autoeval', 4, true,
17
+ "Evaluate every unrecognized command"],
18
+ ['autolist', 4, true,
19
+ "Execute 'list' command on every breakpoint"],
20
+ ['autoirb', 4, true,
21
+ "Invoke IRB on every stop"],
22
+ ['autoreload', 4, true,
23
+ "Reload source code when changed"],
24
+ ['basename', 1, true,
25
+ "Report file basename only showing file names"],
26
+ ['callstyle', 2, false,
27
+ "Set how you want call parameters displayed"],
28
+ ['debuggertesting', 8, false,
29
+ "Used when testing the debugger"],
30
+ ['forcestep', 2, true,
31
+ "Make sure 'next/step' commands always move to a new line"],
32
+ ['fullpath', 2, true,
33
+ "Display full file names in frames"],
34
+ ['history', 2, false,
35
+ "Generic command for setting command history parameters",
36
+ "set history filename -- Set the filename in which to record the command history
37
+ set history save -- Set saving of the history record on exit
38
+ set history size -- Set the size of the command history"],
39
+ ['keep-frame-bindings', 1, true,
40
+ "Save frame binding on each call"],
41
+ ['linetrace+', 10, true,
42
+ "Set line execution tracing to show different lines"],
43
+ ['linetrace', 3, true,
44
+ "Set line execution tracing"],
45
+ ['listsize', 3, false,
46
+ "Set number of source lines to list by default"],
47
+ # ['post-mortem', 3, true,
48
+ # "Set whether we do post-mortem handling on an uncaught exception"],
49
+ ['trace', 1, true,
50
+ "Display stack trace when 'eval' raises exception"],
51
+ ['width', 1, false,
52
+ "Number of characters the debugger thinks are in a line"],
53
+ ].map do |name, min, is_bool, short_help, long_help|
54
+ SubcmdStruct2.new(name, min, is_bool, short_help, long_help)
55
+ end unless defined?(Subcommands)
56
+
57
+ self.allow_in_control = true
58
+
59
+ def regexp
60
+ /^set (?: \s+ (.*) )?$/ix
61
+ end
62
+
63
+ def execute
64
+ if not @match[1]
65
+ print "\"set\" must be followed by the name of an set command:\n"
66
+ print "List of set subcommands:\n\n"
67
+ for subcmd in Subcommands do
68
+ print "set #{subcmd.name} -- #{subcmd.short_help}\n"
69
+ end
70
+ else
71
+ args = @match[1].split(/[ \t]+/)
72
+ subcmd = args.shift
73
+ subcmd.downcase!
74
+ if subcmd =~ /^no/i
75
+ set_on = false
76
+ subcmd = subcmd[2..-1]
77
+ else
78
+ set_on = true
79
+ end
80
+ for try_subcmd in Subcommands do
81
+ if (subcmd.size >= try_subcmd.min) and
82
+ (try_subcmd.name[0..subcmd.size-1] == subcmd)
83
+ begin
84
+ if try_subcmd.is_bool
85
+ if args.size > 0
86
+ set_on = get_onoff(args[0])
87
+ end
88
+ end
89
+ case try_subcmd.name
90
+ when /^annotate$/
91
+ level = get_int(args[0], "Set annotate", 0, 3, 0)
92
+ if level
93
+ Debugger.annotate = level
94
+ else
95
+ return
96
+ end
97
+ if defined?(Debugger::RDEBUG_SCRIPT)
98
+ # rdebug was called initially. 1st arg is script name.
99
+ Command.settings[:argv][1..-1] = args
100
+ else
101
+ # rdebug wasn't called initially. 1st arg is not script name.
102
+ Command.settings[:argv] = args
103
+ end
104
+ when /^args$/
105
+ Command.settings[:argv][1..-1] = args
106
+ when /^autolist$/
107
+ Command.settings[:autolist] = (set_on ? 1 : 0)
108
+ when /^autoeval$/
109
+ Command.settings[:autoeval] = set_on
110
+ when /^basename$/
111
+ Command.settings[:basename] = set_on
112
+ when /^callstyle$/
113
+ if args[0]
114
+ arg = args[0].downcase.to_sym
115
+ case arg
116
+ when :short, :last, :tracked
117
+ Command.settings[:callstyle] = arg
118
+ Debugger.track_frame_args = arg == :tracked ? true : false
119
+ print "%s\n" % show_setting(try_subcmd.name)
120
+ return
121
+ end
122
+ end
123
+ print "Invalid call style #{arg}. Should be one of: " +
124
+ "'short', 'last', or 'tracked'.\n"
125
+ when /^trace$/
126
+ Command.settings[:stack_trace_on_error] = set_on
127
+ when /^fullpath$/
128
+ Command.settings[:full_path] = set_on
129
+ when /^autoreload$/
130
+ Command.settings[:reload_source_on_change] = set_on
131
+ when /^autoirb$/
132
+ Command.settings[:autoirb] = (set_on ? 1 : 0)
133
+ when /^debuggertesting$/
134
+ Command.settings[:debuggertesting] = set_on
135
+ if set_on
136
+ Command.settings[:basename] = true
137
+ end
138
+ when /^forcestep$/
139
+ self.class.settings[:force_stepping] = set_on
140
+ when /^history$/
141
+ if 2 == args.size
142
+ interface = @state.interface
143
+ case args[0]
144
+ when /^save$/
145
+ interface.history_save = get_onoff(args[1])
146
+ when /^size$/
147
+ interface.history_length = get_int(args[1],
148
+ "Set history size")
149
+ else
150
+ print "Invalid history parameter #{args[0]}. Should be 'save' or 'size'.\n"
151
+ end
152
+ else
153
+ print "Need two parameters for 'set history'; got #{args.size}.\n"
154
+ return
155
+ end
156
+ when /^keep-frame-bindings$/
157
+ Debugger.keep_frame_binding = set_on
158
+ when /^linetrace\+$/
159
+ self.class.settings[:tracing_plus] = set_on
160
+ when /^linetrace$/
161
+ Debugger.tracing = set_on
162
+ when /^listsize$/
163
+ listsize = get_int(args[0], "Set listsize", 1, nil, 10)
164
+ if listsize
165
+ self.class.settings[:listsize] = listsize
166
+ else
167
+ return
168
+ end
169
+ # when /^post-mortem$/
170
+ # unless Debugger.post_mortem? == set_on
171
+ # if set_on
172
+ # Debugger.post_mortem
173
+ # else
174
+ # errmsg "Can't turn off post-mortem once it is on.\n"
175
+ # return
176
+ # end
177
+ # end
178
+ when /^width$/
179
+ width = get_int(args[0], "Set width", 10, nil, 80)
180
+ if width
181
+ self.class.settings[:width] = width
182
+ ENV['COLUMNS'] = width.to_s
183
+ else
184
+ return
185
+ end
186
+ else
187
+ print "Unknown setting #{@match[1]}.\n"
188
+ return
189
+ end
190
+ print "%s\n" % show_setting(try_subcmd.name)
191
+ return
192
+ rescue RuntimeError
193
+ return
194
+ end
195
+ end
196
+ end
197
+ print "Unknown set command #{subcmd}\n"
198
+ end
199
+ end
200
+
201
+ class << self
202
+ def help_command
203
+ "set"
204
+ end
205
+
206
+ def help(args)
207
+ if args[1]
208
+ s = args[1]
209
+ subcmd = Subcommands.find do |try_subcmd|
210
+ (s.size >= try_subcmd.min) and
211
+ (try_subcmd.name[0..s.size-1] == s)
212
+ end
213
+ if subcmd
214
+ str = subcmd.short_help + '.'
215
+ str += "\n" + subcmd.long_help if subcmd.long_help
216
+ return str
217
+ else
218
+ return "Invalid 'set' subcommand '#{args[1]}'."
219
+ end
220
+ end
221
+ s = %{
222
+ Modifies parts of the ruby-debug environment. Boolean values take
223
+ on, off, 1 or 0.
224
+ You can see these environment settings with the \"show\" command.
225
+
226
+ --
227
+ List of set subcommands:
228
+ --
229
+ }
230
+ for subcmd in Subcommands do
231
+ s += "set #{subcmd.name} -- #{subcmd.short_help}\n"
232
+ end
233
+ return s
234
+ end
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,253 @@
1
+ module Debugger
2
+ # Mix-in module to showing settings
3
+ module ShowFunctions # :nodoc:
4
+ def show_setting(setting_name)
5
+ case setting_name
6
+ when /^annotate$/
7
+ Debugger.annotate ||= 0
8
+ return ("Annotation level is #{Debugger.annotate}")
9
+ when /^args$/
10
+ if Command.settings[:argv] and Command.settings[:argv].size > 0
11
+ if defined?(Debugger::RDEBUG_SCRIPT)
12
+ # rdebug was called initially. 1st arg is script name.
13
+ args = Command.settings[:argv][1..-1].join(' ')
14
+ else
15
+ # rdebug wasn't called initially. 1st arg is not script name.
16
+ args = Command.settings[:argv].join(' ')
17
+ end
18
+ else
19
+ args = ''
20
+ end
21
+ return "Argument list to give program being debugged when it is started is \"#{args}\"."
22
+ when /^autolist$/
23
+ on_off = Command.settings[:autolist] > 0
24
+ return "autolist is #{show_onoff(on_off)}."
25
+ when /^autoeval$/
26
+ on_off = Command.settings[:autoeval]
27
+ return "autoeval is #{show_onoff(on_off)}."
28
+ when /^autoreload$/
29
+ on_off = Command.settings[:reload_source_on_change]
30
+ return "autoreload is #{show_onoff(on_off)}."
31
+ when /^autoirb$/
32
+ on_off = Command.settings[:autoirb] > 0
33
+ return "autoirb is #{show_onoff(on_off)}."
34
+ when /^basename$/
35
+ on_off = Command.settings[:basename]
36
+ return "basename is #{show_onoff(on_off)}."
37
+ when /^callstyle$/
38
+ style = Command.settings[:callstyle]
39
+ return "Frame call-display style is #{style}."
40
+ when /^commands(:?\s+(\d+))?$/
41
+ if @state.interface.readline_support?
42
+ s = '';
43
+ args = @match[1].split
44
+ if args[1]
45
+ first_line = args[1].to_i - 4
46
+ last_line = first_line + 10 - 1
47
+ if first_line > Readline::HISTORY.length
48
+ first_line = last_line = Readline::HISTORY.length
49
+ elsif first_line <= 0
50
+ first_line = 1
51
+ end
52
+ if last_line > Readline::HISTORY.length
53
+ last_line = Readline::HISTORY.length
54
+ end
55
+ i = first_line
56
+ commands = Readline::HISTORY.to_a[first_line..last_line]
57
+ else
58
+ if Readline::HISTORY.length > 10
59
+ commands = Readline::HISTORY.to_a[-10..-1]
60
+ i = Readline::HISTORY.length - 10
61
+ else
62
+ commands = Readline::HISTORY.to_a
63
+ i = 1
64
+ end
65
+ end
66
+ commands.each do |cmd|
67
+ s += ("%5d %s\n" % [i, cmd])
68
+ i += 1
69
+ end
70
+ else
71
+ s='No readline suport'
72
+ end
73
+ return s
74
+ when /^debuggertesting$/
75
+ on_off = Command.settings[:debuggertesting]
76
+ return "Currently testing the debugger is #{show_onoff(on_off)}."
77
+ when /^forcestep$/
78
+ on_off = self.class.settings[:force_stepping]
79
+ return "force-stepping is #{show_onoff(on_off)}."
80
+ when /^fullpath$/
81
+ on_off = Command.settings[:full_path]
82
+ return "Displaying frame's full file names is #{show_onoff(on_off)}."
83
+ when /^history(:?\s+(filename|save|size))?$/
84
+ args = @match[1].split
85
+ interface = @state.interface
86
+ if args[1]
87
+ show_save = show_size = show_filename = false
88
+ prefix = false
89
+ if args[1] == "save"
90
+ show_save = true
91
+ elsif args[1] == "size"
92
+ show_size = true
93
+ elsif args[1] == "filename"
94
+ show_filename = true
95
+ end
96
+ else
97
+ show_save = show_size = show_filename = true
98
+ prefix = true
99
+ end
100
+ s = []
101
+ if show_filename
102
+ msg = (prefix ? "filename: " : "") +
103
+ "The filename in which to record the command history is " +
104
+ "#{interface.histfile.inspect}"
105
+ s << msg
106
+ end
107
+ if show_save
108
+ msg = (prefix ? "save: " : "") +
109
+ "Saving of history save is #{show_onoff(interface.history_save)}."
110
+ s << msg
111
+ end
112
+ if show_size
113
+ msg = (prefix ? "size: " : "") +
114
+ "Debugger history size is #{interface.history_length}"
115
+ s << msg
116
+ end
117
+ return s.join("\n")
118
+ when /^keep-frame-bindings$/
119
+ on_off = Debugger.keep_frame_binding?
120
+ return "keep-frame-bindings is #{show_onoff(on_off)}."
121
+ when /^linetrace$/
122
+ on_off = Debugger.tracing
123
+ return "line tracing is #{show_onoff(on_off)}."
124
+ when /^linetrace\+$/
125
+ on_off = Command.settings[:tracing_plus]
126
+ if on_off
127
+ return "line tracing style is different consecutive lines."
128
+ else
129
+ return "line tracing style is every line."
130
+ end
131
+ when /^listsize$/
132
+ listlines = Command.settings[:listsize]
133
+ return "Number of source lines to list by default is #{listlines}."
134
+ when /^port$/
135
+ return "server port is #{Debugger::PORT}."
136
+ when /^post-mortem$/
137
+ on_off = Debugger.post_mortem?
138
+ return "post-mortem handling is #{show_onoff(on_off)}."
139
+ when /^trace$/
140
+ on_off = Command.settings[:stack_trace_on_error]
141
+ return "Displaying stack trace is #{show_onoff(on_off)}."
142
+ when /^version$/
143
+ return "ruby-debug #{Debugger::VERSION}"
144
+ when /^width$/
145
+ return "width is #{self.class.settings[:width]}."
146
+ else
147
+ return "Unknown show subcommand #{setting_name}."
148
+ end
149
+ end
150
+ end
151
+
152
+ # Implements debugger "show" command.
153
+ class ShowCommand < Command
154
+
155
+ Subcommands =
156
+ [
157
+ ['annotate', 2, "Show annotation level",
158
+ "0 == normal; 2 == output annotated suitably for use by programs that control
159
+ ruby-debug."],
160
+ ['args', 2,
161
+ "Show argument list to give program being debugged when it is started",
162
+ "Follow this command with any number of args, to be passed to the program."],
163
+ ['autoeval', 4, "Show if unrecognized command are evaluated"],
164
+ ['autolist', 4, "Show if 'list' commands is run on breakpoints"],
165
+ ['autoirb', 4, "Show if IRB is invoked on debugger stops"],
166
+ ['autoreload', 4, "Show if source code is reloaded when changed"],
167
+ ['basename', 1, "Show if basename used in reporting files"],
168
+ ['callstyle', 2, "Show paramater style used showing call frames"],
169
+ ['commands', 2, "Show the history of commands you typed",
170
+ "You can supply a command number to start with."],
171
+ ['forcestep', 1, "Show if sure 'next/step' forces move to a new line"],
172
+ ['fullpath', 2, "Show if full file names are displayed in frames"],
173
+ ['history', 2, "Generic command for showing command history parameters",
174
+ "show history filename -- Show the filename in which to record the command history
175
+ show history save -- Show saving of the history record on exit
176
+ show history size -- Show the size of the command history"],
177
+ ['keep-frame-bindings', 1, "Save frame binding on each call"],
178
+ ['linetrace', 3, "Show line execution tracing"],
179
+ ['linetrace+', 10,
180
+ "Show if consecutive lines should be different are shown in tracing"],
181
+ ['listsize', 3, "Show number of source lines to list by default"],
182
+ ['port', 3, "Show server port"],
183
+ ['post-mortem', 3, "Show whether we go into post-mortem debugging on an uncaught exception"],
184
+ ['trace', 1,
185
+ "Show if a stack trace is displayed when 'eval' raises exception"],
186
+ ['version', 1,
187
+ "Show what version of the debugger this is"],
188
+ ['width', 1,
189
+ "Show the number of characters the debugger thinks are in a line"],
190
+ ].map do |name, min, short_help, long_help|
191
+ SubcmdStruct.new(name, min, short_help, long_help)
192
+ end unless defined?(Subcommands)
193
+
194
+ self.allow_in_control = true
195
+
196
+ def regexp
197
+ /^show (?: \s+ (.+) )?$/xi
198
+ end
199
+
200
+ def execute
201
+ if not @match[1]
202
+ print "\"show\" must be followed by the name of an show command:\n"
203
+ print "List of show subcommands:\n\n"
204
+ for subcmd in Subcommands do
205
+ print "show #{subcmd.name} -- #{subcmd.short_help}\n"
206
+ end
207
+ else
208
+ args = @match[1].split(/[ \t]+/)
209
+ param = args.shift
210
+ subcmd = find(Subcommands, param)
211
+ if subcmd
212
+ print "%s\n" % show_setting(subcmd.name)
213
+ else
214
+ print "Unknown show command #{param}\n"
215
+ end
216
+ end
217
+ end
218
+
219
+ class << self
220
+ def help_command
221
+ "show"
222
+ end
223
+
224
+ def help(args)
225
+ if args[1]
226
+ s = args[1]
227
+ subcmd = Subcommands.find do |try_subcmd|
228
+ (s.size >= try_subcmd.min) and
229
+ (try_subcmd.name[0..s.size-1] == s)
230
+ end
231
+ if subcmd
232
+ str = subcmd.short_help + '.'
233
+ str += "\n" + subcmd.long_help if subcmd.long_help
234
+ return str
235
+ else
236
+ return "Invalid 'show' subcommand '#{args[1]}'."
237
+ end
238
+ end
239
+ s = "
240
+ Generic command for showing things about the debugger.
241
+
242
+ --
243
+ List of show subcommands:
244
+ --
245
+ "
246
+ for subcmd in Subcommands do
247
+ s += "show #{subcmd.name} -- #{subcmd.short_help}\n"
248
+ end
249
+ return s
250
+ end
251
+ end
252
+ end
253
+ end