debug 0.2.1 → 1.0.0.alpha0

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/lib/debug/repl.rb ADDED
@@ -0,0 +1,67 @@
1
+ require_relative 'session'
2
+
3
+ module DEBUGGER__
4
+ class UI_Repl
5
+ def initialize
6
+ end
7
+
8
+ def quit n
9
+ exit n
10
+ end
11
+
12
+ def ask prompt
13
+ print prompt
14
+ (gets || '').strip
15
+ end
16
+
17
+ def puts str
18
+ case str
19
+ when Array
20
+ str.each{|line|
21
+ $stdout.puts line.chomp
22
+ }
23
+ when String
24
+ str.each_line{|line|
25
+ $stdout.puts line.chomp
26
+ }
27
+ when nil
28
+ $stdout.puts
29
+ end
30
+ end
31
+
32
+ begin
33
+ require 'readline'
34
+ def readline
35
+ setup_interrupt do
36
+ str = Readline.readline("\n(rdb) ", true)
37
+ (str || 'quit').strip
38
+ end
39
+ end
40
+ rescue LoadError
41
+ def readline
42
+ setup_interrupt do
43
+ print "\n(rdb) "
44
+ (gets || 'quit').strip
45
+ end
46
+ end
47
+ end
48
+
49
+ def setup_interrupt
50
+ current_thread = Thread.current # should be session_server thread
51
+
52
+ prev_handler = trap(:INT){
53
+ current_thread.raise Interrupt
54
+ }
55
+
56
+ yield
57
+ ensure
58
+ trap(:INT, prev_handler)
59
+ end
60
+ end
61
+
62
+ SESSION = Session.new(UI_Repl.new)
63
+
64
+ PREV_HANDLER = trap(:SIGINT){
65
+ ThreadClient.current.on_trap
66
+ }
67
+ end
@@ -0,0 +1,119 @@
1
+ require 'socket'
2
+ require_relative 'session'
3
+
4
+ module DEBUGGER__
5
+ class UI_Server
6
+ def initialize
7
+ @sock = nil
8
+ @client_addr = nil
9
+ @q_msg = Queue.new
10
+ @q_ans = Queue.new
11
+
12
+ @reader_thread = Thread.new do
13
+ accept do |server|
14
+ @sock = server
15
+ @q_msg = Queue.new
16
+ @q_ans = Queue.new
17
+
18
+ setup_interrupt do
19
+ pause
20
+
21
+ begin
22
+ while line = @sock.gets
23
+ case line
24
+ when /\Apause/
25
+ pause
26
+ when /\Acommand ?(.+)/
27
+ @q_msg << $1
28
+ when /\Aanswer (.*)/
29
+ @q_ans << $1
30
+ else
31
+ STDERR.puts "unsupported: #{line}"
32
+ exit!
33
+ end
34
+ end
35
+ end
36
+ end
37
+ ensure
38
+ @sock = nil
39
+ @q_msg.close
40
+ @q_ans.close
41
+ end
42
+ end
43
+ end
44
+
45
+
46
+ def setup_interrupt
47
+ prev_handler = trap(:SIGINT) do
48
+ # $stderr.puts "trapped SIGINT"
49
+ ThreadClient.current.on_trap
50
+
51
+ case prev_handler
52
+ when Proc
53
+ prev_handler.call
54
+ else
55
+ # ignore
56
+ end
57
+ end
58
+
59
+ yield
60
+ ensure
61
+ trap(:SIGINT, prev_handler)
62
+ end
63
+
64
+ def accept
65
+ raise "NOT IMPLEMENTED ERROR"
66
+ end
67
+
68
+ attr_reader :reader_thread
69
+
70
+ class NoRemoteError < Exception; end
71
+
72
+ def sock
73
+ yield @sock if @sock
74
+ rescue Errno::EPIPE
75
+ # ignore
76
+ end
77
+
78
+ def ask prompt
79
+ sock do |s|
80
+ s.puts "ask #{prompt}"
81
+ @q_ans.pop
82
+ end
83
+ end
84
+
85
+ def puts str
86
+ case str
87
+ when Array
88
+ enum = str.each
89
+ when String
90
+ enum = str.each_line
91
+ end
92
+
93
+ sock do |s|
94
+ enum.each do |line|
95
+ s.puts "out #{line.chomp}"
96
+ end
97
+ end
98
+ end
99
+
100
+ def readline
101
+ (sock do |s|
102
+ s.puts "input"
103
+ @q_msg.pop
104
+ end || 'continue').strip
105
+ end
106
+
107
+ def pause
108
+ $stderr.puts "DEBUG: pause request"
109
+ Process.kill(:SIGINT, Process.pid)
110
+ end
111
+
112
+ def quit n
113
+ # ignore n
114
+ sock do |s|
115
+ s.puts "quit"
116
+ end
117
+ end
118
+ end
119
+ end