rb8-trepanning 0.1.5 → 0.1.6
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.
- data/CHANGES +18 -4
- data/ChangeLog +100 -87
- data/Makefile +23 -4
- data/README.textile +3 -3
- data/Rakefile +26 -20
- data/app/complete.rb +13 -13
- data/app/default.rb +8 -8
- data/app/display.rb +7 -7
- data/app/frame.rb +8 -8
- data/app/irb.rb +15 -15
- data/app/options.rb +25 -25
- data/app/run.rb +16 -8
- data/app/util.rb +7 -7
- data/bin/trepan8 +2 -2
- data/check-filter.rb +21 -0
- data/interface.rb +4 -4
- data/interface/user.rb +11 -11
- data/io.rb +18 -19
- data/io/input.rb +14 -12
- data/lib/debugger.rb +3 -1
- data/lib/trepanning.rb +30 -28
- data/processor.rb +41 -38
- data/processor/command.rb +9 -9
- data/processor/command/alias.rb +6 -6
- data/processor/command/down.rb +1 -2
- data/processor/command/edit.rb +12 -8
- data/processor/command/eval.rb +7 -7
- data/processor/command/info_subcmd/macro.rb +6 -6
- data/processor/command/info_subcmd/program.rb +5 -1
- data/processor/command/macro.rb +6 -6
- data/processor/command/show_subcmd/abbrev.rb +2 -2
- data/processor/command/up.rb +1 -2
- data/processor/complete.rb +120 -0
- data/processor/default.rb +13 -9
- data/processor/load_cmds.rb +18 -97
- data/processor/location.rb +34 -31
- data/processor/msg.rb +5 -5
- data/processor/validate.rb +44 -35
- data/test/data/break_loop_bug.right +2 -2
- data/test/data/edit.cmd +1 -1
- data/test/data/edit.right +7 -1
- data/test/data/printvar.right +2 -2
- data/test/data/raise.right +0 -1
- data/test/data/trace-mingw.right +28 -0
- data/test/integration/.gitignore +1 -0
- data/test/integration/test-raise.rb +10 -1
- data/test/integration/test-trace.rb +10 -6
- data/test/unit/test-app-options.rb +9 -3
- data/test/unit/test-app-run.rb +8 -1
- data/test/unit/test-cmd-alias.rb +2 -2
- data/test/unit/test-proc-default.rb +34 -0
- metadata +10 -6
data/app/run.rb
CHANGED
@@ -12,13 +12,13 @@ module Trepan
|
|
12
12
|
# see. FIXME: Should we make ARGV an explicit parameter?
|
13
13
|
def debug_program(ruby_path, options)
|
14
14
|
# Make sure Ruby script syntax checks okay.
|
15
|
-
# Otherwise we get a load message that looks like trepan8 has
|
16
|
-
# a problem.
|
17
|
-
|
15
|
+
# Otherwise we get a load message that looks like trepan8 has
|
16
|
+
# a problem.
|
17
|
+
|
18
18
|
output = ruby_syntax_errors(Trepan::PROG_SCRIPT.inspect)
|
19
19
|
if output
|
20
20
|
puts output
|
21
|
-
exit $?.exitstatus
|
21
|
+
exit $?.exitstatus
|
22
22
|
end
|
23
23
|
|
24
24
|
cmdproc = Debugger.handler.cmdproc
|
@@ -47,6 +47,14 @@ module Trepan
|
|
47
47
|
# Do a shell-like path lookup for prog_script and return the results.
|
48
48
|
# If we can't find anything return prog_script.
|
49
49
|
def whence_file(prog_script)
|
50
|
+
if RbConfig::CONFIG['target_os'].start_with?('mingw')
|
51
|
+
if (prog_script =~ /^[a-zA-Z][:]/)
|
52
|
+
start = prog_script[2..2]
|
53
|
+
if [File::ALT_SEPARATOR, File::SEPARATOR].member?(start)
|
54
|
+
return prog_script
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
50
58
|
if prog_script.start_with?(File::SEPARATOR) || prog_script.start_with?('.')
|
51
59
|
# Don't search since this name has path is explicitly absolute or
|
52
60
|
# relative.
|
@@ -69,11 +77,11 @@ module Trepan
|
|
69
77
|
end
|
70
78
|
end
|
71
79
|
|
72
|
-
# Path name of Ruby interpreter we were invoked with. Is part of
|
80
|
+
# Path name of Ruby interpreter we were invoked with. Is part of
|
73
81
|
# 1.9 but not necessarily 1.8.
|
74
82
|
def RbConfig.ruby
|
75
|
-
File.join(RbConfig::CONFIG['bindir'],
|
76
|
-
RbConfig::CONFIG['RUBY_INSTALL_NAME'] +
|
83
|
+
File.join(RbConfig::CONFIG['bindir'],
|
84
|
+
RbConfig::CONFIG['RUBY_INSTALL_NAME'] +
|
77
85
|
RbConfig::CONFIG['EXEEXT'])
|
78
86
|
end unless defined? RbConfig.ruby
|
79
87
|
|
@@ -83,7 +91,7 @@ if __FILE__ == $0
|
|
83
91
|
puts whence_file('irb')
|
84
92
|
puts whence_file('probably-does-not-exist')
|
85
93
|
puts RbConfig.ruby
|
86
|
-
puts "#{__FILE__} is syntactically correct" unless
|
94
|
+
puts "#{__FILE__} is syntactically correct" unless
|
87
95
|
ruby_syntax_errors(__FILE__)
|
88
96
|
readme = File.join(File.dirname(__FILE__), '..', 'README.textile')
|
89
97
|
puts "#{readme} is not syntactically correct" if
|
data/app/util.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Trepan
|
4
4
|
module Util
|
5
5
|
|
6
|
-
module_function
|
6
|
+
module_function
|
7
7
|
def safe_repr(str, max, elipsis='... ')
|
8
8
|
if str.is_a?(String) && max > 0 && str.size > max && !str.index("\n")
|
9
9
|
"%s%s%s" % [ str[0...max/2], elipsis, str[str.size-max/2..str.size]]
|
@@ -16,20 +16,20 @@ module Trepan
|
|
16
16
|
# If name is a unique leading prefix of one of the entries of list,
|
17
17
|
# then return that. Otherwise return name.
|
18
18
|
def uniq_abbrev(list, name)
|
19
|
-
candidates = list.select do |try_name|
|
19
|
+
candidates = list.select do |try_name|
|
20
20
|
try_name.start_with?(name)
|
21
21
|
end
|
22
22
|
candidates.size == 1 ? candidates.first : name
|
23
23
|
end
|
24
24
|
|
25
25
|
# extract the "expression" part of a line of source code.
|
26
|
-
#
|
26
|
+
#
|
27
27
|
def extract_expression(text)
|
28
28
|
if text =~ /^\s*(?:if|elsif|unless)\s+/
|
29
|
-
text.gsub!(/^\s*(?:if|elsif|unless)\s+/,'')
|
29
|
+
text.gsub!(/^\s*(?:if|elsif|unless)\s+/,'')
|
30
30
|
text.gsub!(/\s+then\s*$/, '')
|
31
31
|
elsif text =~ /^\s*(?:until|while)\s+/
|
32
|
-
text.gsub!(/^\s*(?:until|while)\s+/,'')
|
32
|
+
text.gsub!(/^\s*(?:until|while)\s+/,'')
|
33
33
|
text.gsub!(/\s+do\s*$/, '')
|
34
34
|
elsif text =~ /^\s*return\s+/
|
35
35
|
# EXPRESION in: return EXPRESSION
|
@@ -54,7 +54,7 @@ module Trepan
|
|
54
54
|
result = yield
|
55
55
|
$VERBOSE = original_verbosity
|
56
56
|
return result
|
57
|
-
end
|
57
|
+
end
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -67,7 +67,7 @@ if __FILE__ == $0
|
|
67
67
|
puts safe_repr(string.inspect, 17, '')
|
68
68
|
# ------------------------------------
|
69
69
|
# extract_expression
|
70
|
-
['if condition("if")',
|
70
|
+
['if condition("if")',
|
71
71
|
'until until_termination',
|
72
72
|
'return return_value',
|
73
73
|
'nothing_to_be.done'
|
data/bin/trepan8
CHANGED
@@ -81,8 +81,8 @@ else
|
|
81
81
|
# run startup script if specified
|
82
82
|
Trepan.add_command_file(options[:script]) if options[:script]
|
83
83
|
|
84
|
-
# activate post-mortem
|
85
|
-
|
84
|
+
# activate post-mortem. ruby-debug-base provides the hooks
|
85
|
+
Debugger.post_mortem if options[:post_mortem]
|
86
86
|
|
87
87
|
if !options[:quit]
|
88
88
|
if Debugger.started?
|
data/check-filter.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Use this to cut out the crud from make check.
|
3
|
+
# Use like this:
|
4
|
+
# make check 2>&1 | ruby ../make-check-filter.rb
|
5
|
+
# See Makefile.am
|
6
|
+
pats = ["^(?:Loaded",
|
7
|
+
"^WARNING: 'require",
|
8
|
+
'Started',
|
9
|
+
"Making check in",
|
10
|
+
'Test run options',
|
11
|
+
"^Loaded suite",
|
12
|
+
'^(?:re)?make\[',
|
13
|
+
'^##[<>]+'
|
14
|
+
].join('|') + ')'
|
15
|
+
# puts pats
|
16
|
+
skip_re = /#{pats}/
|
17
|
+
|
18
|
+
while gets()
|
19
|
+
next if $_ =~ skip_re
|
20
|
+
puts $_
|
21
|
+
end
|
data/interface.rb
CHANGED
@@ -11,7 +11,7 @@ module Trepan
|
|
11
11
|
|
12
12
|
# A debugger interface handles the communication or interaction with between
|
13
13
|
# the program and the outside portion which could be
|
14
|
-
# - a user,
|
14
|
+
# - a user,
|
15
15
|
# - a front-end that talks to a user, or
|
16
16
|
# - another interface in another process or computer
|
17
17
|
class Interface
|
@@ -30,7 +30,7 @@ module Trepan
|
|
30
30
|
@history_save = false
|
31
31
|
@histsize = nil
|
32
32
|
@input = inp || STDIN
|
33
|
-
@interactive = false
|
33
|
+
@interactive = false
|
34
34
|
@opts = opts
|
35
35
|
@output = out || STDOUT
|
36
36
|
end
|
@@ -60,7 +60,7 @@ module Trepan
|
|
60
60
|
|
61
61
|
def finalize(last_wishes=nil)
|
62
62
|
if @output && !@output.closed?
|
63
|
-
msg "%sThat's all, folks..." %
|
63
|
+
msg "%sThat's all, folks..." %
|
64
64
|
(defined?(Trepan::PROGRAM) ? "#{Trepan::PROGRAM}: " : '')
|
65
65
|
end
|
66
66
|
close
|
@@ -74,7 +74,7 @@ module Trepan
|
|
74
74
|
def interactive?
|
75
75
|
# Default false and making subclasses figure out how to determine
|
76
76
|
# interactiveness.
|
77
|
-
false
|
77
|
+
false
|
78
78
|
end
|
79
79
|
|
80
80
|
# used to write to a debugger that is connected to this
|
data/interface/user.rb
CHANGED
@@ -14,12 +14,12 @@ class Trepan::UserInterface < Trepan::Interface
|
|
14
14
|
|
15
15
|
DEFAULT_USER_OPTS = {
|
16
16
|
:readline => true, # Try to use GNU Readline?
|
17
|
-
|
17
|
+
|
18
18
|
# The below are only used if we want and have readline support.
|
19
19
|
# See method Trepan::GNU_readline? below.
|
20
20
|
:histsize => 256, # Use gdb's default setting
|
21
21
|
:file_history => '.trepan8_hist', # where history file lives
|
22
|
-
# Note a directory will
|
22
|
+
# Note a directory will
|
23
23
|
# be appended
|
24
24
|
:history_save => true # do we save the history?
|
25
25
|
} unless defined?(DEFAULT_USER_OPTS)
|
@@ -51,14 +51,14 @@ class Trepan::UserInterface < Trepan::Interface
|
|
51
51
|
def confirm(prompt, default)
|
52
52
|
default_str = default ? 'Y/n' : 'N/y'
|
53
53
|
while true do
|
54
|
-
begin
|
54
|
+
begin
|
55
55
|
response = readline('%s (%s) ' % [prompt, default_str])
|
56
56
|
rescue EOFError
|
57
57
|
return default
|
58
58
|
end
|
59
59
|
response = response.strip.downcase
|
60
60
|
|
61
|
-
# We don't catch "Yes, I'm sure" or "NO!", but I leave that
|
61
|
+
# We don't catch "Yes, I'm sure" or "NO!", but I leave that
|
62
62
|
# as an exercise for the reader.
|
63
63
|
break if YES_OR_NO.member?(response)
|
64
64
|
msg "Please answer 'yes' or 'no'. Try again."
|
@@ -69,7 +69,7 @@ class Trepan::UserInterface < Trepan::Interface
|
|
69
69
|
# Read a saved Readline history file into Readline. The history
|
70
70
|
# file will be created if it doesn't already exist.
|
71
71
|
# Much of this code follows what's done in ruby-debug.
|
72
|
-
def read_history
|
72
|
+
def read_history
|
73
73
|
unless @histfile
|
74
74
|
dirname = ENV['HOME'] || ENV['HOMEPATH'] || File.expand_path('~')
|
75
75
|
@histfile = File.join(dirname, @opts[:file_history])
|
@@ -77,8 +77,8 @@ class Trepan::UserInterface < Trepan::Interface
|
|
77
77
|
@histsize ||= (ENV['HISTSIZE'] ? ENV['HISTSIZE'].to_i : @opts[:histsize])
|
78
78
|
Readline.completion_proc = @opts[:complete]
|
79
79
|
if File.exists?(@histfile)
|
80
|
-
lines = IO::readlines(@histfile).last(@histsize).collect do
|
81
|
-
|line| line.chomp
|
80
|
+
lines = IO::readlines(@histfile).last(@histsize).collect do
|
81
|
+
|line| line.chomp
|
82
82
|
end
|
83
83
|
Readline::HISTORY.push(*lines)
|
84
84
|
@history_io = File.new(@histfile, "a")
|
@@ -89,7 +89,7 @@ class Trepan::UserInterface < Trepan::Interface
|
|
89
89
|
@history_save = @opts[:history_save]
|
90
90
|
end
|
91
91
|
|
92
|
-
def save_history
|
92
|
+
def save_history
|
93
93
|
if @histfile
|
94
94
|
lines = Readline::HISTORY.to_a
|
95
95
|
lines = lines[-@histsize, @histsize] if lines.size > @histsize
|
@@ -97,7 +97,7 @@ class Trepan::UserInterface < Trepan::Interface
|
|
97
97
|
open(@histfile, 'w') do |file|
|
98
98
|
Readline::HISTORY.to_a.last(@histsize).each do |line|
|
99
99
|
file.puts line
|
100
|
-
end
|
100
|
+
end
|
101
101
|
end if defined?(@history_save) and @history_save
|
102
102
|
rescue
|
103
103
|
end
|
@@ -107,7 +107,7 @@ class Trepan::UserInterface < Trepan::Interface
|
|
107
107
|
def finalize(last_wishes=nil)
|
108
108
|
# ?? print gdb-style exit annotation if annotate = 2?
|
109
109
|
if Trepan::GNU_readline? && @history_save
|
110
|
-
save_history
|
110
|
+
save_history
|
111
111
|
end
|
112
112
|
super
|
113
113
|
end
|
@@ -115,7 +115,7 @@ class Trepan::UserInterface < Trepan::Interface
|
|
115
115
|
def interactive? ; @input.interactive? end
|
116
116
|
|
117
117
|
def read_command(prompt='')
|
118
|
-
readline(prompt)
|
118
|
+
readline(prompt)
|
119
119
|
end
|
120
120
|
|
121
121
|
def readline(prompt='')
|
data/io.rb
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
# classes to support communication to and from the debugger. This
|
3
3
|
# communcation might be to/from another process or another computer.
|
4
4
|
# And reading may be from a debugger command script.
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# For example, we'd like to support Sockets, and serial lines and file
|
7
7
|
# reading, as well a readline-type input. Encryption and Authentication
|
8
8
|
# methods might decorate some of the communication channels.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Some ideas originiated as part of Matt Fleming's 2006 Google Summer of
|
11
11
|
# Code project.
|
12
12
|
|
@@ -14,7 +14,7 @@ module Trepan
|
|
14
14
|
|
15
15
|
NotImplementedMessage = 'This method must be overriden in a subclass' unless
|
16
16
|
defined?(NotImplementedMessage)
|
17
|
-
|
17
|
+
|
18
18
|
class InputBase
|
19
19
|
attr_reader :input
|
20
20
|
attr_reader :line_edit
|
@@ -33,7 +33,7 @@ module Trepan
|
|
33
33
|
@input.close unless @input.closed?
|
34
34
|
end
|
35
35
|
|
36
|
-
def eof?
|
36
|
+
def eof?
|
37
37
|
begin
|
38
38
|
@input.eof?
|
39
39
|
rescue IOError
|
@@ -41,7 +41,7 @@ module Trepan
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
# Read a line of input. EOFError will be raised on EOF.
|
44
|
+
# Read a line of input. EOFError will be raised on EOF.
|
45
45
|
#
|
46
46
|
# Note that we don't support prompting first. Instead, arrange
|
47
47
|
# to call Trepan::Output.write() first with the prompt. If
|
@@ -69,7 +69,7 @@ module Trepan
|
|
69
69
|
@eof = true
|
70
70
|
end
|
71
71
|
|
72
|
-
def eof?
|
72
|
+
def eof?
|
73
73
|
@eof
|
74
74
|
end
|
75
75
|
|
@@ -77,7 +77,7 @@ module Trepan
|
|
77
77
|
@output.flush
|
78
78
|
end
|
79
79
|
|
80
|
-
# Use this to set where to write to. output can be a
|
80
|
+
# Use this to set where to write to. output can be a
|
81
81
|
# file object or a string. This code raises IOError on error.
|
82
82
|
def write(*args)
|
83
83
|
@output.print(*args)
|
@@ -95,17 +95,17 @@ module Trepan
|
|
95
95
|
# handled by the same channel, e.g. a socket or tty.
|
96
96
|
#
|
97
97
|
class InOutBase
|
98
|
-
|
98
|
+
|
99
99
|
def initialize(inout, opts={})
|
100
100
|
@opts = DEFAULT_OPTS.merge(opts)
|
101
101
|
@inout = inout
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
def close
|
105
105
|
@inout.close() if @inout
|
106
106
|
end
|
107
|
-
|
108
|
-
def eof?
|
107
|
+
|
108
|
+
def eof?
|
109
109
|
begin
|
110
110
|
@input.eof?
|
111
111
|
rescue IOError
|
@@ -116,9 +116,9 @@ module Trepan
|
|
116
116
|
def flush
|
117
117
|
@inout.flush
|
118
118
|
end
|
119
|
-
|
120
|
-
# Read a line of input. EOFError will be raised on EOF.
|
121
|
-
#
|
119
|
+
|
120
|
+
# Read a line of input. EOFError will be raised on EOF.
|
121
|
+
#
|
122
122
|
# Note that we don't support prompting first. Instead, arrange to
|
123
123
|
# call DebuggerOutput.write() first with the prompt. If `use_raw'
|
124
124
|
# is set raw_input() will be used in that is supported by the
|
@@ -128,15 +128,15 @@ module Trepan
|
|
128
128
|
@input.readline
|
129
129
|
end
|
130
130
|
|
131
|
-
# Use this to set where to write to. output can be a
|
131
|
+
# Use this to set where to write to. output can be a
|
132
132
|
# file object or a string. This code raises IOError on error.
|
133
|
-
#
|
134
|
-
# Use this to set where to write to. output can be a
|
133
|
+
#
|
134
|
+
# Use this to set where to write to. output can be a
|
135
135
|
# file object or a string. This code raises IOError on error.
|
136
136
|
def write(*args)
|
137
137
|
@inout.write(*args)
|
138
138
|
end
|
139
|
-
|
139
|
+
|
140
140
|
# used to write to a debugger that is connected to this
|
141
141
|
# server; `str' written will have a newline added to it
|
142
142
|
def writeline( msg)
|
@@ -145,4 +145,3 @@ module Trepan
|
|
145
145
|
end
|
146
146
|
|
147
147
|
end
|
148
|
-
|
data/io/input.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
# Debugger user/command-oriented input possibly attached to IO-style
|
5
5
|
# input or GNU Readline.
|
6
|
-
#
|
6
|
+
#
|
7
7
|
|
8
8
|
require 'rubygems'; require 'require_relative'
|
9
9
|
require_relative '../io'
|
@@ -14,6 +14,8 @@ module Trepan
|
|
14
14
|
# input or GNU Readline.
|
15
15
|
class UserInput < Trepan::InputBase
|
16
16
|
|
17
|
+
attr_reader :use_readline
|
18
|
+
|
17
19
|
@@readline_finalized = false
|
18
20
|
|
19
21
|
def initialize(inp, opts={})
|
@@ -27,13 +29,13 @@ module Trepan
|
|
27
29
|
def closed?; @input.closed? end
|
28
30
|
def eof?; @eof end
|
29
31
|
|
30
|
-
def interactive?
|
32
|
+
def interactive?
|
31
33
|
@input.respond_to?(:isatty) && @input.isatty
|
32
34
|
end
|
33
|
-
# Read a line of input. EOFError will be raised on EOF.
|
35
|
+
# Read a line of input. EOFError will be raised on EOF.
|
34
36
|
def readline(prompt='')
|
35
37
|
raise EOFError if eof?
|
36
|
-
begin
|
38
|
+
begin
|
37
39
|
if @line_edit && @use_readline
|
38
40
|
line = Readline.readline(prompt, true)
|
39
41
|
else
|
@@ -49,28 +51,28 @@ module Trepan
|
|
49
51
|
raise EOFError if eof?
|
50
52
|
return line
|
51
53
|
end
|
52
|
-
|
54
|
+
|
53
55
|
class << self
|
54
|
-
# Use this to set where to read from.
|
56
|
+
# Use this to set where to read from.
|
55
57
|
#
|
56
58
|
# Set opts[:line_edit] if you want this input to interact with
|
57
59
|
# GNU-like readline library. By default, we will assume to try
|
58
|
-
# using readline.
|
60
|
+
# using readline.
|
59
61
|
def open(inp=nil, opts={})
|
60
62
|
inp ||= STDIN
|
61
63
|
inp = File.new(inp, 'r') if inp.is_a?(String)
|
62
|
-
opts[:line_edit] = @line_edit =
|
64
|
+
opts[:line_edit] = @line_edit =
|
63
65
|
inp.respond_to?(:isatty) && inp.isatty && Trepan::GNU_readline?
|
64
66
|
self.new(inp, opts)
|
65
67
|
end
|
66
68
|
|
67
69
|
def finalize
|
68
70
|
if defined?(RbReadline) && !@@readline_finalized
|
69
|
-
begin
|
71
|
+
begin
|
70
72
|
RbReadline.rl_cleanup_after_signal()
|
71
73
|
rescue
|
72
74
|
end
|
73
|
-
begin
|
75
|
+
begin
|
74
76
|
RbReadline.rl_deprep_terminal()
|
75
77
|
rescue
|
76
78
|
end
|
@@ -88,7 +90,7 @@ module Trepan
|
|
88
90
|
result = yield
|
89
91
|
$VERBOSE = original_verbosity
|
90
92
|
return result
|
91
|
-
end
|
93
|
+
end
|
92
94
|
module_function :suppress_warnings
|
93
95
|
end
|
94
96
|
|
@@ -117,7 +119,7 @@ def Trepan::GNU_readline?
|
|
117
119
|
return true
|
118
120
|
end
|
119
121
|
end
|
120
|
-
|
122
|
+
|
121
123
|
# Demo
|
122
124
|
if __FILE__ == $0
|
123
125
|
puts 'Have GNU is: %s' % Trepan::GNU_readline?
|