ruined 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 +11 -0
- data/lib/ruined/css/ruin.css +4 -3
- data/lib/ruined/html/main.html +108 -20
- data/lib/ruined/ruinmain.rb +53 -11
- data/lib/uined.rb +1 -1
- metadata +4 -4
data/ChangeLog
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
Tue Nov 9 2:42:30 2010 arton
|
2
|
+
* ruined/ruinmain.rb
|
3
|
+
write file with binary mode for voiding bad conversion (\r\n -> \r\r\n)
|
4
|
+
* uined.rb
|
5
|
+
return waitcline.html if restart
|
6
|
+
* ruined/html/main.html
|
7
|
+
implements edit command
|
8
|
+
Mon Oct 25 22:41:20 2010 arton
|
9
|
+
* ruined/ruinmain.rb
|
10
|
+
version 0.0.9 => 0.1.0
|
11
|
+
convert file, variable's value and output into utf-8
|
1
12
|
Sun Oct 17 19:24:00 2010 arton
|
2
13
|
* ruined/ruinmain.rb
|
3
14
|
version 0.0.8 => 0.0.9
|
data/lib/ruined/css/ruin.css
CHANGED
@@ -38,13 +38,13 @@ div.vars-pane {
|
|
38
38
|
|
39
39
|
div#button-panel {
|
40
40
|
float: left;
|
41
|
-
width:
|
41
|
+
width: 65%;
|
42
42
|
height: 40px
|
43
43
|
}
|
44
44
|
|
45
45
|
div#speed-panel {
|
46
46
|
float: left;
|
47
|
-
width:
|
47
|
+
width: 30%;
|
48
48
|
height: 40px
|
49
49
|
}
|
50
50
|
|
@@ -72,7 +72,8 @@ div#output {
|
|
72
72
|
|
73
73
|
div#threads {
|
74
74
|
overflow: scroll;
|
75
|
-
height:
|
75
|
+
height: 100px;
|
76
|
+
padding: 10px;
|
76
77
|
}
|
77
78
|
|
78
79
|
div.footer {
|
data/lib/ruined/html/main.html
CHANGED
@@ -12,24 +12,25 @@ var files = new Object();
|
|
12
12
|
var priorLine = { line: null, index: null };
|
13
13
|
var interval = 1000;
|
14
14
|
var contTimer = null;
|
15
|
+
var editing = null;
|
15
16
|
function addFile(name, line, command) {
|
16
17
|
var a = name.split('/');
|
17
18
|
$('#lists').tabs('add' , '/debug/file/' + name , a[a.length - 1]);
|
18
19
|
var index = $('#lists').tabs('length') - 1;
|
19
20
|
$('#lists').tabs('select', index);
|
20
21
|
$('td').bind('click', function(ev) {
|
22
|
+
var bgclr = '';
|
21
23
|
var sub = 'false';
|
22
24
|
if (ev.currentTarget.style.backgroundColor == '') {
|
23
25
|
sub = 'true';
|
26
|
+
bgclr = 'saddlebrown';
|
27
|
+
} else if (ev.currentTarget.style.backgroundColor == 'yellow') {
|
28
|
+
sub = 'true';
|
29
|
+
bgclr = 'olive';
|
30
|
+
} else if (ev.currentTarget.style.backgroundColor == 'olive') {
|
31
|
+
bgclr = 'yellow';
|
24
32
|
}
|
25
|
-
var
|
26
|
-
var key, file;
|
27
|
-
for (key in files) {
|
28
|
-
if (files[key] == index) {
|
29
|
-
file = key;
|
30
|
-
break;
|
31
|
-
}
|
32
|
-
}
|
33
|
+
var file = selectFile();
|
33
34
|
if (file != null) {
|
34
35
|
var line = 0;
|
35
36
|
var list = $('#ui-tabs-' + (index * 2 + 2) + ' > table > tbody > tr > td');
|
@@ -40,10 +41,8 @@ function addFile(name, line, command) {
|
|
40
41
|
}
|
41
42
|
}
|
42
43
|
$.get('/debug/break/' + sub + '/' + file + '/' + line, function() {
|
43
|
-
var bgclr = '';
|
44
44
|
var clr = '';
|
45
45
|
if (sub == 'true') {
|
46
|
-
bgclr = 'saddlebrown';
|
47
46
|
clr = 'white';
|
48
47
|
}
|
49
48
|
ev.currentTarget.style.backgroundColor = bgclr;
|
@@ -53,11 +52,24 @@ function addFile(name, line, command) {
|
|
53
52
|
});
|
54
53
|
return index;
|
55
54
|
}
|
55
|
+
function selectFile() {
|
56
|
+
var index = $('#lists').tabs('option', 'selected');
|
57
|
+
var key, file;
|
58
|
+
for (key in files) {
|
59
|
+
if (files[key] == index) {
|
60
|
+
file = key;
|
61
|
+
break;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
return file;
|
65
|
+
}
|
56
66
|
function changeTab(index) {
|
57
67
|
$('#lists').tabs('select', index);
|
58
68
|
}
|
59
69
|
function lineColor(command, brk) {
|
60
|
-
if (
|
70
|
+
if (brk) {
|
71
|
+
return 'olive';
|
72
|
+
} else if (command == 'cont') {
|
61
73
|
return 'aquamarine';
|
62
74
|
}
|
63
75
|
return 'yellow';
|
@@ -66,6 +78,7 @@ function stopRun() {
|
|
66
78
|
clearTimeout(contTimer);
|
67
79
|
contTimer = null;
|
68
80
|
$('#run').button('option', 'label', 'run');
|
81
|
+
$('#edit').button('option', 'disabled', false);
|
69
82
|
}
|
70
83
|
function setLine(index, line, command, brk) {
|
71
84
|
if (line > 0) {
|
@@ -85,7 +98,24 @@ function setLine(index, line, command, brk) {
|
|
85
98
|
style.color = '';
|
86
99
|
$('#ui-tabs-' + (index * 2 + 2) + ' > table > tbody > tr > td')[line].scrollIntoView(true);
|
87
100
|
}
|
101
|
+
function runProc(command) {
|
102
|
+
if (isEditMode()) {
|
103
|
+
saveProc(command, false);
|
104
|
+
} else {
|
105
|
+
if (contTimer == null) {
|
106
|
+
contProc('cont');
|
107
|
+
$('#run').button('option', 'label', 'stop');
|
108
|
+
$('#edit').button('option', 'disabled', true);
|
109
|
+
} else {
|
110
|
+
stopRun();
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
88
114
|
function stepProc(command) {
|
115
|
+
if (isEditMode()) {
|
116
|
+
saveProc(command, true);
|
117
|
+
return;
|
118
|
+
}
|
89
119
|
$.getJSON('/debug/' + command, function(data) {
|
90
120
|
if (data == null || data.file == null) {
|
91
121
|
if (contTimer != null) stopRun();
|
@@ -132,6 +162,65 @@ function contProc(command) {
|
|
132
162
|
stepProc(command);
|
133
163
|
contTimer = setTimeout('contProc("' + command + '");', interval);
|
134
164
|
}
|
165
|
+
function editProc(command) {
|
166
|
+
var emode = isEditMode();
|
167
|
+
if (emode) {
|
168
|
+
var root = $('#ui-tabs-' + (editing * 2 + 2))[0];
|
169
|
+
if (root.codeTable) {
|
170
|
+
root.replaceChild(root.codeTable, root.childNodes(0));
|
171
|
+
}
|
172
|
+
} else {
|
173
|
+
editing = $('#lists').tabs('option', 'selected');
|
174
|
+
var root = $('#ui-tabs-' + (editing * 2 + 2))[0];
|
175
|
+
$.get('/debug/file/' + selectFile(), function(data) {
|
176
|
+
root.codeTable = root.childNodes(0);
|
177
|
+
var txa = document.createElement('textarea');
|
178
|
+
txa.style.fontSize = '11pt';
|
179
|
+
txa.rows = 22;
|
180
|
+
txa.cols = 68;
|
181
|
+
txa.innerHTML = data;
|
182
|
+
root.replaceChild(txa, root.codeTable);
|
183
|
+
root.originalCode = data;
|
184
|
+
}, 'text');
|
185
|
+
}
|
186
|
+
editMode(emode);
|
187
|
+
}
|
188
|
+
function saveProc(command, rst) {
|
189
|
+
var root = $('#ui-tabs-' + (editing * 2 + 2))[0];
|
190
|
+
var newText = root.childNodes(0).innerHTML;
|
191
|
+
var anew = newText.split(/\r?\n/)
|
192
|
+
var aorg = root.originalCode.split(/\r?\n/)
|
193
|
+
if (anew.length == aorg.length && isSameArray(anew, aorg)) {
|
194
|
+
alert('no save is needed');
|
195
|
+
} else {
|
196
|
+
$.post('/debug/file/' + selectFile(), newText, function(data) {
|
197
|
+
if (rst) {
|
198
|
+
document.location.href = 'http://localhost.:8384/restart';
|
199
|
+
}
|
200
|
+
}, 'text');
|
201
|
+
}
|
202
|
+
editMode(isEditMode());
|
203
|
+
if (root.codeTable) {
|
204
|
+
root.replaceChild(root.codeTable, root.childNodes(0));
|
205
|
+
}
|
206
|
+
}
|
207
|
+
function isSameArray(a0, a1) {
|
208
|
+
// assert a0.length == a1.length
|
209
|
+
for (var i = 0; i < a0.length; i++) {
|
210
|
+
if (a0[i] != a1[i]) return false;
|
211
|
+
}
|
212
|
+
return true;
|
213
|
+
}
|
214
|
+
function isEditMode() {
|
215
|
+
return $('#edit').button('option', 'label') == 'Disc';
|
216
|
+
}
|
217
|
+
function editMode(b) {
|
218
|
+
var btn = new Array('#step', '#run', '#edit');
|
219
|
+
var label = (b) ? new Array('Step', 'Run', 'Edit') : new Array('Save Rst', 'Save Cont', 'Disc');
|
220
|
+
for (var i = 0; i < 3; i++) {
|
221
|
+
$(btn[i]).button('option', 'label', label[i]);
|
222
|
+
}
|
223
|
+
}
|
135
224
|
function initTabs(elm) {
|
136
225
|
elm.tabs();
|
137
226
|
elm.tabs({ajaxOptions: {async: false}});
|
@@ -179,17 +268,15 @@ $(document).ready(function() {
|
|
179
268
|
$.ajaxSetup({cache: false});
|
180
269
|
|
181
270
|
$('button').button();
|
182
|
-
$('#run').click(function() {
|
183
|
-
if (contTimer == null) {
|
184
|
-
contProc('cont');
|
185
|
-
$('#run').button('option', 'label', 'stop');
|
186
|
-
} else {
|
187
|
-
stopRun();
|
188
|
-
}
|
189
|
-
});
|
190
271
|
$('#step').click(function() {
|
191
272
|
stepProc('step');
|
192
273
|
});
|
274
|
+
$('#run').click(function() {
|
275
|
+
runProc('run');
|
276
|
+
});
|
277
|
+
$('#edit').click(function() {
|
278
|
+
editProc('edit');
|
279
|
+
});
|
193
280
|
$('#waiting').ajaxError(function() {
|
194
281
|
if (contTimer != null) {
|
195
282
|
stopRun();
|
@@ -205,6 +292,7 @@ $(document).ready(function() {
|
|
205
292
|
<div class="console">
|
206
293
|
<button id="step">Step</button>
|
207
294
|
<button id="run">Run</button>
|
295
|
+
<button id="edit">Edit</button>
|
208
296
|
</div>
|
209
297
|
</div>
|
210
298
|
<div id="speed-panel">
|
@@ -239,6 +327,6 @@ $(document).ready(function() {
|
|
239
327
|
<hr>
|
240
328
|
<div id="waiting"></div>
|
241
329
|
<address id="ruby-platform"></address>
|
242
|
-
<!-- hhmts start --> Last modified:
|
330
|
+
<!-- hhmts start --> Last modified: Tue Nov 09 02:37:01 +0900 2010 <!-- hhmts end -->
|
243
331
|
</div>
|
244
332
|
</body> </html>
|
data/lib/ruined/ruinmain.rb
CHANGED
@@ -7,9 +7,10 @@ require 'json'
|
|
7
7
|
require 'thread'
|
8
8
|
require 'monitor'
|
9
9
|
require 'stringio'
|
10
|
+
require 'fileutils'
|
10
11
|
|
11
12
|
module Ruined
|
12
|
-
RUINED_VERSION = '0.0
|
13
|
+
RUINED_VERSION = '0.1.0'
|
13
14
|
|
14
15
|
@queue = [Queue.new, Queue.new]
|
15
16
|
@breakpoints = []
|
@@ -68,7 +69,11 @@ module Ruined
|
|
68
69
|
include WEBrick::HTMLUtils
|
69
70
|
def service(req, res)
|
70
71
|
if Ruined.local_call?(req.addr)
|
72
|
+
@response = res
|
73
|
+
@request = req
|
71
74
|
super
|
75
|
+
@response = nil
|
76
|
+
@request = nil
|
72
77
|
else
|
73
78
|
bye(res)
|
74
79
|
end
|
@@ -76,15 +81,21 @@ module Ruined
|
|
76
81
|
def do_GET(req, res)
|
77
82
|
m = %r|/debug/([^/?]+)/?([^?]*).*\Z|.match(req.unparsed_uri)
|
78
83
|
if m
|
79
|
-
@response = res
|
80
84
|
res.body = __send__(m[1].to_sym, *(m[2].split('/').map{|x|URI.decode(x)}))
|
81
85
|
else
|
82
86
|
bye(res)
|
83
87
|
end
|
84
|
-
|
88
|
+
end
|
89
|
+
def do_POST(req, res)
|
90
|
+
m = %r|/debug/([^/?]+)/?([^?]*).*\Z|.match(req.unparsed_uri)
|
91
|
+
if m && m[1] == 'file'
|
92
|
+
res.body = __send__(m[1].to_sym, *(m[2].split('/').map{|x|URI.decode(x)}))
|
93
|
+
else
|
94
|
+
bye(res)
|
95
|
+
end
|
85
96
|
end
|
86
97
|
|
87
|
-
attr_reader :response
|
98
|
+
attr_reader :response, :request
|
88
99
|
|
89
100
|
def break(*a)
|
90
101
|
if a.size < 3
|
@@ -122,11 +133,29 @@ module Ruined
|
|
122
133
|
end
|
123
134
|
|
124
135
|
def file(*a)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
136
|
+
file = a.join('/')
|
137
|
+
if request.request_method == 'GET'
|
138
|
+
request.accept.each do |accept|
|
139
|
+
if accept =~ /html/i
|
140
|
+
break
|
141
|
+
elsif accept =~ %r|text/plain|i
|
142
|
+
File.open(file) do |f|
|
143
|
+
return Ruined::to_utf8(f.read)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
to_html(file)
|
148
|
+
else
|
149
|
+
# TODO: newline and charset justify
|
150
|
+
# wb is workaround for inhibit to put addition \r
|
151
|
+
File.open("#{file}.new", 'wb') do |f|
|
152
|
+
f.write(request.body)
|
153
|
+
end
|
154
|
+
FileUtils.cp file, "#{file}.bak", :verbose => true
|
155
|
+
FileUtils.cp "#{file}.new", file, :verbose => true
|
156
|
+
FileUtils.rm "#{file}.new"
|
157
|
+
"save #{file}"
|
158
|
+
end
|
130
159
|
end
|
131
160
|
|
132
161
|
def locals(*a)
|
@@ -164,7 +193,8 @@ module Ruined
|
|
164
193
|
def create_varlist(t)
|
165
194
|
s = '<table class="vars"><tr><th>Name</th><th>Value</th></tr>'
|
166
195
|
t.each do |e|
|
167
|
-
|
196
|
+
v = Ruined.to_utf8(e[:value].inspect)
|
197
|
+
s << "<tr><td>#{e[:name]}</td><td class=\"var-value\">#{escape(v)}</td></tr>"
|
168
198
|
end
|
169
199
|
s + '</table>'
|
170
200
|
end
|
@@ -177,6 +207,14 @@ module Ruined
|
|
177
207
|
end
|
178
208
|
end
|
179
209
|
|
210
|
+
def to_html(file)
|
211
|
+
r = '<table>'
|
212
|
+
File.open(file).each_line do |line|
|
213
|
+
r << "<tr><td><pre>#{escape(Ruined::to_utf8(line))}</pre></td></tr>"
|
214
|
+
end.close
|
215
|
+
r + '</table>'
|
216
|
+
end
|
217
|
+
|
180
218
|
def bye(res)
|
181
219
|
res.status = 404
|
182
220
|
res.body = '<html>bye</html>'
|
@@ -265,11 +303,15 @@ EOD
|
|
265
303
|
out.pos = 0
|
266
304
|
ret = ''
|
267
305
|
out.each_line do |x|
|
268
|
-
ret << "#{HTMLUtils.escape(x.chomp)}<br/>"
|
306
|
+
ret << "#{HTMLUtils.escape(to_utf8(x.chomp))}<br/>"
|
269
307
|
end
|
270
308
|
ret
|
271
309
|
end
|
272
310
|
|
311
|
+
def self.to_utf8(s)
|
312
|
+
(s.encoding != Encoding::UTF_8) ? s.encode(Encoding::UTF_8) : s
|
313
|
+
end
|
314
|
+
|
273
315
|
def self.add_unbreakable(t)
|
274
316
|
@monitor.synchronize {
|
275
317
|
@unbreakable_threads << t
|
data/lib/uined.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruined
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.9
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- arton
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-11-09 00:00:00 +09:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|