ruined 0.0.1 → 0.0.2
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 +3 -0
- data/lib/ruined/html/main.html +13 -5
- data/lib/ruined/ruinmain.rb +271 -243
- metadata +3 -3
data/ChangeLog
CHANGED
data/lib/ruined/html/main.html
CHANGED
@@ -92,6 +92,13 @@ function stepProc(command) {
|
|
92
92
|
$('button').button('disable');
|
93
93
|
return;
|
94
94
|
}
|
95
|
+
if (data['break'] || data['event'] == 'exit') {
|
96
|
+
stopRun();
|
97
|
+
if (data['event'] == 'exit') {
|
98
|
+
$('button').button('disable');
|
99
|
+
alert('program exit');
|
100
|
+
}
|
101
|
+
}
|
95
102
|
if (files[data.file] == null) {
|
96
103
|
files[data.file] = addFile(data.file, data.line, command);
|
97
104
|
} else {
|
@@ -105,9 +112,6 @@ function stepProc(command) {
|
|
105
112
|
span = document.createElement('span');
|
106
113
|
$('#stdout')[0].appendChild(span);
|
107
114
|
span.scrollIntoView(true);
|
108
|
-
if (data['break']) {
|
109
|
-
stopRun();
|
110
|
-
}
|
111
115
|
});
|
112
116
|
}
|
113
117
|
function contProc(command) {
|
@@ -152,7 +156,11 @@ $(document).ready(function() {
|
|
152
156
|
if (contTimer != null) {
|
153
157
|
stopRun();
|
154
158
|
}
|
155
|
-
|
159
|
+
$('#vars').tabs({
|
160
|
+
show: function(envet, ui) {
|
161
|
+
alert('program terminated');
|
162
|
+
}
|
163
|
+
});
|
156
164
|
});
|
157
165
|
stepProc('stepping');
|
158
166
|
});
|
@@ -194,6 +202,6 @@ $(document).ready(function() {
|
|
194
202
|
<hr>
|
195
203
|
<div id="waiting"></div>
|
196
204
|
<address id="ruby-platform"></address>
|
197
|
-
<!-- hhmts start --> Last modified: Mon Oct 11
|
205
|
+
<!-- hhmts start --> Last modified: Mon Oct 11 17:22:50 +0900 2010 <!-- hhmts end -->
|
198
206
|
</div>
|
199
207
|
</body> </html>
|
data/lib/ruined/ruinmain.rb
CHANGED
@@ -1,243 +1,271 @@
|
|
1
|
-
#!/usr/local/bin/ruby -Ku
|
2
|
-
# coding: utf-8
|
3
|
-
|
4
|
-
require 'webrick'
|
5
|
-
require 'json'
|
6
|
-
require 'thread'
|
7
|
-
require 'monitor'
|
8
|
-
require 'stringio'
|
9
|
-
|
10
|
-
module Ruined
|
11
|
-
RUINED_VERSION = '0.0.
|
12
|
-
|
13
|
-
@queue = [Queue.new, Queue.new]
|
14
|
-
@breakpoints = []
|
15
|
-
@monitor = Monitor.new
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
def
|
61
|
-
end
|
62
|
-
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
{ :name => v.to_s, :value => instance_eval(v.to_s) }
|
147
|
-
end
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
def self.
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
1
|
+
#!/usr/local/bin/ruby -Ku
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'webrick'
|
5
|
+
require 'json'
|
6
|
+
require 'thread'
|
7
|
+
require 'monitor'
|
8
|
+
require 'stringio'
|
9
|
+
|
10
|
+
module Ruined
|
11
|
+
RUINED_VERSION = '0.0.2'
|
12
|
+
|
13
|
+
@queue = [Queue.new, Queue.new]
|
14
|
+
@breakpoints = []
|
15
|
+
@monitor = Monitor.new
|
16
|
+
@tlses = { '$!' => nil, '$?' => nil, '$@' => nil, '$SAFE' => nil}
|
17
|
+
IGNORES = [:$&, :$', :$+, :$_, :$`, :$~, :$KCODE, :$= ]
|
18
|
+
|
19
|
+
include WEBrick
|
20
|
+
svr = HTTPServer.new(:Port => 8383,
|
21
|
+
:ServerType => Thread,
|
22
|
+
:Logger => ($DEBUG) ? Log.new(nil, BasicLog::DEBUG) : Log.new,
|
23
|
+
:DocumentRoot => File.dirname(__FILE__))
|
24
|
+
trap('INT') do
|
25
|
+
svr.shutdown
|
26
|
+
end
|
27
|
+
|
28
|
+
class DebugServlet < HTTPServlet::AbstractServlet
|
29
|
+
include WEBrick::HTMLUtils
|
30
|
+
def service(req, res)
|
31
|
+
if req.addr[3] == '127.0.0.1'
|
32
|
+
super
|
33
|
+
else
|
34
|
+
bye(res)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
def do_GET(req, res)
|
38
|
+
m = %r|/debug/([^/]+)/?(.*)\Z|.match(req.path)
|
39
|
+
if m
|
40
|
+
res.body = __send__(m[1].to_sym, *(m[2].split('/')))
|
41
|
+
else
|
42
|
+
bye(res)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def break(*a)
|
47
|
+
if a.size < 3
|
48
|
+
bye(response)
|
49
|
+
else
|
50
|
+
point = [a[1..(a.size - 2)].join('/'), a[a.size - 1].to_i]
|
51
|
+
if a[0] == 'true'
|
52
|
+
Ruined.breakpoints << point
|
53
|
+
else
|
54
|
+
Ruined.breakpoints.delete point
|
55
|
+
end
|
56
|
+
JSON(point)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def run(*a)
|
61
|
+
end
|
62
|
+
|
63
|
+
def stop(*a)
|
64
|
+
end
|
65
|
+
|
66
|
+
def stepping(*a)
|
67
|
+
Ruined.wait 1
|
68
|
+
JSON(Ruined.current)
|
69
|
+
end
|
70
|
+
|
71
|
+
def cont(*a)
|
72
|
+
Ruined.release 0
|
73
|
+
Ruined.wait 1
|
74
|
+
JSON(Ruined.current)
|
75
|
+
end
|
76
|
+
|
77
|
+
def step(*a)
|
78
|
+
cont(a)
|
79
|
+
end
|
80
|
+
|
81
|
+
def file(*a)
|
82
|
+
r = '<table>'
|
83
|
+
File.open(a.join('/')).each_line do |line|
|
84
|
+
r << "<tr><td><pre>#{escape(line)}</pre></td></tr>"
|
85
|
+
end.close
|
86
|
+
r + '</table>'
|
87
|
+
end
|
88
|
+
|
89
|
+
def locals(*a)
|
90
|
+
s = '<table class="vars"><tr><th>Name</th><th>Value</th></tr>'
|
91
|
+
Ruined.local_vars.each do |e|
|
92
|
+
s << "<tr><td>#{escape(e[:name])}</td><td>#{escape(e[:value].inspect)}</td></tr>"
|
93
|
+
end
|
94
|
+
s + '</table>'
|
95
|
+
end
|
96
|
+
|
97
|
+
def globals(*a)
|
98
|
+
s = '<table class="vars"><tr><th>Name</th><th>Value</th></tr>'
|
99
|
+
Ruined.global_vars.each do |e|
|
100
|
+
s << "<tr><td>#{e[:name]}</td><td>#{escape(e[:value].inspect)}</td></tr>"
|
101
|
+
end
|
102
|
+
s + '</table>'
|
103
|
+
end
|
104
|
+
|
105
|
+
def self(*a)
|
106
|
+
s = '<table class="vars"><tr><th>Name</th><th>Value</th></tr>'
|
107
|
+
Ruined.self_vars.each do |e|
|
108
|
+
s << "<tr><td>#{e[:name]}</td><td>#{escape(e[:value].inspect)}</td></tr>"
|
109
|
+
end
|
110
|
+
s + '</table>'
|
111
|
+
end
|
112
|
+
|
113
|
+
def start(*a)
|
114
|
+
'<html>start</html>'
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def bye(res)
|
120
|
+
res.status = 404
|
121
|
+
res.body = '<html>bye</html>'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.current
|
126
|
+
@current
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.breakpoints
|
130
|
+
@breakpoints
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.local_vars
|
134
|
+
script = <<EOD
|
135
|
+
local_variables.map do |v|
|
136
|
+
(v == :_) ? nil : { :name => v.to_s, :value => eval(v.to_s) }
|
137
|
+
end - [nil]
|
138
|
+
EOD
|
139
|
+
@current_binding ? eval(script, @current_binding) : []
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.self_vars
|
143
|
+
script = <<EOD
|
144
|
+
[{ :name => 'class', :value => self.class.to_s }] +
|
145
|
+
instance_variables.map do |v|
|
146
|
+
{ :name => v.to_s, :value => instance_eval(v.to_s) }
|
147
|
+
end +
|
148
|
+
self.class.class_variables.map do |v|
|
149
|
+
{ :name => v.to_s, :value => instance_eval(v.to_s) }
|
150
|
+
end
|
151
|
+
EOD
|
152
|
+
@current_binding ? eval(script, @current_binding) : []
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.global_vars
|
156
|
+
script = <<EOD
|
157
|
+
(global_variables - Ruined::IGNORES).map do |v|
|
158
|
+
if v.to_s =~ /\\A\\$[1-9]/
|
159
|
+
nil
|
160
|
+
else
|
161
|
+
{ :name => v.to_s, :value => eval(v.to_s) }
|
162
|
+
end
|
163
|
+
end - [nil]
|
164
|
+
EOD
|
165
|
+
a = eval(script)
|
166
|
+
0.upto(a.size - 1) do |i|
|
167
|
+
if @tlses.has_key?(a[i][:name])
|
168
|
+
a[i][:value] = @tlses[a[i][:name]]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
a
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.tls_vars
|
175
|
+
@@tlses
|
176
|
+
end
|
177
|
+
|
178
|
+
def self.wait(t)
|
179
|
+
@monitor.synchronize {
|
180
|
+
unless @queue[t].empty?
|
181
|
+
@queue[t].clear
|
182
|
+
logger.debug("------------not wait exit #{t}")
|
183
|
+
return
|
184
|
+
end
|
185
|
+
}
|
186
|
+
logger.debug("------------wait #{t}")
|
187
|
+
@queue[t].pop
|
188
|
+
logger.debug("------------wait exit #{t}")
|
189
|
+
end
|
190
|
+
|
191
|
+
def self.release(t)
|
192
|
+
logger.debug("------------release #{t}")
|
193
|
+
@monitor.synchronize {
|
194
|
+
@queue[t].push nil
|
195
|
+
}
|
196
|
+
logger.debug("------------release exit #{t}")
|
197
|
+
end
|
198
|
+
|
199
|
+
def self.output
|
200
|
+
return '' unless StringIO === $stdout
|
201
|
+
out = $stdout
|
202
|
+
$stdout = StringIO.new
|
203
|
+
out.pos = 0
|
204
|
+
ret = ''
|
205
|
+
out.each_line do |x|
|
206
|
+
ret << "#{x.chomp}<br/>"
|
207
|
+
end
|
208
|
+
ret
|
209
|
+
end
|
210
|
+
|
211
|
+
svr.mount('/debug', DebugServlet)
|
212
|
+
svr.mount_proc('/quit') do |req, res|
|
213
|
+
if req.addr[3] == '127.0.0.1'
|
214
|
+
set_trace_func(nil)
|
215
|
+
c = 0
|
216
|
+
if req.path =~ %r|/(\d+)|
|
217
|
+
c = $1.to_i
|
218
|
+
end
|
219
|
+
res.body = '<html>bye</html>'
|
220
|
+
Thread.start do
|
221
|
+
@monitor.synchronize {
|
222
|
+
@queue = nil
|
223
|
+
}
|
224
|
+
Thread.pass
|
225
|
+
svr.shutdown
|
226
|
+
exit(c)
|
227
|
+
end
|
228
|
+
else
|
229
|
+
res.status = 404
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
define_method(:logger) do
|
234
|
+
return svr.logger
|
235
|
+
end
|
236
|
+
module_function(:logger)
|
237
|
+
|
238
|
+
svr.start
|
239
|
+
|
240
|
+
main_thread = Thread.current
|
241
|
+
|
242
|
+
set_trace_func Proc.new {|event, file, line, id, binding, klass|
|
243
|
+
unless file =~ %r#(lib/ruby|webrick|internal)# || main_thread != Thread.current
|
244
|
+
if event.index('c-') != 0
|
245
|
+
if file == $0 && !$stdout.instance_of?(StringIO)
|
246
|
+
$stdout = StringIO.new
|
247
|
+
end
|
248
|
+
@tlses.each do |k, v|
|
249
|
+
@tlses[k] = eval(k)
|
250
|
+
end
|
251
|
+
b = breakpoints.include? [file, line]
|
252
|
+
@current_binding = binding
|
253
|
+
@current = { 'event' => event, 'file' => file, 'line' => line,
|
254
|
+
'id' => id.to_s, 'break' => b, 'stdout' => output }
|
255
|
+
svr.logger.debug(@current.inspect)
|
256
|
+
release 1
|
257
|
+
wait 0
|
258
|
+
svr.logger.debug('continue...')
|
259
|
+
end
|
260
|
+
end
|
261
|
+
}
|
262
|
+
at_exit {
|
263
|
+
if @current
|
264
|
+
@current['event'] = 'exit'
|
265
|
+
@current['stdout'] = output
|
266
|
+
release 1
|
267
|
+
wait 0
|
268
|
+
end
|
269
|
+
}
|
270
|
+
end
|
271
|
+
|
metadata
CHANGED