rb8-trepanning 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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