trepanning 0.0.9 → 0.1.0
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/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
|