ruby-debug 0.1.5 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -0
- data/Rakefile +25 -2
- data/bin/rdebug +79 -8
- data/bin/remote +30 -0
- data/ext/ruby_debug.c +65 -54
- data/lib/ruby-debug/interface.rb +69 -0
- data/lib/ruby-debug/processor.rb +627 -0
- data/lib/ruby-debug.rb +36 -561
- metadata +7 -2
data/CHANGES
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.2 (2006-06-17)
|
2
|
+
- Added the remote debugging. It should be activated by calling Debugger#start_server method.
|
3
|
+
- CHANGED: In order to activate the debugger, it's not enough to require 'ruby-debug'.
|
4
|
+
Debugger#start method must be called explicitly.
|
5
|
+
- Debugger used to evaluate anything you enter as long as it's not a command. Starting from
|
6
|
+
this version the 'eval' command must be used to evaluate an expression.
|
7
|
+
|
1
8
|
0.1.5 (2006-06-13)
|
2
9
|
- Now the check for a breakpoint uses base filename of the source file.
|
3
10
|
- Removed compilation warnings when compiling with -Wall
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ require 'rake/rdoctask'
|
|
5
5
|
SO_NAME = "ruby_debug.so"
|
6
6
|
|
7
7
|
# ------- Default Package ----------
|
8
|
-
RUBY_DEBUG_VERSION = "0.
|
8
|
+
RUBY_DEBUG_VERSION = "0.2"
|
9
9
|
|
10
10
|
FILES = FileList[
|
11
11
|
'Rakefile',
|
@@ -48,7 +48,6 @@ EOF
|
|
48
48
|
spec.has_rdoc = false
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
51
|
# Rake task to build the default package
|
53
52
|
Rake::GemPackageTask.new(default_spec) do |pkg|
|
54
53
|
pkg.need_tar = true
|
@@ -57,6 +56,30 @@ end
|
|
57
56
|
|
58
57
|
task :default => [:package]
|
59
58
|
|
59
|
+
# Windows specification
|
60
|
+
win_spec = default_spec.clone
|
61
|
+
win_spec.extensions = []
|
62
|
+
win_spec.platform = Gem::Platform::WIN32
|
63
|
+
win_spec.files += ["lib/#{SO_NAME}"]
|
64
|
+
|
65
|
+
desc "Create Windows Gem"
|
66
|
+
task :win32_gem do
|
67
|
+
# Copy the win32 extension the top level directory
|
68
|
+
current_dir = File.expand_path(File.dirname(__FILE__))
|
69
|
+
source = File.join(current_dir, "ext", "win32", SO_NAME)
|
70
|
+
target = File.join(current_dir, "lib", SO_NAME)
|
71
|
+
cp(source, target)
|
72
|
+
|
73
|
+
# Create the gem, then move it to pkg
|
74
|
+
Gem::Builder.new(win_spec).build
|
75
|
+
gem_file = "#{win_spec.name}-#{win_spec.version}-#{win_spec.platform}.gem"
|
76
|
+
mv(gem_file, "pkg/#{gem_file}")
|
77
|
+
|
78
|
+
# Remove win extension fro top level directory
|
79
|
+
rm(target)
|
80
|
+
end
|
81
|
+
|
82
|
+
|
60
83
|
desc "Publish ruby-debug to RubyForge."
|
61
84
|
task :publish do
|
62
85
|
require 'rake/contrib/sshpublisher'
|
data/bin/rdebug
CHANGED
@@ -1,13 +1,84 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
if ARGV.empty?
|
4
|
-
puts "Usage: #{__FILE__} <script>"
|
5
|
-
exit(1)
|
6
|
-
end
|
7
|
-
|
8
3
|
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require "ostruct"
|
9
6
|
require 'ruby-debug'
|
10
|
-
trap('INT') { Debugger.interrupt_last }
|
11
7
|
|
12
|
-
|
13
|
-
|
8
|
+
options = OpenStruct.new(
|
9
|
+
'server' => false,
|
10
|
+
'client' => false,
|
11
|
+
'host' => nil,
|
12
|
+
'port' => Debugger::PORT
|
13
|
+
)
|
14
|
+
|
15
|
+
opts = OptionParser.new do |opts|
|
16
|
+
opts.banner = <<EOB
|
17
|
+
ruby-debug #{Debugger::VERSION}
|
18
|
+
Usage: rdebug [options] <script.rb> <script.rb parameters>
|
19
|
+
EOB
|
20
|
+
opts.separator ""
|
21
|
+
opts.separator "Options:"
|
22
|
+
opts.on("-s", "--server", "Listen for remote connections") {options.server = true}
|
23
|
+
opts.on("-c", "--client", "Connect to remote debugger") {options.client = true}
|
24
|
+
opts.on("-h", "--host HOST", "Host name used for remote debugging") {|options.host|}
|
25
|
+
opts.on("-p", "--port PORT", Integer, "Port used for remote debugging") {|options.port|}
|
26
|
+
opts.separator ""
|
27
|
+
opts.separator "Common options:"
|
28
|
+
opts.on_tail("--help", "Show this message") do
|
29
|
+
puts opts
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
opts.on_tail("-v", "--version", "Show version") do
|
33
|
+
puts "ruby-debug #{Debugger::VERSION}"
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
opts.parse! ARGV
|
40
|
+
rescue StandardError => e
|
41
|
+
puts opts
|
42
|
+
puts
|
43
|
+
puts e.message
|
44
|
+
exit(-1)
|
45
|
+
end
|
46
|
+
|
47
|
+
if options.client
|
48
|
+
require "socket"
|
49
|
+
interface = Debugger::LocalInterface.new
|
50
|
+
socket = TCPSocket.new(options.host, options.port)
|
51
|
+
puts "Connected."
|
52
|
+
|
53
|
+
catch(:exit) do
|
54
|
+
while (line = socket.gets)
|
55
|
+
case line
|
56
|
+
when /^PROMPT (.*)$/
|
57
|
+
input = interface.read_command($1)
|
58
|
+
throw :exit unless input
|
59
|
+
socket.puts input
|
60
|
+
when /^CONFIRM (.*)$/
|
61
|
+
input = interface.confirm($1)
|
62
|
+
throw :exit unless input
|
63
|
+
socket.puts input
|
64
|
+
else
|
65
|
+
print line
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
socket.close
|
70
|
+
puts
|
71
|
+
else
|
72
|
+
if ARGV.empty?
|
73
|
+
puts opts
|
74
|
+
puts
|
75
|
+
puts "Must specify a script to run"
|
76
|
+
exit(-1)
|
77
|
+
end
|
78
|
+
|
79
|
+
trap('INT') { Debugger.interrupt_last }
|
80
|
+
Debugger.start_server(options.host, options.port) if options.server
|
81
|
+
Debugger.start
|
82
|
+
debugger 2
|
83
|
+
load ARGV.shift
|
84
|
+
end
|
data/bin/remote
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
require "ruby-debug/inputs"
|
5
|
+
|
6
|
+
host = ARGV[0] || "localhost"
|
7
|
+
port = 8989
|
8
|
+
|
9
|
+
input = Debugger::LocalInput.new
|
10
|
+
socket = TCPSocket.new(host, port)
|
11
|
+
puts "Connected."
|
12
|
+
|
13
|
+
catch(:exit) do
|
14
|
+
while (line = socket.gets)
|
15
|
+
case line
|
16
|
+
when /^PROMPT (.*)$/
|
17
|
+
data = input.read_command($1)
|
18
|
+
throw :exit unless data
|
19
|
+
socket.puts data
|
20
|
+
when /^CONFIRM (.*)$/
|
21
|
+
data = input.confirm($1)
|
22
|
+
throw :exit unless data
|
23
|
+
socket.puts data
|
24
|
+
else
|
25
|
+
print line
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
socket.close
|
30
|
+
puts
|
data/ext/ruby_debug.c
CHANGED
@@ -4,13 +4,15 @@
|
|
4
4
|
#include <rubysig.h>
|
5
5
|
#include <st.h>
|
6
6
|
|
7
|
-
#define DEBUG_VERSION "0.
|
7
|
+
#define DEBUG_VERSION "0.2"
|
8
8
|
|
9
9
|
typedef struct {
|
10
10
|
int thnum;
|
11
|
+
VALUE last_file;
|
12
|
+
VALUE last_line;
|
13
|
+
int moved;
|
11
14
|
int stop_next;
|
12
15
|
int dest_frame;
|
13
|
-
int src_line;
|
14
16
|
int stop_line;
|
15
17
|
int stop_frame;
|
16
18
|
int suspend;
|
@@ -43,7 +45,7 @@ static VALUE cContext;
|
|
43
45
|
static VALUE cFrame;
|
44
46
|
static VALUE cBreakpoint;
|
45
47
|
|
46
|
-
static ID
|
48
|
+
static ID idAtLine;
|
47
49
|
static ID idAtBreakpoint;
|
48
50
|
static ID idAtCatchpoint;
|
49
51
|
static ID idAtTracing;
|
@@ -81,6 +83,8 @@ debug_context_mark(void* data)
|
|
81
83
|
debug_context_t *debug_context = (debug_context_t *)data;
|
82
84
|
rb_gc_mark(debug_context->frames);
|
83
85
|
rb_gc_mark(debug_context->thread);
|
86
|
+
rb_gc_mark(debug_context->last_file);
|
87
|
+
rb_gc_mark(debug_context->last_line);
|
84
88
|
}
|
85
89
|
|
86
90
|
static VALUE
|
@@ -91,9 +95,13 @@ debug_context_create(VALUE thread)
|
|
91
95
|
|
92
96
|
debug_context = ALLOC(debug_context_t);
|
93
97
|
debug_context-> thnum = ++thnum_max;
|
98
|
+
|
99
|
+
debug_context->last_file = Qnil;
|
100
|
+
debug_context->last_line = Qnil;
|
101
|
+
debug_context->moved = 0;
|
102
|
+
|
94
103
|
debug_context->stop_next = -1;
|
95
104
|
debug_context->dest_frame = -1;
|
96
|
-
debug_context->src_line = -1;
|
97
105
|
debug_context->stop_line = -1;
|
98
106
|
debug_context->stop_frame = -1;
|
99
107
|
debug_context->suspend = 0;
|
@@ -145,16 +153,36 @@ debug_frame_create(VALUE file, VALUE line, VALUE binding, ID id)
|
|
145
153
|
return result;
|
146
154
|
}
|
147
155
|
|
148
|
-
static
|
149
|
-
|
156
|
+
static void
|
157
|
+
save_current_position(VALUE context)
|
150
158
|
{
|
151
|
-
VALUE
|
159
|
+
VALUE cur_frame;
|
160
|
+
debug_context_t *debug_context;
|
161
|
+
debug_frame_t *debug_frame;
|
162
|
+
|
163
|
+
Data_Get_Struct(context, debug_context_t, debug_context);
|
164
|
+
if(RARRAY(debug_context->frames)->len == 0)
|
165
|
+
return;
|
166
|
+
|
167
|
+
cur_frame = *RARRAY(debug_context->frames)->ptr;
|
168
|
+
Data_Get_Struct(cur_frame, debug_frame_t, debug_frame);
|
169
|
+
|
170
|
+
debug_context->last_file = debug_frame->file;
|
171
|
+
debug_context->last_line = debug_frame->line;
|
172
|
+
debug_context->moved = 0;
|
173
|
+
}
|
152
174
|
|
153
|
-
|
175
|
+
#define did_moved() (debug_context->last_line != line || \
|
176
|
+
debug_context->last_file == Qnil || \
|
177
|
+
rb_str_cmp(debug_context->last_file, file) != 0)
|
154
178
|
|
179
|
+
static VALUE
|
180
|
+
call_at_line(VALUE context, int thnum, VALUE binding, VALUE file, VALUE line)
|
181
|
+
{
|
155
182
|
last_debugged_thnum = thnum;
|
183
|
+
save_current_position(context);
|
156
184
|
debug_suspend(mDebugger);
|
157
|
-
return rb_funcall(context,
|
185
|
+
return rb_funcall(context, idAtLine, 3, file, line, binding);
|
158
186
|
}
|
159
187
|
|
160
188
|
static void
|
@@ -189,7 +217,7 @@ basename(VALUE filename)
|
|
189
217
|
}
|
190
218
|
|
191
219
|
static int
|
192
|
-
check_breakpoints(
|
220
|
+
check_breakpoints(debug_context_t *debug_context, VALUE file, VALUE klass, VALUE pos)
|
193
221
|
{
|
194
222
|
VALUE breakpoint;
|
195
223
|
debug_breakpoint_t *debug_breakpoint;
|
@@ -197,6 +225,9 @@ check_breakpoints(VALUE context, VALUE file, VALUE klass, VALUE pos)
|
|
197
225
|
|
198
226
|
if(RARRAY(breakpoints)->len == 0)
|
199
227
|
return -1;
|
228
|
+
if(!debug_context->moved)
|
229
|
+
return -1;
|
230
|
+
|
200
231
|
for(i = 0; i < RARRAY(breakpoints)->len; i++)
|
201
232
|
{
|
202
233
|
breakpoint = rb_ary_entry(breakpoints, i);
|
@@ -282,10 +313,12 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
282
313
|
debug_context_t *debug_context;
|
283
314
|
VALUE file = Qnil, line = Qnil;
|
284
315
|
int breakpoint_index = -1;
|
285
|
-
|
316
|
+
|
286
317
|
static int debugging = 0;
|
287
318
|
|
319
|
+
if (mid == ID_ALLOCATOR) return;
|
288
320
|
if(debugging) return;
|
321
|
+
if(!node) return;
|
289
322
|
|
290
323
|
debugging++;
|
291
324
|
|
@@ -294,11 +327,11 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
294
327
|
Data_Get_Struct(context, debug_context_t, debug_context);
|
295
328
|
check_suspend(debug_context);
|
296
329
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
330
|
+
file = rb_str_new2(node->nd_file);
|
331
|
+
line = INT2FIX(nd_line(node));
|
332
|
+
|
333
|
+
if(did_moved())
|
334
|
+
debug_context->moved = 1;
|
302
335
|
|
303
336
|
switch(event)
|
304
337
|
{
|
@@ -310,15 +343,15 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
310
343
|
{
|
311
344
|
rb_funcall(context, idAtTracing, 2, file, line);
|
312
345
|
}
|
313
|
-
|
346
|
+
|
314
347
|
if(debug_context->dest_frame == -1 ||
|
315
348
|
RARRAY(debug_context->frames)->len == debug_context->dest_frame)
|
316
349
|
{
|
317
350
|
debug_context->stop_next--;
|
318
351
|
if(debug_context->stop_next < 0)
|
319
|
-
|
352
|
+
debug_context->stop_next = -1;
|
320
353
|
/* we check that we actualy moved to another line */
|
321
|
-
if(
|
354
|
+
if(did_moved())
|
322
355
|
{
|
323
356
|
debug_context->stop_line--;
|
324
357
|
}
|
@@ -334,7 +367,7 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
334
367
|
}
|
335
368
|
|
336
369
|
if(debug_context->stop_next == 0 || debug_context->stop_line == 0 ||
|
337
|
-
(breakpoint_index = check_breakpoints(
|
370
|
+
(breakpoint_index = check_breakpoints(debug_context, file, klass, line)) != -1)
|
338
371
|
{
|
339
372
|
binding = self? create_binding(self) : Qnil;
|
340
373
|
/* check breakpoint expression */
|
@@ -342,41 +375,37 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
342
375
|
{
|
343
376
|
breakpoint = get_breakpoint_at(breakpoint_index);
|
344
377
|
if(check_breakpoint_expression(breakpoint, binding))
|
345
|
-
rb_funcall(context, idAtBreakpoint,
|
378
|
+
rb_funcall(context, idAtBreakpoint, 1, breakpoint);
|
346
379
|
else
|
347
380
|
break;
|
348
381
|
}
|
349
382
|
|
350
383
|
/* reset all pointers */
|
351
384
|
debug_context->dest_frame = -1;
|
352
|
-
debug_context->src_line = -1;
|
353
385
|
debug_context->stop_line = -1;
|
354
386
|
debug_context->stop_next = -1;
|
355
387
|
|
356
|
-
|
388
|
+
call_at_line(context, debug_context->thnum, binding, file, line);
|
357
389
|
}
|
358
390
|
break;
|
359
391
|
}
|
360
392
|
case RUBY_EVENT_C_CALL:
|
361
|
-
{
|
362
|
-
if(node)
|
363
393
|
{
|
364
394
|
set_frame_source(debug_context, file, line);
|
365
|
-
|
366
|
-
break;
|
395
|
+
break;
|
367
396
|
}
|
368
397
|
case RUBY_EVENT_CALL:
|
369
398
|
{
|
370
399
|
save_call_frame(self, file, line, mid, debug_context);
|
371
|
-
breakpoint_index = check_breakpoints(
|
400
|
+
breakpoint_index = check_breakpoints(debug_context, file, klass, rb_str_new2(rb_id2name(mid)));
|
372
401
|
if(breakpoint_index != -1)
|
373
402
|
{
|
374
403
|
binding = self? create_binding(self) : Qnil;
|
375
404
|
breakpoint = get_breakpoint_at(breakpoint_index);
|
376
405
|
if(check_breakpoint_expression(breakpoint, binding))
|
377
406
|
{
|
378
|
-
rb_funcall(context, idAtBreakpoint,
|
379
|
-
|
407
|
+
rb_funcall(context, idAtBreakpoint, 1, breakpoint);
|
408
|
+
call_at_line(context, debug_context->thnum, binding, file, line);
|
380
409
|
}
|
381
410
|
}
|
382
411
|
break;
|
@@ -407,7 +436,7 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
407
436
|
if( !NIL_P(rb_class_inherited_p(expn_class, rb_eSystemExit)) )
|
408
437
|
{
|
409
438
|
debug_stop(mDebugger);
|
410
|
-
|
439
|
+
break;
|
411
440
|
}
|
412
441
|
|
413
442
|
if(catchpoint == Qnil)
|
@@ -419,10 +448,10 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
419
448
|
aclass = rb_ary_entry(ancestors, i);
|
420
449
|
if(rb_str_cmp(rb_mod_name(aclass), catchpoint) == 0)
|
421
450
|
{
|
422
|
-
rb_funcall(context, idAtCatchpoint,
|
451
|
+
rb_funcall(context, idAtCatchpoint, 1, ruby_errinfo);
|
423
452
|
binding = self? create_binding(self) : Qnil;
|
424
|
-
|
425
|
-
|
453
|
+
call_at_line(context, debug_context->thnum, binding, file, line);
|
454
|
+
break;
|
426
455
|
}
|
427
456
|
}
|
428
457
|
|
@@ -437,18 +466,6 @@ debug_event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
|
|
437
466
|
debugging--;
|
438
467
|
}
|
439
468
|
|
440
|
-
static VALUE
|
441
|
-
debug_thnum(VALUE self)
|
442
|
-
{
|
443
|
-
VALUE thread, context;
|
444
|
-
debug_context_t *debug_context;
|
445
|
-
|
446
|
-
thread = rb_thread_current();
|
447
|
-
context = thread_context_lookup(thread);
|
448
|
-
Data_Get_Struct(context, debug_context_t, debug_context);
|
449
|
-
return INT2FIX(debug_context->thnum);
|
450
|
-
}
|
451
|
-
|
452
469
|
static VALUE
|
453
470
|
debug_start(VALUE self)
|
454
471
|
{
|
@@ -743,9 +760,8 @@ context_stop_next(VALUE self, VALUE steps)
|
|
743
760
|
static VALUE
|
744
761
|
context_step_over(int argc, VALUE *argv, VALUE self)
|
745
762
|
{
|
746
|
-
VALUE lines, frame
|
763
|
+
VALUE lines, frame;
|
747
764
|
debug_context_t *debug_context;
|
748
|
-
debug_frame_t *debug_frame;
|
749
765
|
|
750
766
|
debug_check_started();
|
751
767
|
|
@@ -766,10 +782,6 @@ context_step_over(int argc, VALUE *argv, VALUE self)
|
|
766
782
|
debug_context->dest_frame = FIX2INT(frame);
|
767
783
|
}
|
768
784
|
|
769
|
-
cur_frame = *RARRAY(debug_context->frames)->ptr;
|
770
|
-
Data_Get_Struct(cur_frame, debug_frame_t, debug_frame);
|
771
|
-
debug_context->src_line = FIX2INT(debug_frame->line);
|
772
|
-
|
773
785
|
return Qnil;
|
774
786
|
}
|
775
787
|
|
@@ -937,7 +949,6 @@ Init_ruby_debug()
|
|
937
949
|
rb_define_module_function(mDebugger, "start", debug_start, 0);
|
938
950
|
rb_define_module_function(mDebugger, "stop", debug_stop, 0);
|
939
951
|
rb_define_module_function(mDebugger, "started?", debug_is_started, 0);
|
940
|
-
rb_define_module_function(mDebugger, "thnum", debug_thnum, 0);
|
941
952
|
rb_define_module_function(mDebugger, "breakpoints", debug_breakpoints, 0);
|
942
953
|
rb_define_module_function(mDebugger, "add_breakpoint", debug_add_breakpoint, -1);
|
943
954
|
rb_define_module_function(mDebugger, "catchpoint", debug_catchpoint, 0);
|
@@ -974,7 +985,7 @@ Init_ruby_debug()
|
|
974
985
|
rb_define_method(cBreakpoint, "pos", breakpoint_pos, 0);
|
975
986
|
rb_define_method(cBreakpoint, "expr", breakpoint_expr, 0);
|
976
987
|
|
977
|
-
|
988
|
+
idAtLine = rb_intern("at_line");
|
978
989
|
idAtBreakpoint = rb_intern("at_breakpoint");
|
979
990
|
idAtCatchpoint = rb_intern("at_catchpoint");
|
980
991
|
idAtTracing = rb_intern("at_tracing");
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Debugger
|
2
|
+
class LocalInterface
|
3
|
+
def read_command(prompt)
|
4
|
+
readline(prompt, true)
|
5
|
+
end
|
6
|
+
|
7
|
+
def confirm(prompt)
|
8
|
+
readline(prompt, false)
|
9
|
+
end
|
10
|
+
|
11
|
+
def print(*args)
|
12
|
+
STDOUT.printf(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def close
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
begin
|
21
|
+
require 'readline'
|
22
|
+
def readline(prompt, hist)
|
23
|
+
Readline::readline(prompt, hist)
|
24
|
+
end
|
25
|
+
rescue LoadError
|
26
|
+
def readline(prompt, hist)
|
27
|
+
STDOUT.print prompt
|
28
|
+
STDOUT.flush
|
29
|
+
line = STDIN.gets
|
30
|
+
exit unless line
|
31
|
+
line.chomp!
|
32
|
+
line
|
33
|
+
end
|
34
|
+
USE_READLINE = false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class RemoteInterface
|
39
|
+
def initialize(socket)
|
40
|
+
@socket = socket
|
41
|
+
end
|
42
|
+
|
43
|
+
def read_command(prompt)
|
44
|
+
send_command "PROMPT #{prompt}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def confirm(prompt)
|
48
|
+
send_command "CONFIRM #{prompt}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def print(*args)
|
52
|
+
@socket.printf(*args)
|
53
|
+
end
|
54
|
+
|
55
|
+
def close
|
56
|
+
@socket.close
|
57
|
+
rescue Exception
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def send_command(msg)
|
63
|
+
@socket.puts msg
|
64
|
+
result = @socket.gets
|
65
|
+
raise IOError unless result
|
66
|
+
result.chomp
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|