rb8-trepanning 0.1.3 → 0.1.4

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 (106) hide show
  1. data/CHANGES +10 -0
  2. data/ChangeLog +276 -0
  3. data/Makefile +13 -0
  4. data/Rakefile +1 -2
  5. data/app/display.rb +41 -1
  6. data/app/irb.rb +55 -49
  7. data/app/options.rb +3 -2
  8. data/app/run.rb +25 -7
  9. data/app/util.rb +19 -1
  10. data/bin/trepan8 +0 -2
  11. data/data/perldb.bindings +17 -0
  12. data/interface/script.rb +1 -1
  13. data/interface/server.rb +1 -1
  14. data/interface/user.rb +3 -1
  15. data/{interface/base_intf.rb → interface.rb} +1 -1
  16. data/io/input.rb +1 -1
  17. data/io/null_output.rb +1 -1
  18. data/io/string_array.rb +2 -2
  19. data/io/tcpclient.rb +1 -1
  20. data/io/tcpserver.rb +1 -1
  21. data/{io/base_io.rb → io.rb} +0 -0
  22. data/lib/debugger.rb +0 -1
  23. data/lib/trepanning.rb +3 -1
  24. data/processor/command/alias.rb +13 -2
  25. data/processor/command/backtrace.rb +2 -1
  26. data/processor/command/base/subcmd.rb +1 -5
  27. data/processor/command/base/submgr.rb +1 -1
  28. data/processor/command/base/subsubcmd.rb +1 -1
  29. data/processor/command/base/subsubmgr.rb +4 -4
  30. data/processor/command/break.rb +19 -11
  31. data/processor/command/catch.rb +1 -1
  32. data/processor/command/complete.rb +1 -1
  33. data/processor/command/continue.rb +7 -1
  34. data/processor/command/directory.rb +2 -2
  35. data/processor/command/disable.rb +13 -14
  36. data/processor/command/display.rb +3 -1
  37. data/processor/command/down.rb +8 -8
  38. data/processor/command/edit.rb +1 -1
  39. data/processor/command/enable.rb +21 -22
  40. data/processor/command/eval.rb +1 -2
  41. data/processor/command/exit.rb +25 -8
  42. data/processor/command/finish.rb +7 -2
  43. data/processor/command/frame.rb +1 -1
  44. data/processor/command/help.rb +3 -4
  45. data/processor/command/info.rb +2 -0
  46. data/processor/command/info_subcmd/files.rb +2 -2
  47. data/processor/command/info_subcmd/locals.rb +6 -53
  48. data/processor/command/info_subcmd/source.rb +10 -4
  49. data/processor/command/info_subcmd/variables.rb +35 -0
  50. data/processor/command/info_subcmd/variables_subcmd/.gitignore +1 -0
  51. data/processor/command/info_subcmd/variables_subcmd/class.rb +42 -0
  52. data/processor/command/info_subcmd/variables_subcmd/constant.rb +42 -0
  53. data/processor/command/info_subcmd/{globals.rb → variables_subcmd/globals.rb} +22 -17
  54. data/processor/command/info_subcmd/variables_subcmd/instance.rb +42 -0
  55. data/processor/command/info_subcmd/variables_subcmd/locals.rb +80 -0
  56. data/processor/command/kill.rb +8 -7
  57. data/processor/command/list.rb +2 -2
  58. data/processor/command/macro.rb +27 -9
  59. data/processor/command/next.rb +1 -1
  60. data/processor/command/parsetree.rb +1 -1
  61. data/processor/command/pp.rb +1 -1
  62. data/processor/command/pr.rb +1 -1
  63. data/processor/command/ps.rb +1 -1
  64. data/processor/command/restart.rb +1 -1
  65. data/processor/command/save.rb +1 -1
  66. data/processor/command/set_subcmd/auto.rb +7 -1
  67. data/processor/command/set_subcmd/different.rb +1 -1
  68. data/processor/command/set_subcmd/trace.rb +5 -4
  69. data/processor/command/set_subcmd/trace_subcmd/print.rb +4 -3
  70. data/processor/command/shell.rb +5 -4
  71. data/processor/command/show_subcmd/{alias.rb → aliases.rb} +2 -2
  72. data/processor/command/source.rb +1 -1
  73. data/processor/command/step.rb +2 -5
  74. data/processor/command/tbreak.rb +1 -1
  75. data/processor/command/unalias.rb +13 -8
  76. data/processor/command/undisplay.rb +13 -9
  77. data/processor/command/up.rb +12 -14
  78. data/processor/command.rb +138 -230
  79. data/processor/display.rb +46 -10
  80. data/processor/help.rb +5 -3
  81. data/processor/hook.rb +2 -2
  82. data/processor/location.rb +25 -0
  83. data/processor/mock.rb +3 -2
  84. data/processor/msg.rb +55 -42
  85. data/processor/old-command.rb +270 -0
  86. data/processor/{processor.rb → old-processor.rb} +7 -8
  87. data/processor/running.rb +7 -12
  88. data/processor/subcmd.rb +15 -41
  89. data/processor/validate.rb +240 -238
  90. data/{processor/main.rb → processor.rb} +20 -42
  91. data/test/data/trace.cmd +6 -0
  92. data/test/data/trace.right +46 -0
  93. data/test/integration/helper.rb +2 -0
  94. data/test/integration/test-trace.rb +29 -0
  95. data/test/unit/cmd-helper.rb +2 -3
  96. data/test/unit/test-app-options.rb +13 -11
  97. data/test/unit/test-app-run.rb +7 -1
  98. data/test/unit/test-base-cmd.rb +1 -1
  99. data/test/unit/test-cmd-kill.rb +11 -4
  100. data/test/unit/test-io-tcpserver.rb +9 -4
  101. data/test/unit/test-proc-eval.rb +1 -2
  102. data/test/unit/test-proc-location.rb +26 -32
  103. data/test/unit/test-subcmd-help.rb +1 -1
  104. data/trepan8.gemspec +9 -1
  105. metadata +60 -17
  106. data/processor/command/base/cmd.rb +0 -177
data/processor/msg.rb CHANGED
@@ -3,59 +3,72 @@
3
3
  require 'rubygems'; require 'require_relative'
4
4
  require_relative '../app/util'
5
5
  require_relative 'virtual'
6
- module Trepan
7
- class CmdProcessor < VirtualCmdProcessor
8
- attr_accessor :ruby_highlighter
9
6
 
10
- def errmsg(message, opts={})
11
- message = safe_rep(message) unless opts[:unlimited]
12
- if @settings[:highlight] && defined?(Term::ANSIColor)
13
- message =
14
- Term::ANSIColor.italic + message + Term::ANSIColor.reset
15
- end
16
- @intf.errmsg(message)
17
- end
7
+ begin require 'term/ansicolor'; rescue LoadError; end
18
8
 
19
- def msg(message, opts={})
20
- message = safe_rep(message) unless opts[:unlimited]
21
- @intf.msg(message)
22
- end
9
+ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
10
+ attr_accessor :ruby_highlighter
11
+
12
+ def confirm(msg, default)
13
+ @settings[:confirm] ? @dbgr.intf[-1].confirm(msg, default) : true
14
+ end
23
15
 
24
- def msg_nocr(message, opts={})
16
+ def errmsg(message, opts={})
17
+ if message.kind_of?(Array)
18
+ message.each do |mess|
19
+ errmsg(mess, opts)
20
+ end
21
+ return
22
+ else
25
23
  message = safe_rep(message) unless opts[:unlimited]
26
- @intf.msg_nocr(message)
27
24
  end
28
-
29
- def read_command()
30
- @intf.read_command(@prompt)
25
+ if @settings[:highlight] && defined?(Term::ANSIColor)
26
+ message =
27
+ Term::ANSIColor.italic + message + Term::ANSIColor.reset
31
28
  end
29
+ @intf.errmsg(message)
30
+ end
32
31
 
33
- def ruby_format(text)
34
- return text unless settings[:highlight]
35
- unless @ruby_highlighter
36
- begin
37
- require 'coderay'
38
- require 'term/ansicolor'
39
- @ruby_highlighter = CodeRay::Duo[:ruby, :term]
40
- rescue LoadError
41
- return text
42
- end
43
- end
44
- return @ruby_highlighter.encode(text)
45
- end
32
+ def msg(message, opts={})
33
+ message = safe_rep(message) unless opts[:unlimited]
34
+ message = ruby_format(message) if opts[:code]
35
+ @intf.msg(message)
36
+ end
46
37
 
47
- def safe_rep(str)
48
- Util::safe_repr(str, @settings[:maxstring])
49
- end
38
+ def msg_nocr(message, opts={})
39
+ message = safe_rep(message) unless opts[:unlimited]
40
+ @intf.msg_nocr(message)
41
+ end
50
42
 
51
- def section(message, opts={})
52
- message = safe_rep(message) unless opts[:unlimited]
53
- if @settings[:highlight] && defined?(Term::ANSIColor)
54
- message =
55
- Term::ANSIColor.bold + message + Term::ANSIColor.reset
43
+ def read_command()
44
+ @intf.read_command(@prompt)
45
+ end
46
+
47
+ def ruby_format(text)
48
+ return text unless settings[:highlight]
49
+ unless @ruby_highlighter
50
+ begin
51
+ require 'coderay'
52
+ require 'term/ansicolor'
53
+ @ruby_highlighter = CodeRay::Duo[:ruby, :term]
54
+ rescue LoadError
55
+ return text
56
56
  end
57
- @intf.msg(message)
58
57
  end
58
+ return @ruby_highlighter.encode(text)
59
+ end
59
60
 
61
+ def safe_rep(str)
62
+ Trepan::Util::safe_repr(str, @settings[:maxstring])
60
63
  end
64
+
65
+ def section(message, opts={})
66
+ message = safe_rep(message) unless opts[:unlimited]
67
+ if @settings[:highlight] && defined?(Term::ANSIColor)
68
+ message =
69
+ Term::ANSIColor.bold + message + Term::ANSIColor.reset
70
+ end
71
+ @intf.msg(message)
72
+ end
73
+
61
74
  end
@@ -0,0 +1,270 @@
1
+ require 'rubygems'
2
+ require 'columnize'
3
+ require 'require_relative'
4
+ require_relative './helper'
5
+
6
+ module Trepan
7
+ RUBY_DEBUG_DIR = File.expand_path(File.dirname(__FILE__)) unless
8
+ defined?(RUBY_DEBUG_DIR)
9
+
10
+ # A Trepan::Command object is is the base class for commands that
11
+ # implement a single debugger command. Individual debugger commands
12
+ # will be a subclass of this. The singleton class object is the
13
+ # command manager for all commands.
14
+ #
15
+ # Each debugger command is expected to implement the following methods:
16
+ # _regexp_:: A regular expression which input strings are matched
17
+ # against. If we have a match, run this command.
18
+ # It is the ruby-debug programmer's responsibility
19
+ # to make sure that these regular expressions match disjoint
20
+ # sets of strings. Otherwise one is arbitrarily used.
21
+ # _execute_:: Ruby code that implements the command.
22
+ # _help_:: Should return a String containing descriptive help for
23
+ # the commmand. Used by the 'help' command Trepan::HelpCommand
24
+ # _help_command_:: The name of the command listed via help.
25
+ #
26
+ # _help_ and _help_command_ methods are singleton methods, not
27
+ # instance methods like _regexp_ and _execute_.
28
+ class OldCommand
29
+ SubcmdStruct=Struct.new(:name, :min, :short_help, :long_help) unless
30
+ defined?(SubcmdStruct)
31
+
32
+ include Columnize
33
+
34
+ # Find _param_ in _subcmds_. The _param_ id downcased and can be
35
+ # abbreviated to the minimum length listed in the subcommands
36
+ def find(subcmds, param)
37
+ param.downcase!
38
+ for try_subcmd in subcmds do
39
+ if (param.size >= try_subcmd.min) and
40
+ (try_subcmd.name[0..param.size-1] == param)
41
+ return try_subcmd
42
+ end
43
+ end
44
+ return nil
45
+ end
46
+
47
+ class << self
48
+ # An Array containing Trepan::Command classes that implment each
49
+ # of the debugger commands.
50
+ def commands
51
+ @commands ||= []
52
+ end
53
+
54
+ DEF_OPTIONS = {
55
+ :allow_in_control => false,
56
+ :allow_in_post_mortem => true,
57
+ :event => true,
58
+ :always_run => 0,
59
+ :unknown => false,
60
+ :need_context => false,
61
+ } unless defined?(DEF_OPTIONS)
62
+
63
+ def inherited(klass)
64
+ DEF_OPTIONS.each do |o, v|
65
+ klass.options[o] = v if klass.options[o].nil?
66
+ end
67
+ commands << klass
68
+ end
69
+
70
+ # Read in and "include" all the subclasses of the
71
+ # Trepan::Command class. For example
72
+ # Trepan::QuitCommand is one of them. The list of Ruby
73
+ # files to read are all the files that end .rb in directory
74
+ # Trepan::RUBY_DEBUG_DIR
75
+ def load_commands
76
+ Dir[File.join(%W(#{Trepan.const_get(:RUBY_DEBUG_DIR)}
77
+ command-ruby-debug *))].each do
78
+ |file|
79
+ require file if file =~ /\.rb$/
80
+ end
81
+ Trepan.constants.grep(/Functions$/).map { |name| Trepan.const_get(name) }.each do |mod|
82
+ include mod
83
+ end
84
+ end
85
+
86
+ def method_missing(meth, *args, &block)
87
+ if meth.to_s =~ /^(.+?)=$/
88
+ @options[$1.intern] = args.first
89
+ else
90
+ if @options.has_key?(meth)
91
+ @options[meth]
92
+ else
93
+ super
94
+ end
95
+ end
96
+ end
97
+
98
+ def options
99
+ @options ||= {}
100
+ end
101
+
102
+ def settings_map
103
+ @@settings_map ||= {}
104
+ end
105
+ private :settings_map
106
+
107
+ # Returns a Hash of Debugger settings, @settings. If doesn't exist
108
+ # we create a @settings hash with [] setter and getter and return that.
109
+ def settings
110
+ unless true and defined? @settings and @settings
111
+ @settings = Object.new
112
+ map = settings_map
113
+ c = class << @settings; self end
114
+ if c.respond_to?(:funcall)
115
+ c.funcall(:define_method, :[]) do |name|
116
+ raise "No such setting #{name}" unless map.has_key?(name)
117
+ map[name][:getter].call
118
+ end
119
+ else
120
+ c.send(:define_method, :[]) do |name|
121
+ raise "No such setting #{name}" unless map.has_key?(name)
122
+ map[name][:getter].call
123
+ end
124
+ end
125
+ c = class << @settings; self end
126
+ if c.respond_to?(:funcall)
127
+ c.funcall(:define_method, :[]=) do |name, value|
128
+ raise "No such setting #{name}" unless map.has_key?(name)
129
+ map[name][:setter].call(value)
130
+ end
131
+ else
132
+ c.send(:define_method, :[]=) do |name, value|
133
+ raise "No such setting #{name}" unless map.has_key?(name)
134
+ map[name][:setter].call(value)
135
+ end
136
+ end
137
+ end
138
+ @settings
139
+ end
140
+
141
+ def register_setting_var(name, default)
142
+ var_name = "@@#{name}"
143
+ class_variable_set(var_name, default)
144
+ register_setting_get(name) { class_variable_get(var_name) }
145
+ register_setting_set(name) { |value| class_variable_set(var_name, value) }
146
+ end
147
+
148
+ def register_setting_get(name, &block)
149
+ settings_map[name] ||= {}
150
+ settings_map[name][:getter] = block
151
+ end
152
+
153
+ def register_setting_set(name, &block)
154
+ settings_map[name] ||= {}
155
+ settings_map[name][:setter] = block
156
+ end
157
+ end
158
+
159
+ register_setting_var(:basename, false) # use basename in showing files?
160
+ register_setting_var(:callstyle, :last)
161
+ register_setting_var(:debuggertesting, false)
162
+ register_setting_var(:force_stepping, false)
163
+ register_setting_var(:full_path, true)
164
+ register_setting_var(:listsize, 10) # number of lines in list command
165
+ register_setting_var(:stack_trace_on_error, false)
166
+ register_setting_var(:tracing_plus, false) # different linetrace lines?
167
+
168
+ # width of line output. Use COLUMNS value if it exists and is
169
+ # not too rediculously large.
170
+ width = ENV['COLUMNS'].to_i
171
+ width = 80 unless width > 10
172
+ register_setting_var(:width, width)
173
+
174
+ if not defined? Trepan::ARGV
175
+ Trepan::ARGV = ARGV.clone
176
+ end
177
+ register_setting_var(:argv, Trepan::ARGV)
178
+
179
+ def initialize(state)
180
+ @state = state
181
+ end
182
+
183
+ def match(input)
184
+ @match = regexp.match(input)
185
+ end
186
+
187
+ protected
188
+
189
+ # FIXME: use delegate?
190
+ def errmsg(*args)
191
+ @state.errmsg(*args)
192
+ end
193
+
194
+ def print(*args)
195
+ @state.print(*args)
196
+ end
197
+
198
+ # Called when we are about to do a dangerous operation. _msg_
199
+ # contains a prompt message. Return _true_ if confirmed or _false_
200
+ # if not confirmed.
201
+ def confirm(msg)
202
+ @state.confirm(msg) == 'y'
203
+ end
204
+
205
+ # debug_eval like Kernel.eval or Object.instance_eval but using
206
+ # the bindings for the debugged program. If there is a
207
+ # syntax-error like exception in running eval, print an
208
+ # appropriate message and throw :debug_error
209
+ def debug_eval(str, b = get_binding)
210
+ begin
211
+ val = eval(str, b)
212
+ rescue StandardError, ScriptError => e
213
+ if OldCommand.settings[:stack_trace_on_error]
214
+ at = eval("caller(1)", b)
215
+ print "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')
216
+ for i in at
217
+ print "\tfrom %s\n", i
218
+ end
219
+ else
220
+ print "#{e.class} Exception: #{e.message}\n"
221
+ end
222
+ throw :debug_error
223
+ end
224
+ end
225
+
226
+ # debug_eval like Kernel.eval or Object.instance_eval but using
227
+ # the bindings for the debugged program. If there is a syntax
228
+ # error kind of exception in running eval, no warning is given and
229
+ # nil is returned.
230
+ def debug_silent_eval(str)
231
+ begin
232
+ eval(str, get_binding)
233
+ rescue StandardError, ScriptError
234
+ nil
235
+ end
236
+ end
237
+
238
+ # Return a binding object for the debugged program.
239
+ def get_binding
240
+ @state.context.frame_binding(@state.frame_pos)
241
+ end
242
+
243
+ def line_at(file, line)
244
+ Debugger.line_at(file, line)
245
+ end
246
+
247
+ def get_context(thnum)
248
+ Debugger.contexts.find{|c| c.thnum == thnum}
249
+ end
250
+ end
251
+
252
+ OldCommand.load_commands
253
+
254
+ # Returns setting object.
255
+ # Use Debugger.settings[] and Debugger.settings[]= methods to query and set
256
+ # debugger settings. These settings are available:
257
+ #
258
+ # - :autolist - automatically calls 'list' command on breakpoint
259
+ # - :autoeval - evaluates input in the current binding if it's not recognized as a debugger command
260
+ # - :autoirb - automatically calls 'irb' command on breakpoint
261
+ # - :stack_trace_on_error - shows full stack trace if eval command results with an exception
262
+ # - :frame_full_path - displays full paths when showing frame stack
263
+ # - :frame_class_names - displays method's class name when showing frame stack
264
+ # - :reload_source_on_change - makes 'list' command to always display up-to-date source code
265
+ # - :force_stepping - stepping command asways move to the new line
266
+ #
267
+ def self.settings
268
+ OldCommand.settings
269
+ end
270
+ end
@@ -2,9 +2,8 @@ require 'rubygems'
2
2
  require 'ruby-debug-base'
3
3
  require 'require_relative'
4
4
  require_relative '../interface/user'
5
- require_relative './command'
6
- require_relative './default'
7
- require_relative './main'
5
+ require_relative 'old-command'
6
+ require_relative 'default'
8
7
  require_relative '../app/frame'
9
8
 
10
9
  # _Trepan_ is the module name space for this debugger.
@@ -196,13 +195,13 @@ module Trepan
196
195
  Debugger::RDEBUG_FILE == file # Don't trace ourself
197
196
  @last_file = CommandProcessor.canonic_file(file)
198
197
  canonic_file = CommandProcessor.canonic_file(file)
199
- unless canonic_file == @last_file and @last_line == line and
200
- Command.settings[:tracing_plus]
201
- print "Tracing(%d):%s:%s %s",
202
- context.thnum, canonic_file, line, Debugger.line_at(file, line)
198
+ # unless canonic_file == @last_file and @last_line == line and
199
+ # Command.settings[:tracing_plus]
200
+ print("Tracing(%d):%s:%s %s" %
201
+ [context.thnum, canonic_file, line, Debugger.line_at(file, line)])
203
202
  @last_file = canonic_file
204
203
  @last_line = line
205
- end
204
+ # end
206
205
  always_run(context, file, line, 2)
207
206
  end
208
207
  protect :at_tracing
data/processor/running.rb CHANGED
@@ -48,18 +48,13 @@ class Trepan::CmdProcessor < Trepan::VirtualCmdProcessor
48
48
  # @next_thread = Thread.current
49
49
  # end
50
50
 
51
- # # Does whatever needs to be done to set to step program
52
- # # execution.
53
- # def step(step_count=1, opts={}, condition=nil)
54
- # continue
55
- # @core.step_count = step_count
56
- # @different_pos = opts[:different_pos] if
57
- # opts.keys.member?(:different_pos)
58
- # @stop_condition = condition
59
- # @stop_events = opts[:stop_events] if
60
- # opts.keys.member?(:stop_events)
61
- # @to_method = opts[:to_method]
62
- # end
51
+ # Does whatever needs to be done to set to step program
52
+ # execution.
53
+ def step(step_count=1, opts={}, condition=nil)
54
+ @context.step(step_count, opts[:different_pos])
55
+ @state.proceed
56
+ @leave_cmd_loop = true
57
+ end
63
58
 
64
59
  def quit(cmd='quit')
65
60
  @next_level = 32000 # I'm guessing the stack size can't
data/processor/subcmd.rb CHANGED
@@ -14,17 +14,24 @@ module Trepan
14
14
 
15
15
  # Find subcmd in self.subcmds
16
16
  def lookup(subcmd_prefix, use_regexp=true)
17
- compare = if use_regexp
18
- lambda{|name| name.to_s =~ /^#{subcmd_prefix}/}
19
- else
20
- lambda{|name| 0 == name.to_s.index(subcmd_prefix)}
21
- end
17
+ compare =
18
+ if !@cmd.settings[:abbrev]
19
+ lambda{|name| name.to_s == subcmd_prefix}
20
+ elsif use_regexp
21
+ lambda{|name| name.to_s =~ /^#{subcmd_prefix}/}
22
+ else
23
+ lambda{|name| 0 == name.to_s.index(subcmd_prefix)}
24
+ end
25
+ candidates = []
22
26
  @subcmds.each do |subcmd_name, subcmd|
23
27
  if compare.call(subcmd_name) &&
24
28
  subcmd_prefix.size >= subcmd.class.const_get(:MIN_ABBREV)
25
- return subcmd
29
+ candidates << subcmd
26
30
  end
27
31
  end
32
+ if candidates.size == 1
33
+ return candidates.first
34
+ end
28
35
  return nil
29
36
  end
30
37
 
@@ -61,48 +68,15 @@ module Trepan
61
68
  @cmdlist << subcmd_name
62
69
  end
63
70
 
64
- # Run subcmd_name with args using obj for the environent
65
- def run( subcmd_name, arg)
66
- entry=lookup(subcmd_name)
67
- if entry
68
- entry['callback'].send(arg)
69
- else
70
- @proc.undefined_cmd(entry.__class__.name, subcmd_name)
71
- end
72
- end
73
-
74
71
  # help for subcommands
75
72
  # Note: format of help is compatible with ddd.
76
73
  def help(*args)
77
-
78
- msg args
79
- subcmd_prefix = args[0]
80
- if not subcmd_prefix or subcmd_prefix.size == 0
81
- @proc.msg(self.doc)
82
- @proc.msg("\nList of %s subcommands:\n" % [@name])
83
- @list.each do |subcmd_name|
84
- subcmd_helper(subcmd_name, obj, true, true)
85
- end
86
-
87
- entry = lookup(subcmd_prefix)
88
- if entry and entry.respond_to? :help
89
- entry.help(args)
90
- else
91
- @proc.errmsg("Unknown 'help %s' subcommand %s" %
92
- [@name, subcmd_prefix])
93
- end
94
- end
74
+ # Not used but tested for.
95
75
  end
96
76
 
97
77
  def list
98
78
  @subcmds.keys.sort
99
79
  end
100
-
101
- # Error message when a subcommand doesn't exist.
102
- def undefined_subcmd(cmd, subcmd)
103
- @proc.errmsg('Undefined "%s" command: "%s". Try "help".' %
104
- [cmd, subcmd])
105
- end
106
80
  end
107
81
  end
108
82
 
@@ -111,7 +85,7 @@ if __FILE__ == $0
111
85
 
112
86
  require 'rubygems'; require 'require_relative'
113
87
  require_relative 'mock'
114
- require_relative 'command/base/cmd'
88
+ require_relative 'command'
115
89
 
116
90
  class Trepan::TestCommand < Trepan::Command
117
91