rbx-trepanning 0.2.0-universal-rubinius-2.0 → 0.2.1-universal-rubinius-2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +2 -1
- data/.travis.yml +4 -0
- data/ChangeLog +119 -1
- data/Gemfile +16 -0
- data/NEWS +15 -8
- data/README.md +72 -0
- data/Rakefile +16 -13
- 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/options.rb +1 -1
- data/app/util.rb +17 -10
- data/lib/trepanning.rb +0 -1
- data/processor.rb +32 -32
- data/processor/command.rb +32 -13
- 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/help.rb +9 -11
- data/processor/load_cmds.rb +26 -16
- data/processor/mock.rb +8 -9
- data/processor/subcmd.rb +12 -12
- data/test/functional/fn_helper.rb +8 -7
- data/test/functional/test-recursive-bt.rb +26 -15
- 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-io-tcpserver.rb +10 -5
- data/test/unit/test-proc-validate.rb +4 -4
- metadata +116 -110
- data/README.textile +0 -34
data/app/complete.rb
CHANGED
@@ -12,21 +12,21 @@ class Trepan
|
|
12
12
|
def complete_token(complete_ary, prefix)
|
13
13
|
complete_ary.select { |cmd| cmd.to_s.start_with?(prefix) }.map{|cmd| cmd.to_s}.sort
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def complete_token_with_next(complete_hash, prefix, cmd_prefix='')
|
17
17
|
result = []
|
18
|
-
complete_hash.each do |cmd_name, cmd_obj|
|
19
|
-
result << [cmd_name.to_s[cmd_prefix.size..-1], cmd_obj] if
|
18
|
+
complete_hash.each do |cmd_name, cmd_obj|
|
19
|
+
result << [cmd_name.to_s[cmd_prefix.size..-1], cmd_obj] if
|
20
20
|
cmd_name.to_s.start_with?(cmd_prefix + prefix)
|
21
21
|
end
|
22
22
|
result.sort{|a, b| a[0] <=> b[0]}
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
# Find all starting matches in Hash +aliases+ that start with +prefix+,
|
26
26
|
# but filter out any matches already in +expanded+.
|
27
27
|
def complete_token_filtered(aliases, prefix, expanded)
|
28
28
|
complete_ary = aliases.keys
|
29
|
-
complete_ary.select { |cmd|
|
29
|
+
complete_ary.select { |cmd|
|
30
30
|
cmd.to_s.start_with?(prefix) && ! expanded.member?(aliases[cmd])}.sort
|
31
31
|
end
|
32
32
|
|
@@ -37,31 +37,31 @@ class Trepan
|
|
37
37
|
complete_ary = aliases.keys
|
38
38
|
expanded_ary = expanded.keys
|
39
39
|
result = []
|
40
|
-
complete_ary.each do |cmd|
|
41
|
-
if cmd.to_s.start_with?(prefix) &&
|
40
|
+
complete_ary.each do |cmd|
|
41
|
+
if cmd.to_s.start_with?(prefix) &&
|
42
42
|
!expanded_ary.member?(aliases[cmd])
|
43
|
-
result << [cmd, commands[aliases[cmd]]]
|
43
|
+
result << [cmd, commands[aliases[cmd]]]
|
44
44
|
end
|
45
45
|
end
|
46
46
|
result
|
47
47
|
end
|
48
48
|
|
49
49
|
# Find the next token in str string from start_pos, we return
|
50
|
-
# the token and the next blank position after the token or
|
50
|
+
# the token and the next blank position after the token or
|
51
51
|
# str.size if this is the last token. Tokens are delimited by
|
52
52
|
# white space.
|
53
53
|
def next_token(str, start_pos)
|
54
54
|
look_at = str[start_pos..-1]
|
55
55
|
next_nonblank_pos = start_pos + (look_at =~ /\S/ || 0)
|
56
|
-
next_blank_pos =
|
56
|
+
next_blank_pos =
|
57
57
|
if next_match = str[next_nonblank_pos..-1] =~ /\s/
|
58
|
-
next_nonblank_pos + next_match
|
58
|
+
next_nonblank_pos + next_match
|
59
59
|
else
|
60
60
|
str.size
|
61
61
|
end
|
62
62
|
return [next_blank_pos, str[next_nonblank_pos...next_blank_pos]]
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
data/app/default.rb
CHANGED
@@ -9,7 +9,7 @@ class Trepan
|
|
9
9
|
DEFAULT_SETTINGS = {
|
10
10
|
:cmdproc_opts => {}, # Default Trepan::CmdProcessor settings
|
11
11
|
:core_opts => {}, # Default Trepan::Core settings
|
12
|
-
:delete_restore => true, # Delete restore profile after reading?
|
12
|
+
:delete_restore => true, # Delete restore profile after reading?
|
13
13
|
:initial_dir => nil, # If --cd option was given, we save it here.
|
14
14
|
:nx => false, # Don't run user startup file (e.g. .trepanxrc)
|
15
15
|
:offset => 0, # skipping back +offset+ frames. This lets you start
|
@@ -18,7 +18,7 @@ class Trepan
|
|
18
18
|
# Default values used only when 'server' or 'client'
|
19
19
|
# (out-of-process debugging)
|
20
20
|
:port => 1955,
|
21
|
-
:host => 'localhost',
|
21
|
+
:host => 'localhost',
|
22
22
|
|
23
23
|
:restart_argv => Rubinius::OS_ARGV,
|
24
24
|
# Command run when "restart" is given.
|
@@ -27,6 +27,7 @@ class Trepan
|
|
27
27
|
# command-line we need this to skip
|
28
28
|
# over some initial Rubinius loader
|
29
29
|
# commands.
|
30
|
+
:start_frame => 1,
|
30
31
|
} unless defined?(DEFAULT_SETTINGS)
|
31
32
|
|
32
33
|
# Default settings for Trepan run from the command line.
|
@@ -36,7 +37,7 @@ class Trepan
|
|
36
37
|
:nx => false, # Don't run user startup file (e.g. .trepanxrc)
|
37
38
|
:output => nil,
|
38
39
|
:port => DEFAULT_SETTINGS[:port],
|
39
|
-
:host => DEFAULT_SETTINGS[:host],
|
40
|
+
:host => DEFAULT_SETTINGS[:host],
|
40
41
|
:server => false, # Out-of-process debugging?
|
41
42
|
:readline => true, # Try to use GNU Readline?
|
42
43
|
# Note that at most one of :server or :client can be true.
|
@@ -48,10 +49,10 @@ class Trepan
|
|
48
49
|
:hide_stack => true,
|
49
50
|
} unless defined?(DEFAULT_DEBUG_STR_SETTINGS)
|
50
51
|
|
51
|
-
CMD_INITFILE_BASE =
|
52
|
+
CMD_INITFILE_BASE =
|
52
53
|
if RUBY_PLATFORM =~ /mswin/
|
53
54
|
# Of course MS Windows has to be different
|
54
|
-
HOME_DIR = (ENV['HOME'] ||
|
55
|
+
HOME_DIR = (ENV['HOME'] ||
|
55
56
|
ENV['HOMEDRIVE'].to_s + ENV['HOMEPATH'].to_s).to_s
|
56
57
|
'trepanx.ini'
|
57
58
|
else
|
data/app/options.rb
CHANGED
data/app/util.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
# Copyright (C) 2010,
|
1
|
+
# Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
require 'redcard/rubinius'
|
2
3
|
|
3
4
|
class Trepan
|
4
5
|
module Util
|
5
6
|
|
6
|
-
module_function
|
7
|
+
module_function
|
7
8
|
def safe_repr(str, max, elipsis='... ')
|
8
9
|
if str.is_a?(String) && max > 0 && str.size > max && !str.index("\n")
|
9
10
|
"%s%s%s" % [ str[0...max/2], elipsis, str[str.size-max/2..str.size]]
|
@@ -16,20 +17,20 @@ class Trepan
|
|
16
17
|
# If name is a unique leading prefix of one of the entries of list,
|
17
18
|
# then return that. Otherwise return name.
|
18
19
|
def uniq_abbrev(list, name)
|
19
|
-
candidates = list.select do |try_name|
|
20
|
+
candidates = list.select do |try_name|
|
20
21
|
try_name.start_with?(name)
|
21
22
|
end
|
22
23
|
candidates.size == 1 ? candidates.first : name
|
23
24
|
end
|
24
25
|
|
25
26
|
# extract the "expression" part of a line of source code.
|
26
|
-
#
|
27
|
+
#
|
27
28
|
def extract_expression(text)
|
28
29
|
if text =~ /^\s*(?:if|elsif|unless)\s+/
|
29
|
-
text.gsub!(/^\s*(?:if|elsif|unless)\s+/,'')
|
30
|
+
text.gsub!(/^\s*(?:if|elsif|unless)\s+/,'')
|
30
31
|
text.gsub!(/\s+then\s*$/, '')
|
31
32
|
elsif text =~ /^\s*(?:until|while)\s+/
|
32
|
-
text.gsub!(/^\s*(?:until|while)\s+/,'')
|
33
|
+
text.gsub!(/^\s*(?:until|while)\s+/,'')
|
33
34
|
text.gsub!(/\s+do\s*$/, '')
|
34
35
|
elsif text =~ /^\s*return\s+/
|
35
36
|
# EXPRESION in: return EXPRESSION
|
@@ -46,14 +47,20 @@ class Trepan
|
|
46
47
|
return text
|
47
48
|
end
|
48
49
|
|
50
|
+
|
51
|
+
def rubinius_internal?(loc)
|
52
|
+
('Object#' == loc.describe_receiver &&
|
53
|
+
:__script__ == loc.name && RedCard.check('1.8')) or
|
54
|
+
('Rubinius::Loader#' == loc.describe_receiver && RedCard.check('1.9'))
|
55
|
+
end
|
56
|
+
|
49
57
|
# Find user portion of script skipping over Rubinius code loading.
|
50
58
|
# Unless hidestack is off, we don't show parts of the frame below this.
|
51
59
|
def find_main_script(locs)
|
52
60
|
candidate = nil
|
53
61
|
(locs.size-1).downto(0) do |i|
|
54
62
|
loc = locs[i]
|
55
|
-
if
|
56
|
-
:__script__ == loc.name
|
63
|
+
if rubinius_internal?(loc)
|
57
64
|
if loc.method.active_path =~ /\/trepanx$/ ||
|
58
65
|
loc.method.active_path == 'kernel/loader.rb'
|
59
66
|
# Might have been run from standalone trepanx.
|
@@ -74,7 +81,7 @@ class Trepan
|
|
74
81
|
result = yield
|
75
82
|
$VERBOSE = original_verbosity
|
76
83
|
return result
|
77
|
-
end
|
84
|
+
end
|
78
85
|
end
|
79
86
|
end
|
80
87
|
|
@@ -86,7 +93,7 @@ if __FILE__ == $0
|
|
86
93
|
puts safe_repr(string.inspect, 17)
|
87
94
|
puts safe_repr(string.inspect, 17, '')
|
88
95
|
locs = Rubinius::VM.backtrace(0)
|
89
|
-
locs.each_with_index do |l, i|
|
96
|
+
locs.each_with_index do |l, i|
|
90
97
|
puts "#{i}: #{l.describe}"
|
91
98
|
end
|
92
99
|
## puts "main script in above is #{locs.size() - 1 - find_main_script(locs)}"
|
data/lib/trepanning.rb
CHANGED
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
|
|