rbx-trepanning 0.1.0-universal-rubinius-1.2 → 0.2.1-universal-rubinius-1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +3 -0
- data/.travis.yml +4 -0
- data/ChangeLog +162 -0
- data/Gemfile +16 -0
- data/NEWS +15 -8
- data/README.md +72 -0
- data/Rakefile +16 -13
- data/app/client.rb +15 -4
- data/app/cmd_parse.kpeg +38 -40
- data/app/cmd_parse.rb +25 -20
- data/app/cmd_parser.rb +1030 -1036
- data/app/complete.rb +12 -12
- data/app/default.rb +6 -5
- data/app/display.rb +2 -2
- data/app/frame.rb +17 -4
- data/app/method.rb +11 -10
- data/app/options.rb +21 -22
- data/app/util.rb +17 -10
- data/interface/user.rb +2 -2
- data/io/input.rb +13 -3
- data/lib/trepanning.rb +22 -23
- data/processor.rb +32 -32
- data/processor/command.rb +32 -13
- data/processor/command/backtrace.rb +2 -16
- data/processor/command/base/submgr.rb +22 -14
- data/processor/command/base/subsubcmd.rb +11 -13
- data/processor/command/base/subsubmgr.rb +38 -19
- data/processor/command/disassemble.rb +11 -11
- data/processor/command/help.rb +24 -24
- data/processor/command/shell.rb +17 -17
- data/processor/default.rb +5 -2
- data/processor/frame.rb +37 -0
- data/processor/help.rb +9 -11
- data/processor/load_cmds.rb +53 -40
- data/processor/location.rb +2 -2
- data/processor/mock.rb +8 -9
- data/processor/subcmd.rb +12 -12
- data/rbx-trepanning.gemspec +4 -3
- data/sample/rocky-trepanx-colors.rb +1 -1
- data/test/example/factorial.rb +10 -0
- data/test/functional/fn_helper.rb +8 -7
- data/test/functional/test-break.rb +39 -5
- data/test/functional/test-recursive-bt.rb +105 -0
- data/test/integration/helper.rb +14 -14
- data/test/integration/test-quit.rb +8 -2
- data/test/unit/cmd-helper.rb +2 -2
- data/test/unit/test-base-subcmd.rb +14 -3
- data/test/unit/test-completion.rb +7 -3
- data/test/unit/test-io-tcpserver.rb +10 -5
- data/test/unit/test-proc-validate.rb +4 -4
- metadata +208 -113
- data/README.textile +0 -34
data/lib/trepanning.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# -*- coding: utf-8 -*-
|
3
|
-
# Copyright (C) 2010,
|
3
|
+
# Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
4
4
|
require 'readline'
|
5
5
|
require 'compiler/iseq'
|
6
6
|
|
@@ -17,7 +17,7 @@ require_relative '../interface/script' # --command interface (includes I/O)
|
|
17
17
|
require_relative '../interface/client' # client interface (remote debugging)
|
18
18
|
require_relative '../interface/server' # server interface (remote debugging)
|
19
19
|
require_relative '../io/null_output'
|
20
|
-
|
20
|
+
|
21
21
|
#
|
22
22
|
# The Rubinius Trepan debugger.
|
23
23
|
#
|
@@ -57,8 +57,8 @@ class Trepan
|
|
57
57
|
@completion_proc = method(:completion_method)
|
58
58
|
|
59
59
|
@in_deferred_checking = false
|
60
|
-
|
61
|
-
@intf =
|
60
|
+
|
61
|
+
@intf =
|
62
62
|
if @settings[:server]
|
63
63
|
@completion_proc = nil
|
64
64
|
opts = Trepan::ServerInterface::DEFAULT_INIT_CONNECTION_OPTS.dup
|
@@ -110,17 +110,17 @@ class Trepan
|
|
110
110
|
@loaded_hook = proc { |file|
|
111
111
|
check_deferred_breakpoints
|
112
112
|
}
|
113
|
-
|
113
|
+
|
114
114
|
@added_hook = proc { |mod, name, exec|
|
115
115
|
check_deferred_breakpoints
|
116
116
|
}
|
117
117
|
|
118
118
|
# Use a few Rubinius-specific hooks to trigger checking
|
119
119
|
# for deferred breakpoints.
|
120
|
-
|
120
|
+
|
121
121
|
Rubinius::CodeLoader.loaded_hook.add @loaded_hook
|
122
122
|
Rubinius.add_method_hook.add @added_hook
|
123
|
-
|
123
|
+
|
124
124
|
end
|
125
125
|
|
126
126
|
# Run user debugger command startup files.
|
@@ -131,10 +131,10 @@ class Trepan
|
|
131
131
|
# such as called from GNU Readline with <TAB>.
|
132
132
|
def completion_method(last_token, leading=Readline.line_buffer)
|
133
133
|
completion = @processor.complete(leading, last_token)
|
134
|
-
if 1 == completion.size
|
134
|
+
if 1 == completion.size
|
135
135
|
completion_token = completion[0]
|
136
136
|
if last_token.end_with?(' ')
|
137
|
-
if last_token.rstrip == completion_token
|
137
|
+
if last_token.rstrip == completion_token
|
138
138
|
# There is nothing more to complete
|
139
139
|
[]
|
140
140
|
else
|
@@ -152,22 +152,21 @@ class Trepan
|
|
152
152
|
|
153
153
|
## HACK to skip over loader code. Until I find something better...
|
154
154
|
def skip_loader
|
155
|
-
cmds =
|
155
|
+
cmds =
|
156
156
|
if @settings[:skip_loader] == :Xdebug
|
157
157
|
['continue Rubinius::CodeLoader.load_script',
|
158
|
-
'
|
158
|
+
'next 6',
|
159
159
|
# 'set kernelstep off', # eventually would like 'on'
|
160
|
-
'step',
|
160
|
+
'step',
|
161
161
|
]
|
162
162
|
else
|
163
163
|
['next', 'next', 'next',
|
164
164
|
# 'set kernelstep off', # eventually would like 'on'
|
165
|
-
'set hidelevel -1',
|
166
165
|
'step', ]
|
167
166
|
end
|
168
167
|
|
169
168
|
input = Trepan::StringArrayInput.open(cmds)
|
170
|
-
startup = Trepan::ScriptInterface.new('startup',
|
169
|
+
startup = Trepan::ScriptInterface.new('startup',
|
171
170
|
Trepan::OutputNull.new(nil),
|
172
171
|
:input => input)
|
173
172
|
@intf << startup
|
@@ -207,7 +206,7 @@ class Trepan
|
|
207
206
|
|
208
207
|
process_cmdfile_setting(settings)
|
209
208
|
|
210
|
-
# Feed info (breakpoint, debugged program thread, channel and backtrace
|
209
|
+
# Feed info (breakpoint, debugged program thread, channel and backtrace
|
211
210
|
# info) to the debugger thread
|
212
211
|
locs = Rubinius::VM.backtrace(@settings[:offset] + 1, true)
|
213
212
|
|
@@ -222,7 +221,7 @@ class Trepan
|
|
222
221
|
# wait for the debugger to release us
|
223
222
|
channel.receive
|
224
223
|
|
225
|
-
# Now that there is a debugger on the other end, set the debugged
|
224
|
+
# Now that there is a debugger on the other end, set the debugged
|
226
225
|
# program thread to call us when it hits a breakpoint.
|
227
226
|
Thread.current.set_debugger_thread @thread
|
228
227
|
self
|
@@ -260,7 +259,7 @@ class Trepan
|
|
260
259
|
|
261
260
|
def process_cmdfile_setting(settings)
|
262
261
|
settings[:cmdfiles].each do |item|
|
263
|
-
cmdfile, opts =
|
262
|
+
cmdfile, opts =
|
264
263
|
if item.kind_of?(Array)
|
265
264
|
item
|
266
265
|
else
|
@@ -285,7 +284,7 @@ class Trepan
|
|
285
284
|
end
|
286
285
|
|
287
286
|
# Wait for someone to stop
|
288
|
-
@breakpoint, @debugee_thread, @channel, @vm_locations =
|
287
|
+
@breakpoint, @debugee_thread, @channel, @vm_locations =
|
289
288
|
@local_channel.receive
|
290
289
|
|
291
290
|
# Uncache all frames since we stopped at a new place
|
@@ -299,7 +298,7 @@ class Trepan
|
|
299
298
|
status = @breakpoint.hit!(@vm_locations.first.variables)
|
300
299
|
if status
|
301
300
|
break
|
302
|
-
elsif @breakpoint.enabled? && status.nil?
|
301
|
+
elsif @breakpoint.enabled? && status.nil?
|
303
302
|
# A permanent breakpoint. Check the condition.
|
304
303
|
break if @breakpoint.condition?(@current_frame.binding)
|
305
304
|
end
|
@@ -309,7 +308,7 @@ class Trepan
|
|
309
308
|
end
|
310
309
|
end
|
311
310
|
|
312
|
-
event =
|
311
|
+
event =
|
313
312
|
if @breakpoint
|
314
313
|
@breakpoint.event || 'brkpt'
|
315
314
|
else
|
@@ -342,15 +341,15 @@ class Trepan
|
|
342
341
|
end
|
343
342
|
|
344
343
|
def add_deferred_breakpoint(klass_name, which, name, line)
|
345
|
-
dbp = Trepan::DeferredBreakpoint.new(self, @current_frame, klass_name,
|
346
|
-
which, name, line,
|
344
|
+
dbp = Trepan::DeferredBreakpoint.new(self, @current_frame, klass_name,
|
345
|
+
which, name, line,
|
347
346
|
@deferred_breakpoints)
|
348
347
|
@deferred_breakpoints << dbp
|
349
348
|
# @processor.brkpts << dbp
|
350
349
|
end
|
351
350
|
|
352
351
|
def check_deferred_breakpoints
|
353
|
-
unless @in_deferred_checking
|
352
|
+
unless @in_deferred_checking
|
354
353
|
@in_deferred_checking = true
|
355
354
|
@deferred_breakpoints.delete_if do |bp|
|
356
355
|
bp.resolve!
|
data/processor.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
-
# The main "driver" class for a command processor. Other parts of the
|
2
|
+
# The main "driver" class for a command processor. Other parts of the
|
3
3
|
# command class and debugger command objects are pulled in from here.
|
4
4
|
|
5
5
|
require 'set'
|
6
6
|
|
7
7
|
require 'rubygems'; require 'require_relative'
|
8
|
-
## %w(default display eventbuf eval load_cmds location frame hook msg
|
8
|
+
## %w(default display eventbuf eval load_cmds location frame hook msg
|
9
9
|
## validate).each do
|
10
|
-
%w(default breakpoint disassemble display eval eventbuf load_cmds location
|
10
|
+
%w(default breakpoint disassemble display eval eventbuf load_cmds location
|
11
11
|
frame hook msg running stepping validate).each do
|
12
12
|
|mod_str|
|
13
13
|
require_relative "processor/#{mod_str}"
|
@@ -31,7 +31,7 @@ class Trepan
|
|
31
31
|
## FIXME 1.9.2 has attr_reader !
|
32
32
|
attr_accessor :debug_nest # Number of nested debugs. Used in showing
|
33
33
|
# prompt.
|
34
|
-
attr_accessor :different_pos # Same type as settings[:different]
|
34
|
+
attr_accessor :different_pos # Same type as settings[:different]
|
35
35
|
# this is the temporary value for the
|
36
36
|
# next stop while settings is the default
|
37
37
|
# value to use.
|
@@ -39,8 +39,8 @@ class Trepan
|
|
39
39
|
attr_reader :intf # Current interface
|
40
40
|
# Trepan::Core instance)
|
41
41
|
attr_accessor :leave_cmd_loop # Commands set this to signal to leave
|
42
|
-
# the command loop (which often continues to
|
43
|
-
# run the debugged program).
|
42
|
+
# the command loop (which often continues to
|
43
|
+
# run the debugged program).
|
44
44
|
attr_accessor :line_no # Last line shown in "list" command
|
45
45
|
attr_accessor :next_level # Fixnum. frame.stack_size has to
|
46
46
|
# be <= than this. If next'ing,
|
@@ -48,7 +48,7 @@ class Trepan
|
|
48
48
|
attr_accessor :next_thread # Thread. If non-nil then in
|
49
49
|
# stepping the thread has to be
|
50
50
|
# this thread.
|
51
|
-
attr_accessor :pass_exception # Pass an exception back
|
51
|
+
attr_accessor :pass_exception # Pass an exception back
|
52
52
|
attr_accessor :prompt # String print before requesting input
|
53
53
|
attr_reader :settings # Hash[:symbol] of command
|
54
54
|
# processor settings
|
@@ -57,7 +57,7 @@ class Trepan
|
|
57
57
|
# The following are used in to force stopping at a different line
|
58
58
|
# number. FIXME: could generalize to a position object.
|
59
59
|
attr_accessor :last_pos # Last position. 6-Tuple: of
|
60
|
-
# [location, container, stack_size,
|
60
|
+
# [location, container, stack_size,
|
61
61
|
# current_thread, pc_offset]
|
62
62
|
|
63
63
|
|
@@ -71,7 +71,7 @@ class Trepan
|
|
71
71
|
@next_level = 32000
|
72
72
|
@next_thread = nil
|
73
73
|
@user_variables = 0
|
74
|
-
|
74
|
+
|
75
75
|
|
76
76
|
start_cmds = settings.delete(:start_cmds)
|
77
77
|
start_file = settings.delete(:start_file)
|
@@ -81,18 +81,18 @@ class Trepan
|
|
81
81
|
|
82
82
|
# FIXME: Rework using a general "set substitute file" command and
|
83
83
|
# a global default profile which gets read.
|
84
|
-
prelude_file = File.expand_path(File.join(File.dirname(__FILE__),
|
84
|
+
prelude_file = File.expand_path(File.join(File.dirname(__FILE__),
|
85
85
|
%w(.. data prelude.rb)))
|
86
86
|
|
87
87
|
# Start with empty thread and frame info.
|
88
|
-
frame_teardown
|
88
|
+
frame_teardown
|
89
89
|
|
90
90
|
# Run initialization routines for each of the "submodule"s.
|
91
91
|
# load_cmds has to come first.
|
92
92
|
## %w(load_cmds breakpoint display eventbuf frame running validate
|
93
93
|
## ).each do |submod|
|
94
|
-
%w(load_cmds breakpoint display eventbuf frame running
|
95
|
-
stepping validate).each do
|
94
|
+
%w(load_cmds breakpoint display eventbuf frame running
|
95
|
+
stepping validate).each do
|
96
96
|
|submod|
|
97
97
|
self.send("#{submod}_initialize")
|
98
98
|
end
|
@@ -115,7 +115,7 @@ class Trepan
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def compute_prompt
|
118
|
-
"(#{@settings[:prompt]}): "
|
118
|
+
"(#{@settings[:prompt]}): "
|
119
119
|
end
|
120
120
|
|
121
121
|
# Check that we meed the criteria that cmd specifies it needs
|
@@ -124,13 +124,13 @@ class Trepan
|
|
124
124
|
# Check we have frame is not null
|
125
125
|
min_args = cmd.class.const_get(:MIN_ARGS)
|
126
126
|
if nargs < min_args
|
127
|
-
errmsg(("Command '%s' needs at least %d argument(s); " +
|
127
|
+
errmsg(("Command '%s' needs at least %d argument(s); " +
|
128
128
|
"got %d.") % [name, min_args, nargs])
|
129
129
|
return false
|
130
130
|
end
|
131
131
|
max_args = cmd.class.const_get(:MAX_ARGS)
|
132
132
|
if max_args and nargs > max_args
|
133
|
-
errmsg(("Command '%s' needs at most %d argument(s); " +
|
133
|
+
errmsg(("Command '%s' needs at most %d argument(s); " +
|
134
134
|
"got %d.") % [name, max_args, nargs])
|
135
135
|
return false
|
136
136
|
end
|
@@ -154,14 +154,14 @@ class Trepan
|
|
154
154
|
return true if @intf.input_eof? && intf_size == 1
|
155
155
|
while intf_size > 1 || !@intf.input_eof?
|
156
156
|
begin
|
157
|
-
@current_command =
|
157
|
+
@current_command =
|
158
158
|
if @cmd_queue.empty?
|
159
159
|
# Leave trailing blanks on for the "complete" command
|
160
|
-
read_command.chomp
|
160
|
+
read_command.chomp
|
161
161
|
else
|
162
162
|
@cmd_queue.shift
|
163
163
|
end
|
164
|
-
if @current_command.empty?
|
164
|
+
if @current_command.empty?
|
165
165
|
next unless @last_command && intf.interactive?;
|
166
166
|
end
|
167
167
|
next if @current_command[0..0] == '#' # Skip comment lines
|
@@ -200,7 +200,7 @@ class Trepan
|
|
200
200
|
@unconditional_prehooks.run
|
201
201
|
if breakpoint?
|
202
202
|
delete_breakpoint(@brkpt) if @brkpt.temp?
|
203
|
-
@last_pos = [@frame.vm_location, @stack_size, @current_thread, @event]
|
203
|
+
@last_pos = [@frame.vm_location, @stack_size, @current_thread, @event]
|
204
204
|
end
|
205
205
|
|
206
206
|
if stepping_skip? # || @stack_size <= @hide_level
|
@@ -219,12 +219,12 @@ class Trepan
|
|
219
219
|
|
220
220
|
@leave_cmd_loop = false
|
221
221
|
print_location unless @settings[:traceprint]
|
222
|
-
# if 'trace-var' == @event
|
222
|
+
# if 'trace-var' == @event
|
223
223
|
# msg "Note: we are stopped *after* the above location."
|
224
224
|
# end
|
225
225
|
|
226
226
|
@eventbuf.add_mark if @settings[:tracebuffer]
|
227
|
-
|
227
|
+
|
228
228
|
@return_to_program = false
|
229
229
|
@cmdloop_prehooks.run
|
230
230
|
return false
|
@@ -239,7 +239,7 @@ class Trepan
|
|
239
239
|
# if settings[:traceprint]
|
240
240
|
# @return_to_program = 'step'
|
241
241
|
# else
|
242
|
-
if !skip_command
|
242
|
+
if !skip_command
|
243
243
|
break if process_command_and_quit?()
|
244
244
|
end
|
245
245
|
# end
|
@@ -274,7 +274,7 @@ class Trepan
|
|
274
274
|
# Run current_command, a String. @last_command is set after the
|
275
275
|
# command is run if it is a command.
|
276
276
|
def run_command(current_command)
|
277
|
-
eval_command =
|
277
|
+
eval_command =
|
278
278
|
if current_command[0..0] == '!'
|
279
279
|
current_command[0] = ''
|
280
280
|
else
|
@@ -295,7 +295,7 @@ class Trepan
|
|
295
295
|
break unless @macros.member?(macro_cmd_name)
|
296
296
|
current_command = @macros[macro_cmd_name][0].call(*args[1..-1])
|
297
297
|
msg current_command.inspect if settings[:debugmacro]
|
298
|
-
if current_command.is_a?(Array) &&
|
298
|
+
if current_command.is_a?(Array) &&
|
299
299
|
current_command.all? {|val| val.is_a?(String)}
|
300
300
|
args = (first=current_command.shift).split
|
301
301
|
@cmd_queue += current_command
|
@@ -310,21 +310,21 @@ class Trepan
|
|
310
310
|
end
|
311
311
|
|
312
312
|
@cmd_name = args[0]
|
313
|
-
run_cmd_name =
|
313
|
+
run_cmd_name =
|
314
314
|
if @aliases.member?(@cmd_name)
|
315
|
-
@aliases[@cmd_name]
|
315
|
+
@aliases[@cmd_name]
|
316
316
|
else
|
317
317
|
@cmd_name
|
318
318
|
end
|
319
|
-
|
319
|
+
|
320
320
|
run_cmd_name = uniq_abbrev(@commands.keys, run_cmd_name) if
|
321
321
|
!@commands.member?(run_cmd_name) && @settings[:abbrev]
|
322
|
-
|
322
|
+
|
323
323
|
if @commands.member?(run_cmd_name)
|
324
324
|
cmd = @commands[run_cmd_name]
|
325
325
|
if ok_for_running(cmd, run_cmd_name, args.size-1)
|
326
326
|
@cmd_argstr = current_command[@cmd_name.size..-1].lstrip
|
327
|
-
cmd.run(args)
|
327
|
+
cmd.run(args)
|
328
328
|
@last_command = current_command
|
329
329
|
end
|
330
330
|
return false
|
@@ -346,7 +346,7 @@ class Trepan
|
|
346
346
|
|
347
347
|
# Error message when a command doesn't exist
|
348
348
|
def undefined_command(cmd_name)
|
349
|
-
begin
|
349
|
+
begin
|
350
350
|
errmsg('Undefined command: "%s". Try "help".' % cmd_name)
|
351
351
|
rescue
|
352
352
|
$stderr.puts 'Undefined command: "%s". Try "help".' % cmd_name
|
@@ -398,7 +398,7 @@ if __FILE__ == $0
|
|
398
398
|
# end
|
399
399
|
# $input = ['1+2']
|
400
400
|
# cmdproc.process_command_and_quit?
|
401
|
-
# $input = ['!s = 5'] # ! means eval line
|
401
|
+
# $input = ['!s = 5'] # ! means eval line
|
402
402
|
# cmdproc.process_command_and_quit?
|
403
403
|
# end
|
404
404
|
end
|
data/processor/command.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
# Copyright (C) 2010,
|
2
|
+
# Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
# Base class of all commands. Code common to all commands is here.
|
4
4
|
# Note: don't end classname with Command (capital C) since main
|
5
|
-
# will think this a command name like QuitCommand
|
5
|
+
# will think this a command name like QuitCommand
|
6
6
|
require 'rubygems'; require 'require_relative'
|
7
|
+
require 'redcard/rubinius'
|
7
8
|
require 'columnize'
|
8
9
|
require_relative '../app/complete'
|
9
10
|
|
@@ -31,7 +32,7 @@ class Trepan
|
|
31
32
|
# List commands arranged in an aligned columns
|
32
33
|
def columnize_commands(commands)
|
33
34
|
width = settings[:maxwidth]
|
34
|
-
Columnize::columnize(commands, width, ' ' * 4,
|
35
|
+
Columnize::columnize(commands, width, ' ' * 4,
|
35
36
|
true, true, ' ' * 2).chomp
|
36
37
|
end
|
37
38
|
|
@@ -53,7 +54,7 @@ class Trepan
|
|
53
54
|
end
|
54
55
|
|
55
56
|
def obj_const(obj, name)
|
56
|
-
obj.class.const_get(name)
|
57
|
+
obj.class.const_get(name)
|
57
58
|
end
|
58
59
|
|
59
60
|
def msg(message, opts={})
|
@@ -65,15 +66,33 @@ class Trepan
|
|
65
66
|
@proc.msg_nocr(msg, opts)
|
66
67
|
end
|
67
68
|
|
69
|
+
def get_const(klass, name)
|
70
|
+
name = name.to_sym if RedCard.check '1.9'
|
71
|
+
if klass.constants.member?(name)
|
72
|
+
klass.const_get(name)
|
73
|
+
else
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def set_const(klass, name, val)
|
79
|
+
name = name.to_sym if RedCard.check '1.9'
|
80
|
+
if klass.constants.member?(name)
|
81
|
+
klass.const_set(name, val)
|
82
|
+
else
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
68
87
|
def my_const(name)
|
69
88
|
# Set class constant SHORT_HELP to be the first line of HELP
|
70
89
|
# unless it has been defined in the class already.
|
71
90
|
# The below was the simplest way I could find to do this since
|
72
91
|
# we are the super class but want to set the subclass's constant.
|
73
92
|
# defined? didn't seem to work here.
|
74
|
-
|
75
|
-
if
|
76
|
-
short_help =
|
93
|
+
short_help = get_const(self.class, 'SHORT_HELP')
|
94
|
+
if !short_help and (help = get_const(self.class, 'HELP'))
|
95
|
+
short_help = help
|
77
96
|
self.class.const_set(:SHORT_HELP, short_help)
|
78
97
|
end
|
79
98
|
self.class.const_get(name)
|
@@ -97,18 +116,18 @@ class Trepan
|
|
97
116
|
end
|
98
117
|
|
99
118
|
def short_help
|
100
|
-
help_constant_sym = if self.class.constants.member?('SHORT_HELP')
|
101
|
-
:SHORT_HELP
|
119
|
+
help_constant_sym = if self.class.constants.member?('SHORT_HELP')
|
120
|
+
:SHORT_HELP
|
102
121
|
else :HELP
|
103
122
|
end
|
104
123
|
my_const(help_constant_sym)
|
105
124
|
end
|
106
125
|
|
107
126
|
# Define a method called 'complete' on the singleton class.
|
108
|
-
def self.completion(ary)
|
109
|
-
self.send(:define_method,
|
110
|
-
:complete,
|
111
|
-
Proc.new {|prefix|
|
127
|
+
def self.completion(ary)
|
128
|
+
self.send(:define_method,
|
129
|
+
:complete,
|
130
|
+
Proc.new {|prefix|
|
112
131
|
Trepan::Complete.complete_token(ary, prefix) })
|
113
132
|
end
|
114
133
|
|