trepanning 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +237 -0
- data/NEWS +8 -0
- data/Rakefile +3 -2
- data/app/breakpoint.rb +8 -8
- data/app/brkptmgr.rb +86 -85
- data/app/client.rb +60 -0
- data/app/core.rb-consider +198 -0
- data/app/default.rb +17 -7
- data/app/disassemble.rb +12 -2
- data/app/options.rb +51 -20
- data/app/yarv.rb +183 -0
- data/bin/trepan +15 -9
- data/data/custom_require.rb +44 -0
- data/data/irbrc +41 -0
- data/data/prelude.rb +38 -0
- data/interface/base_intf.rb +10 -4
- data/interface/client.rb +79 -0
- data/interface/comcodes.rb +18 -0
- data/interface/server.rb +142 -0
- data/io/base_io.rb +57 -3
- data/io/tcpclient.rb +122 -0
- data/io/tcpfns.rb +31 -0
- data/io/tcpserver.rb +137 -0
- data/lib/trepanning.rb +57 -28
- data/processor/command/base/cmd.rb +10 -6
- data/processor/command/base/subcmd.rb +13 -1
- data/processor/command/directory.rb +15 -8
- data/processor/command/disassemble.rb +3 -2
- data/processor/command/help.rb +71 -19
- data/processor/command/info_subcmd/args.rb +2 -3
- data/processor/command/info_subcmd/breakpoints.rb +2 -3
- data/processor/command/info_subcmd/file.rb +2 -3
- data/processor/command/info_subcmd/frame.rb +2 -3
- data/processor/command/info_subcmd/iseq.rb +4 -5
- data/processor/command/info_subcmd/locals.rb +2 -3
- data/processor/command/info_subcmd/program.rb +2 -3
- data/processor/command/info_subcmd/registers.rb +2 -3
- data/processor/command/info_subcmd/return.rb +2 -3
- data/processor/command/info_subcmd/thread.rb +2 -3
- data/processor/command/list.rb +10 -6
- data/processor/command/reload.rb +1 -1
- data/processor/command/reload_subcmd/command.rb +29 -16
- data/processor/command/server.rb +70 -0
- data/processor/command/set_subcmd/auto.rb +2 -3
- data/processor/command/set_subcmd/basename.rb +2 -3
- data/processor/command/set_subcmd/debug.rb +2 -3
- data/processor/command/set_subcmd/different.rb +2 -3
- data/processor/command/set_subcmd/events.rb +2 -3
- data/processor/command/set_subcmd/hidelevel.rb +6 -7
- data/processor/command/set_subcmd/highlight.rb +32 -0
- data/processor/command/set_subcmd/max.rb +2 -3
- data/processor/command/set_subcmd/return.rb +2 -3
- data/processor/command/set_subcmd/sp.rb +2 -3
- data/processor/command/set_subcmd/substitute.rb +2 -3
- data/processor/command/set_subcmd/timer.rb +2 -3
- data/processor/command/set_subcmd/trace.rb +3 -4
- data/processor/command/show_subcmd/alias.rb +3 -3
- data/processor/command/show_subcmd/args.rb +2 -3
- data/processor/command/show_subcmd/auto.rb +1 -2
- data/processor/command/show_subcmd/basename.rb +2 -3
- data/processor/command/show_subcmd/debug.rb +1 -2
- data/processor/command/show_subcmd/different.rb +2 -1
- data/processor/command/show_subcmd/events.rb +2 -2
- data/processor/command/show_subcmd/hidelevel.rb +2 -3
- data/processor/command/show_subcmd/highlight.rb +23 -0
- data/processor/command/show_subcmd/macro.rb +2 -1
- data/processor/command/show_subcmd/max.rb +2 -3
- data/processor/command/show_subcmd/trace.rb +2 -3
- data/processor/command/source.rb +78 -28
- data/processor/default.rb +3 -2
- data/processor/load_cmds.rb +39 -19
- data/processor/location.rb +11 -7
- data/processor/main.rb +31 -15
- data/processor/mock.rb +22 -7
- data/processor/msg.rb +24 -8
- data/test/data/fname-with-blank.right +3 -0
- data/test/data/quit.right +2 -0
- data/test/functional/test-break-long.rb +87 -0
- data/test/functional/tmp/b3.rb +5 -0
- data/test/functional/tmp/immediate-bug1.rb +9 -0
- data/test/integration/helper.rb +14 -11
- data/test/integration/test-fname-with-blank.rb +5 -1
- data/test/integration/test-quit.rb +6 -2
- data/test/unit/cmd-helper.rb +9 -4
- data/test/unit/mock-helper.rb +9 -0
- data/test/unit/test-app-brkpt.rb +4 -4
- data/test/unit/test-app-brkptmgr.rb +2 -2
- data/test/unit/test-app-file.rb +0 -1
- data/test/unit/test-app-options.rb +26 -5
- data/test/unit/test-base-subcmd.rb +0 -1
- data/test/unit/test-cmd-alias.rb +0 -1
- data/test/unit/test-cmd-break.rb +0 -4
- data/test/unit/test-cmd-endisable.rb +1 -3
- data/test/unit/test-cmd-help.rb +0 -1
- data/test/unit/test-cmd-kill.rb +4 -5
- data/test/unit/test-cmd-quit.rb +4 -7
- data/test/unit/test-cmd-source.rb +33 -0
- data/test/unit/test-cmd-step.rb +0 -2
- data/test/unit/test-io-tcp.rb +32 -0
- data/test/unit/test-io-tcpclient.rb +53 -0
- data/test/unit/test-io-tcpserver.rb +49 -0
- data/test/unit/test-proc-main.rb +2 -2
- metadata +195 -175
- data/processor/command/stepi.rb +0 -63
- data/test/functional/tmp/b1.rb +0 -5
- data/test/functional/tmp/s1.rb +0 -9
- data/test/functional/tmp/t2.rb +0 -6
- data/test/integration/try-test-enable.rb +0 -11
data/app/yarv.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
# A CodeRay Scanner for YARV
|
3
|
+
# FIXME: add unit test.
|
4
|
+
require 'rubygems'
|
5
|
+
require 'coderay'
|
6
|
+
module CodeRay
|
7
|
+
module Scanners
|
8
|
+
|
9
|
+
class YARV < Scanner
|
10
|
+
|
11
|
+
include Streamable
|
12
|
+
|
13
|
+
register_for :yarv
|
14
|
+
file_extension 'yarv'
|
15
|
+
|
16
|
+
def string_parse(tokens)
|
17
|
+
if match = scan(/^"[^"]*"/)
|
18
|
+
string = match.dup
|
19
|
+
while "\\" == match[-2..-2]
|
20
|
+
match = scan(/^.*"/)
|
21
|
+
break unless match
|
22
|
+
string << match
|
23
|
+
end
|
24
|
+
tokens << [string, :string]
|
25
|
+
true
|
26
|
+
else
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def space_parse(tokens)
|
32
|
+
if match = scan(/^[ \t]*/)
|
33
|
+
tokens << [match, :space] if match
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def scan_tokens(tokens, options)
|
38
|
+
|
39
|
+
state = :initial
|
40
|
+
number_expected = true
|
41
|
+
|
42
|
+
until eos?
|
43
|
+
|
44
|
+
kind = nil
|
45
|
+
match = nil
|
46
|
+
|
47
|
+
case state
|
48
|
+
|
49
|
+
when :initial
|
50
|
+
if match = scan(/^\s*/)
|
51
|
+
tokens << [match, :space] unless match.empty?
|
52
|
+
end
|
53
|
+
state =
|
54
|
+
if match = scan(/^$/)
|
55
|
+
:initial
|
56
|
+
else
|
57
|
+
:expect_label
|
58
|
+
end
|
59
|
+
|
60
|
+
when :expect_label
|
61
|
+
state =
|
62
|
+
if match = scan(/\d+/x)
|
63
|
+
tokens << [match, :label]
|
64
|
+
:expect_opcode
|
65
|
+
else
|
66
|
+
match = scan(/^.*$/)
|
67
|
+
tokens << [match, :error]
|
68
|
+
:initial
|
69
|
+
end
|
70
|
+
|
71
|
+
when :expect_opcode
|
72
|
+
state =
|
73
|
+
if match = scan(/(\s+)(\S+)/)
|
74
|
+
match =~ /(\s+)(\S+)/
|
75
|
+
tokens << [$1, :space]
|
76
|
+
opcode = $2
|
77
|
+
tokens << [opcode, :reserved]
|
78
|
+
:expect_operand
|
79
|
+
else
|
80
|
+
match = scan(/^(.*)$/)
|
81
|
+
tokens << [match, :error]
|
82
|
+
:initial
|
83
|
+
end
|
84
|
+
|
85
|
+
when :expect_literal
|
86
|
+
space_parse(tokens)
|
87
|
+
if match = scan(/^#<.+>/)
|
88
|
+
tokens << [match, :content]
|
89
|
+
elsif match = scan(/^(\d+)/)
|
90
|
+
tokens << [match, :integer]
|
91
|
+
elsif match = scan(/^([:][^: ,\n]+)/)
|
92
|
+
tokens << [match, :symbol]
|
93
|
+
elsif string_parse(tokens)
|
94
|
+
#
|
95
|
+
elsif match = scan(/nil|true|false/)
|
96
|
+
tokens << [match, :pre_constant]
|
97
|
+
elsif match = scan(/\/.*\//)
|
98
|
+
tokens << [match, :entity]
|
99
|
+
else
|
100
|
+
match = scan(/^.*$/)
|
101
|
+
tokens << [match, :error] unless match.empty?
|
102
|
+
end
|
103
|
+
state = :expect_opt_lineno
|
104
|
+
|
105
|
+
when :expect_operand
|
106
|
+
space_parse(tokens)
|
107
|
+
state = :expect_another_operand
|
108
|
+
if match = scan(/^(\d+)/)
|
109
|
+
tokens << [match, :integer]
|
110
|
+
elsif match = scan(/\/.*\//)
|
111
|
+
# Really a regular expression
|
112
|
+
tokens << [match, :entity]
|
113
|
+
elsif match = scan(/^([:][^: ,\n]+)/)
|
114
|
+
tokens << [match, :symbol]
|
115
|
+
elsif match = scan(/^([$][^ ,\n]+)/)
|
116
|
+
tokens << [match, :global_variable]
|
117
|
+
elsif match = scan(/nil|true|false/)
|
118
|
+
tokens << [match, :pre_constant]
|
119
|
+
elsif match = scan(/nil|true|false/)
|
120
|
+
tokens << [match, :pre_constant]
|
121
|
+
elsif match = scan(/[A-Za-z_][_A-Za-z0-9?!]*/)
|
122
|
+
tokens << [match, :variable]
|
123
|
+
elsif match = scan(/^#[^, \n]*/)
|
124
|
+
tokens << [match, :content]
|
125
|
+
elsif match = scan(/^<.+>/)
|
126
|
+
tokens << [match, :content]
|
127
|
+
elsif string_parse(tokens)
|
128
|
+
else
|
129
|
+
state = :expect_opt_lineno
|
130
|
+
end
|
131
|
+
|
132
|
+
when :expect_another_operand
|
133
|
+
state =
|
134
|
+
if match = scan(/^,/)
|
135
|
+
tokens << [match, :operator]
|
136
|
+
:expect_operand
|
137
|
+
else
|
138
|
+
:expect_opt_lineno
|
139
|
+
end
|
140
|
+
when :expect_opt_lineno
|
141
|
+
space_parse(tokens)
|
142
|
+
if match = scan(/^\(\s+\d+\)$/)
|
143
|
+
tokens << [match, :comment]
|
144
|
+
else
|
145
|
+
match = scan(/^.*$/)
|
146
|
+
tokens << [match, :error] unless match.empty?
|
147
|
+
end
|
148
|
+
state = :initial
|
149
|
+
end
|
150
|
+
end
|
151
|
+
tokens
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
if __FILE__ == $0
|
157
|
+
require 'term/ansicolor'
|
158
|
+
ruby_scanner = CodeRay.scanner :yarv
|
159
|
+
string='
|
160
|
+
0045 opt_regexpmatch1 /^-e$/
|
161
|
+
0000 trace 1 ( 9)
|
162
|
+
0002 putnil
|
163
|
+
0003 putstring "irb"
|
164
|
+
0005 send :require, 1, nil, 8, <ic:0>
|
165
|
+
0011 pop
|
166
|
+
0012 trace 1 ( 11)
|
167
|
+
0014 putstring "/usr/local/bin/irb"
|
168
|
+
0016 getglobal $0
|
169
|
+
0018 opt_eq <ic:8>
|
170
|
+
0020 branchunless 41
|
171
|
+
0022 trace 1 ( 12)
|
172
|
+
0024 getinlinecache 31, <ic:2>
|
173
|
+
0027 getconstant :IRB
|
174
|
+
0029 setinlinecache <ic:2>
|
175
|
+
0031 putstring "/usr/local/bin/irb"
|
176
|
+
0033 send :start, 1, nil, 0, <ic:3>
|
177
|
+
'
|
178
|
+
yarv_scanner = CodeRay.scanner :yarv
|
179
|
+
tokens = yarv_scanner.tokenize(string)
|
180
|
+
p tokens
|
181
|
+
yarv_highlighter = CodeRay::Duo[:yarv, :term]
|
182
|
+
puts yarv_highlighter.encode(string)
|
183
|
+
end
|
data/bin/trepan
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
2
|
+
# Copyright (C) 2010, 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
# Invoke debugger from the command line.
|
4
4
|
require_relative '../app/run'
|
5
5
|
require_relative '../app/options'
|
6
|
+
require_relative '../app/client'
|
6
7
|
require_relative '../lib/trepanning'
|
7
8
|
|
8
9
|
# FIXME: the figure out how to run via gem installation.
|
@@ -20,8 +21,8 @@ if File.basename(__FILE__) == File.basename($0)
|
|
20
21
|
# options = DEFAULT_CMDLINE_SETTINGS.merge({}) seems to change up
|
21
22
|
# DEFAULT_CMDLINE_SETTINGS when options[:key] is changed. The
|
22
23
|
# below is the simplest thing I can come up with so far.
|
23
|
-
options = copy_default_options
|
24
|
-
opts = setup_options(options)
|
24
|
+
options = Trepan.copy_default_options
|
25
|
+
opts = Trepan.setup_options(options)
|
25
26
|
Trepan::ARGV = ARGV.clone
|
26
27
|
rest = opts.parse! ARGV
|
27
28
|
|
@@ -34,13 +35,15 @@ if File.basename(__FILE__) == File.basename($0)
|
|
34
35
|
# FIXME: Should (some of) these be instance variables?
|
35
36
|
Trepan::RUBY_PATH = ruby_path
|
36
37
|
Trepan::TREPAN_PATH = trepan_path
|
37
|
-
Trepan::RBDBGR_FILE = __FILE__
|
38
38
|
|
39
39
|
if ARGV.empty?
|
40
40
|
if options[:version] || options[:help]
|
41
41
|
exit 100
|
42
|
+
elsif options[:client]
|
43
|
+
start_client(options)
|
44
|
+
exit
|
42
45
|
else
|
43
|
-
STDERR.puts 'Sorry - for now you must specify a Ruby script to debug.'
|
46
|
+
STDERR.puts 'Sorry - for now you must specify a Ruby script to debug or use the --client option.'
|
44
47
|
exit(1)
|
45
48
|
end
|
46
49
|
end
|
@@ -51,10 +54,13 @@ if File.basename(__FILE__) == File.basename($0)
|
|
51
54
|
Trepan::PROG_SCRIPT = program_to_debug
|
52
55
|
|
53
56
|
# Set global so others may use this debugger.
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
|
58
|
+
opts = {}
|
59
|
+
%w(cmdfiles initial_dir host nx port server highlight).each do |opt|
|
60
|
+
opts[opt.to_sym] = options[opt.to_sym]
|
61
|
+
end
|
62
|
+
|
63
|
+
$trepan = Trepan.new(opts)
|
58
64
|
debug_program($trepan, Trepan::RUBY_PATH,
|
59
65
|
File.expand_path(program_to_debug))
|
60
66
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
module Kernel
|
8
|
+
|
9
|
+
##
|
10
|
+
# The Kernel#require from before RubyGems was loaded.
|
11
|
+
|
12
|
+
alias gem_original_require require
|
13
|
+
|
14
|
+
##
|
15
|
+
# When RubyGems is required, Kernel#require is replaced with our own which
|
16
|
+
# is capable of loading gems on demand.
|
17
|
+
#
|
18
|
+
# When you call <tt>require 'x'</tt>, this is what happens:
|
19
|
+
# * If the file can be loaded from the existing Ruby loadpath, it
|
20
|
+
# is.
|
21
|
+
# * Otherwise, installed gems are searched for a file that matches.
|
22
|
+
# If it's found in gem 'y', that gem is activated (added to the
|
23
|
+
# loadpath).
|
24
|
+
#
|
25
|
+
# The normal <tt>require</tt> functionality of returning false if
|
26
|
+
# that file has already been loaded is preserved.
|
27
|
+
|
28
|
+
def require(path) # :doc:
|
29
|
+
gem_original_require path
|
30
|
+
rescue LoadError => load_error
|
31
|
+
if load_error.message.end_with?(path)
|
32
|
+
if Gem.try_activate(path)
|
33
|
+
return gem_original_require(path)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
raise load_error
|
38
|
+
end
|
39
|
+
|
40
|
+
private :require
|
41
|
+
private :gem_original_require
|
42
|
+
|
43
|
+
end unless Kernel.private_method_defined?(:gem_original_require)
|
44
|
+
|
data/data/irbrc
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- Ruby -*-
|
2
|
+
# Copyright (C) 2010 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
# We use this as the default startup file for irb inside trepan
|
4
|
+
# Down the line we will have a way for folks to add/override this
|
5
|
+
# with their own file.
|
6
|
+
IRB.conf[:PROMPT_MODE] = :SIMPLE
|
7
|
+
IRB.conf[:PROMPT][:SIMPLE] =
|
8
|
+
{:PROMPT_C=>"trepan ?> ",
|
9
|
+
:PROMPT_I=>"trepan >> ",
|
10
|
+
:PROMPT_N=>"trepan >> ",
|
11
|
+
:PROMPT_S=>nil,
|
12
|
+
:RETURN=>"=> %s\n"}
|
13
|
+
|
14
|
+
# Using dbgr to issue a debugger statement inside irb:
|
15
|
+
# dbgr %w(info program)
|
16
|
+
# dbgr 'info program' # also works
|
17
|
+
# But...
|
18
|
+
# dbgr info program # wrong!
|
19
|
+
#
|
20
|
+
puts "You are in a trepan session. You should have access to program scope."
|
21
|
+
puts "'dbgr', 'step', 'ne', 'q', 'cont' commands have been added."
|
22
|
+
|
23
|
+
if defined?($trepan) && $trepan
|
24
|
+
puts 'You should have access to debugger state via global variable $trepan'
|
25
|
+
end
|
26
|
+
if defined?($trepan_frame) && $trepan_frame
|
27
|
+
puts 'You should have access to the program frame via global variable $trepan_frame'
|
28
|
+
end
|
29
|
+
if defined?($trepan_cmdproc) && $trepan_cmdproc
|
30
|
+
puts 'You should have access to the command processor via global variable $trepan_cmdproc'
|
31
|
+
end
|
32
|
+
|
33
|
+
# Monkeypatch to save the current IRB statement to be run.
|
34
|
+
class IRB::Context
|
35
|
+
alias_method :_trepan_original_evaluate, :evaluate
|
36
|
+
def evaluate(line, line_no)
|
37
|
+
$trepan_irb_statements = line
|
38
|
+
_trepan_original_evaluate(line, line_no)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
data/data/prelude.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
# Mutex
|
3
|
+
|
4
|
+
class Mutex
|
5
|
+
def synchronize
|
6
|
+
self.lock
|
7
|
+
begin
|
8
|
+
yield
|
9
|
+
ensure
|
10
|
+
self.unlock rescue nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Thread
|
16
|
+
|
17
|
+
class Thread
|
18
|
+
MUTEX_FOR_THREAD_EXCLUSIVE = Mutex.new
|
19
|
+
def self.exclusive
|
20
|
+
MUTEX_FOR_THREAD_EXCLUSIVE.synchronize{
|
21
|
+
yield
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Kernel
|
27
|
+
module_function
|
28
|
+
def require_relative(relative_feature)
|
29
|
+
c = caller.first
|
30
|
+
e = c.rindex(/:\d+:in /)
|
31
|
+
file = $`
|
32
|
+
if /\A\((.*)\)/ =~ file # eval, etc.
|
33
|
+
raise LoadError, "require_relative is called in #{$1}"
|
34
|
+
end
|
35
|
+
absolute_feature = File.expand_path(File.join(File.dirname(file), relative_feature))
|
36
|
+
require absolute_feature
|
37
|
+
end
|
38
|
+
end
|
data/interface/base_intf.rb
CHANGED
@@ -33,8 +33,8 @@ class Trepan
|
|
33
33
|
|
34
34
|
# Closes all input and/or output.
|
35
35
|
def close
|
36
|
-
@input.close unless @input.closed?
|
37
|
-
@output.close unless @output.closed?
|
36
|
+
@input.close unless !@input || @input.closed?
|
37
|
+
@output.close unless !@output || @output.closed?
|
38
38
|
end
|
39
39
|
|
40
40
|
# Called when a dangerous action is about to be done to make sure
|
@@ -58,6 +58,10 @@ class Trepan
|
|
58
58
|
close
|
59
59
|
end
|
60
60
|
|
61
|
+
def input_eof?
|
62
|
+
@input.eof?
|
63
|
+
end
|
64
|
+
|
61
65
|
# Return true if interface is interactive.
|
62
66
|
def interactive?
|
63
67
|
# Default false and making subclasses figure out how to determine
|
@@ -82,8 +86,10 @@ class Trepan
|
|
82
86
|
@output.write(msg)
|
83
87
|
end
|
84
88
|
|
85
|
-
def read_command(
|
86
|
-
|
89
|
+
def read_command(prompt='')
|
90
|
+
line = readline(prompt)
|
91
|
+
# FIXME: Do something with history?
|
92
|
+
return line
|
87
93
|
end
|
88
94
|
|
89
95
|
def readline(prompt='')
|
data/interface/client.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2011 Rocky Bernstein <rockyb@rubyforge.net>
|
3
|
+
|
4
|
+
# Interface for client (i.e. user to communication-device) interaction.
|
5
|
+
# The debugged program is at the other end of the communcation.
|
6
|
+
|
7
|
+
require_relative 'user'
|
8
|
+
require_relative '../io/tcpclient'
|
9
|
+
require_relative 'comcodes'
|
10
|
+
|
11
|
+
# Mfifoclient = import_relative('fifoclient', '..io', 'pydbgr')
|
12
|
+
|
13
|
+
# Interface for a user which is attached to a debugged process via
|
14
|
+
# some sort of communication medium (e.g. socket, tty, FIFOs). This
|
15
|
+
# could be on the same computer in a different process or on a remote
|
16
|
+
# computer.
|
17
|
+
class Trepan::ClientInterface < Trepan::Interface
|
18
|
+
|
19
|
+
DEFAULT_INIT_CONNECTION_OPTS = {
|
20
|
+
:open => true,
|
21
|
+
:io => :tcp
|
22
|
+
}
|
23
|
+
|
24
|
+
def initialize(inp=nil, out=nil, inout=nil, user_opts={},
|
25
|
+
connection_opts={})
|
26
|
+
|
27
|
+
@connection_opts = DEFAULT_INIT_CONNECTION_OPTS.merge(connection_opts)
|
28
|
+
|
29
|
+
@user = Trepan::UserInterface.new(inp, out, user_opts)
|
30
|
+
|
31
|
+
@inout =
|
32
|
+
if inout
|
33
|
+
inout
|
34
|
+
else
|
35
|
+
# @server_type = @connection_opts[:io]
|
36
|
+
# if 'FIFO' == self.server_type
|
37
|
+
# Mfifoclient.FIFOClient(opts=@connection_opts)
|
38
|
+
# elsif :tcp == self.server_type
|
39
|
+
Trepan::TCPDbgClient.new(@connection_opts)
|
40
|
+
# else
|
41
|
+
# errmsg("Expecting server type TCP or FIFO. Got: %s." %
|
42
|
+
# self.server_type)
|
43
|
+
# return
|
44
|
+
# end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def confirm(prompt, default)
|
49
|
+
@user.confirm(prompt, default)
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_command(prompt='')
|
53
|
+
@user.read_command(prompt)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Send a message back to the server (in contrast to the local user
|
57
|
+
# output channel).
|
58
|
+
def read_remote
|
59
|
+
coded_line = nil
|
60
|
+
until coded_line
|
61
|
+
coded_line = @inout.read_msg
|
62
|
+
end
|
63
|
+
control = coded_line[0..0]
|
64
|
+
remote_line = coded_line[1..-1]
|
65
|
+
[control, remote_line]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Send a message back to the server (in contrast to the local user
|
69
|
+
# output channel).
|
70
|
+
def write_remote(code, msg)
|
71
|
+
# FIXME change into write_xxx
|
72
|
+
@inout.writeline(code + msg)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Demo
|
77
|
+
if __FILE__ == $0
|
78
|
+
intf = Trepan::ClientInterface.new
|
79
|
+
end
|