arcadia 0.1.2.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
- name=event-log
2
- active=yes
3
- require=ext/ae-event-log/ae-event-log
4
- class=EventLog
5
-
1
+ name=event-log
2
+ active=no
3
+ require=ext/ae-event-log/ae-event-log
4
+ class=EventLog
5
+
@@ -127,10 +127,10 @@ class FileH < ArcadiaExt
127
127
  if _event.context.file
128
128
  self.add2history(_event.context.file)
129
129
  add_to_tree(_event.context.file)
130
- end
130
+ end
131
131
  when EditorContract::FILE_AFTER_CLOSE
132
132
  if _event.context.file
133
- end
133
+ end
134
134
  end
135
135
  end
136
136
 
@@ -0,0 +1,6 @@
1
+ name=flag
2
+ label=Flag
3
+ frame=0.0
4
+ active=no
5
+ require=ext/ae-flag/ae-flag
6
+ class=ArcadiaFlag
@@ -0,0 +1,12 @@
1
+
2
+
3
+ class ArcadiaFlag < ArcadiaExt
4
+ def build
5
+ @tkLabel3 = TkLabel.new(self.frame){
6
+ image TkPhotoImage.new('format'=>'GIF','data' =>A_LOGO_GIF)
7
+ background "#000000"
8
+ place('x'=> 0,'y' => 0, 'relwidth' =>'1', 'relheight'=>'1')
9
+ }
10
+
11
+ end
12
+ end
@@ -1,7 +1,7 @@
1
- name=objic
2
- label=Object Inspector
3
- frame=1.0
4
- active=yes
5
- require=ext/ae-inspector/ae-inspector
6
- class=ObjiController
7
-
1
+ name=objic
2
+ label=Object Inspector
3
+ frame=1.0
4
+ active=yes
5
+ require=ext/ae-inspector/ae-inspector
6
+ class=ObjiController
7
+
@@ -1,15 +1,15 @@
1
- name=output2
2
- label=Event Log
3
- frame=1.1
4
- active=yes
5
- require=ext/ae-output/ae-output
6
- class=Output
7
- MsgContract.channel=CH1
8
-
9
-
10
- font=courier 10
11
- font.bold=courier 10 bold
12
- freebsd::font=courier 10
13
- freebsd::font.bold=courier 12 bold
14
- win::font={Courier New} 9
15
- win::font.bold={Courier New} 9 bold
1
+ name=output2
2
+ label=Event Log
3
+ frame=1.1
4
+ active=no
5
+ require=ext/ae-output/ae-output
6
+ class=Output
7
+ MsgContract.channel=CH1
8
+
9
+
10
+ font=courier 10
11
+ font.bold=courier 10 bold
12
+ freebsd::font=courier 10
13
+ freebsd::font.bold=courier 12 bold
14
+ win::font={Courier New} 9
15
+ win::font.bold={Courier New} 9 bold
@@ -1,7 +1,7 @@
1
- name=palette
2
- label=Palette
3
- frame=0.0
4
- active=yes
5
- require=ext/ae-palette/ae-palette
6
- class=Palette
7
-
1
+ name=palette
2
+ label=Palette
3
+ frame=0.0
4
+ active=yes
5
+ require=ext/ae-palette/ae-palette
6
+ class=Palette
7
+
@@ -0,0 +1,20 @@
1
+ #==============================================================
2
+ name=ruby-debug
3
+ label=Ruby Debug
4
+ frame=1.0
5
+ active=yes
6
+ require=ext/ae-ruby-debug/ae-ruby-debug
7
+ class=RubyDebug
8
+ #==============================================================
9
+ server.host=localhost
10
+ server.port=8989
11
+ server.timeout=10
12
+ font=courier 10
13
+ font.bold=courier 10 bold
14
+ color.background=#ffffff
15
+ color.foreground=#000000
16
+ freebsd::font=courier 10
17
+ freebsd::font.bold=courier 10 bold
18
+ win::font={Courier New} 8
19
+ win::font.bold={Courier New} 8 bold
20
+
@@ -0,0 +1,1329 @@
1
+ #
2
+ # ae-ruby-debug.rb - Arcadia Ruby ide
3
+ # by Antonio Galeone <antonio-galeone@rubyforge.org>
4
+ #
5
+
6
+ class RubyDebugView
7
+ def initialize(_frame, _controller)
8
+ @frame = _frame
9
+ @controller = _controller
10
+ self.build_ui
11
+ @controller.rdc.add_listener(self)
12
+ @nodes_to_open = Array.new
13
+ #@break_hash = Hash.new
14
+ end
15
+
16
+ def build_buttons_set
17
+ _relief = 'groove'
18
+ @debug_button_box.add(
19
+ 'name'=>'debug_over',
20
+ 'background' => 'white',
21
+ 'anchor' => 'nw',
22
+ 'command'=>proc{self.debug_send(:step_over)},
23
+ 'helptext'=>'step over',
24
+ 'image'=> TkPhotoImage.new('dat' => D_NEXT_GIF),
25
+ 'relief'=> _relief
26
+ )
27
+ @debug_button_box.add(
28
+ 'name'=>'debug_into',
29
+ 'background' => 'white',
30
+ 'anchor' => 'nw',
31
+ 'command'=>proc{self.debug_send(:step_into)},
32
+ 'helptext'=>'step into',
33
+ 'image'=> TkPhotoImage.new('dat' => D_STEP_INTO_GIF),
34
+ 'relief'=>_relief
35
+ )
36
+ @debug_button_box.add(
37
+ 'name'=>'debug_out',
38
+ 'background' => 'white',
39
+ 'anchor' => 'nw',
40
+ 'helptext'=>'step out',
41
+ 'command'=>proc{self.debug_send(:step_out)},
42
+ 'image'=> TkPhotoImage.new('dat' => D_STEP_OUT_GIF),
43
+ 'relief'=>_relief
44
+ )
45
+ @debug_button_box.add(
46
+ 'name'=>'debug_resume',
47
+ 'background' => 'white',
48
+ 'anchor' => 'nw',
49
+ 'helptext'=>'resume',
50
+ 'image'=> TkPhotoImage.new('dat' => D_RESUME_GIF),
51
+ 'command'=>proc{self.debug_send(:resume)},
52
+ 'relief'=>_relief
53
+ )
54
+
55
+ @debug_button_box.add(
56
+ 'name'=>'debug_quit',
57
+ 'background' => 'white',
58
+ 'anchor' => 'nw',
59
+ 'helptext'=>'quit',
60
+ 'image'=> TkPhotoImage.new('dat' => D_QUIT_GIF),
61
+ 'command'=>proc{self.debug_send(:quit)},
62
+ 'relief'=>_relief
63
+ )
64
+
65
+ end
66
+
67
+ def build_ui
68
+ _y = 22
69
+ @debug_button_box = Tk::BWidget::ButtonBox.new(@frame){
70
+ homogeneous true
71
+ state 'disabled'
72
+ #background '#3d7956'
73
+ }.place('height'=> _y)
74
+
75
+ @debug_frame = TkFrame.new(@frame){
76
+ border 2
77
+ place(
78
+ 'y'=>_y,
79
+ 'height'=> -_y,
80
+ 'relheight'=> 1,
81
+ 'relwidth'=> 1
82
+ )
83
+ }
84
+
85
+ self.build_buttons_set
86
+
87
+ sf = AGTkOSplittedFrames.new(@debug_frame,70)
88
+
89
+ #-------------------------------------------------
90
+ build_process_panel(sf.top_frame)
91
+ #-------------------------------------------------
92
+
93
+ @enb = Tk::BWidget::NoteBook.new(sf.bottom_frame){
94
+ tabbevelsize 0
95
+ internalborderwidth 2
96
+ activeforeground 'red'
97
+ activebackground 'yellow'
98
+ #background 'black'
99
+ borderwidth 1
100
+ side $arcadia['conf']['editor.tabs.side']
101
+ font $arcadia['conf']['editor.tabs.font']
102
+ place('relwidth' => 1,'relheight' => '1')
103
+ }
104
+ _tab_var = @enb.insert('end', 'vars' ,
105
+ 'text'=> 'Variables',
106
+ 'raisecmd'=>proc{}
107
+ )
108
+ _tab_breakpoint = @enb.insert('end', 'Breakpoint' ,
109
+ 'text'=> 'Breakpoints',
110
+ 'raisecmd'=>proc{}
111
+ )
112
+ # _tab_catchpoint = @enb.insert('end', 'catchpoint' ,
113
+ # 'text'=> 'catchpoint',
114
+ # 'raisecmd'=>proc{}
115
+ # )
116
+
117
+ build_var_panel(_tab_var)
118
+ build_break_panel(_tab_breakpoint)
119
+
120
+ @stack_nodes = Array.new
121
+ @enb.raise('vars')
122
+
123
+ end
124
+
125
+ def build_process_panel(_frame)
126
+ @tree_process = Tk::BWidget::Tree.new(_frame){
127
+ background '#FFFFFF'
128
+ relief 'flat'
129
+ showlines false
130
+ deltay 15
131
+ place('relwidth' => 1,'relheight' => '1')
132
+ }
133
+ @tree_process.textbind("Double-ButtonPress-1", proc{
134
+ _selected = @tree_process.selection_get[0]
135
+ if @tree_process.parent(_selected)=='client'
136
+ _text = @tree_process.itemcget(_selected, 'text')
137
+ pos = match_position_from_stack(_text)
138
+ if pos.length >0
139
+ EditorContract.instance.open_file(self, 'file'=>pos[0], 'line'=>pos[1])
140
+ end
141
+ end
142
+ })
143
+
144
+ end
145
+
146
+ def start_process(_filename)
147
+ @tree_process.insert('end', 'root' ,'server', {
148
+ 'text' => "Server => #{File.basename(_filename)} at #{@controller.conf('server.host')}:#{@controller.conf('server.port')}",
149
+ 'font' => @controller.conf('font.bold')
150
+ })
151
+ @tree_process.insert('end', 'server' ,'client', {
152
+ 'font' => @controller.conf('font.bold'),
153
+ 'text' => "Client"
154
+ })
155
+ @tree_process.open_tree('server',true)
156
+ end
157
+
158
+ def tree_var_free
159
+ @tree_var.delete(@tree_var.nodes('local_var'))
160
+ @tree_var.delete(@tree_var.nodes('instance_var'))
161
+ @tree_var.delete(@tree_var.nodes('global_var'))
162
+ @tree_var.delete(@tree_var.nodes('eval')) if @tree_var.exist?('eval')
163
+ end
164
+
165
+ def tree_process_free
166
+ @tree_process.delete(@tree_process.nodes('root'))
167
+ end
168
+
169
+
170
+ def build_var_panel(_frame)
171
+ _open_proc = proc do |_arg|
172
+ inspect_node(_arg) if @nodes_to_open.include?(_arg)
173
+ end
174
+
175
+ @tree_var = Tk::BWidget::Tree.new(_frame){
176
+ background '#FFFFFF'
177
+ relief 'flat'
178
+ showlines true
179
+ linesfill '#e7de8f'
180
+ deltay 15
181
+ opencmd _open_proc
182
+ # pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
183
+ }.place('relwidth' => 1,'relheight' => '1','bordermode' => 'inside')
184
+
185
+ _scrollcommand = proc{|*args| @tree_var.yview(*args)}
186
+ _scrollbar = TkScrollbar.new(_frame){|s|
187
+ width 8
188
+ command _scrollcommand
189
+ }.pack('side'=>'right', 'fill'=>'y')
190
+ @tree_var.yscrollcommand proc{|first,last| _scrollbar.set(first,last)}
191
+
192
+ @local_on = true
193
+ @instance_on = true
194
+ @global_on = false
195
+
196
+ _i_on = TkPhotoImage.new('dat' => ON_GIF)
197
+ _i_off = TkPhotoImage.new('dat' => OFF_GIF)
198
+
199
+ _b_relief = 'groove'
200
+ @b_local_onoff = TkButton.new(@tree_var){
201
+ image _i_on
202
+ relief _b_relief
203
+ state 'disabled'
204
+ anchor 'nw'
205
+ }.bind("1",proc{
206
+ @local_on = !@local_on
207
+ if @local_on
208
+ @b_local_onoff.image(_i_on)
209
+ command_enabled(false)
210
+ Thread.new{
211
+ update_variables('local_var', @controller.rdc.variables('local_variables')) #if @tree_var.open?('local_var')
212
+ command_enabled(true)
213
+ }
214
+ else
215
+ @b_local_onoff.image(_i_off)
216
+ @tree_var.delete(@tree_var.nodes('local_var'))
217
+ end
218
+ })
219
+
220
+ @tree_var.insert('end', 'root' ,'local_var', {
221
+ #'deltax' => 0,
222
+ #'padx'=>2,
223
+ 'fill'=>'#3f941b',
224
+ 'open'=>true,
225
+ 'anchor'=>'w',
226
+ 'font' => @controller.conf('font.bold'),
227
+ 'text' => "Local variables",
228
+ 'window' => @b_local_onoff
229
+ })
230
+
231
+ @b_instance_onoff = TkButton.new(@tree_var){
232
+ image _i_on
233
+ relief _b_relief
234
+ state 'disabled'
235
+ anchor 'nw'
236
+ }.bind("1",proc{
237
+ @instance_on = !@instance_on
238
+ if @instance_on
239
+ @b_instance_onoff.image(_i_on)
240
+ command_enabled(false)
241
+ Thread.new{
242
+ update_variables('instance_var', @controller.rdc.variables('instance_variables')) #if @tree_var.open?('local_var')
243
+ command_enabled(true)
244
+ }
245
+ else
246
+ @b_instance_onoff.image(_i_off)
247
+ @tree_var.delete(@tree_var.nodes('instance_var'))
248
+ end
249
+ })
250
+ @tree_var.insert('end', 'root' ,'instance_var', {
251
+ # 'deltax' => 0,
252
+ # 'padx'=>2,
253
+ 'fill'=>'#892541',
254
+ 'open'=>true,
255
+ 'anchor'=>'w',
256
+ 'font' => @controller.conf('font.bold'),
257
+ 'text' => "Instance variables",
258
+ 'window' => @b_instance_onoff
259
+ })
260
+
261
+ @b_global_onoff = TkButton.new(@tree_var){
262
+ image _i_off
263
+ relief _b_relief
264
+ state 'disabled'
265
+ anchor 'nw'
266
+ }.bind("1",proc{
267
+ @global_on = !@global_on
268
+ if @global_on
269
+ @b_global_onoff.image(_i_on)
270
+ command_enabled(false)
271
+ Thread.new{
272
+ update_variables('global_var', @controller.rdc.variables('global_variables')) #if @tree_var.open?('local_var')
273
+ command_enabled(true)
274
+ }
275
+ else
276
+ @b_global_onoff.image(_i_off)
277
+ @tree_var.delete(@tree_var.nodes('global_var'))
278
+ end
279
+ })
280
+ @tree_var.insert('end', 'root' ,'global_var', {
281
+ 'fill'=>'#f94867',
282
+ 'open'=>true,
283
+ 'anchor'=>'w',
284
+ 'font' => @controller.conf('font.bold'),
285
+ 'text' => "Global variables",
286
+ 'window' => @b_global_onoff
287
+ })
288
+
289
+
290
+
291
+ end
292
+
293
+ def build_break_panel(_tab_breakpoint)
294
+ @tree_break = Tk::BWidget::Tree.new(_tab_breakpoint){
295
+ background '#FFFFFF'
296
+ relief 'flat'
297
+ showlines true
298
+ linesfill '#e7de8f'
299
+ deltay 15
300
+ }.place('relwidth' => 1,'relheight' => '1')
301
+ end
302
+
303
+ def file2node_name(_file)
304
+ _s = ""
305
+ _file.gsub("/",_s).gsub(".",_s).gsub(":",_s).gsub("\\",_s).gsub("-",_s)
306
+ end
307
+
308
+ def line2node_name(_parent, _line)
309
+ "#{_parent}_#{_line.to_s}"
310
+ end
311
+
312
+ def break_list_add(_file, _line)
313
+ _file_node = file2node_name(_file)
314
+ _line_node = line2node_name(_file_node, _line)
315
+ if !@tree_break.exist?(_file_node)
316
+ @tree_break.insert('end', 'root' ,_file_node, {
317
+ 'fill'=>'#8080ff',
318
+ 'open'=>true,
319
+ 'anchor'=>'w',
320
+ 'font' => @controller.conf('font.bold'),
321
+ 'text' => _file
322
+ })
323
+ end
324
+
325
+ if !@tree_break.exist?(_line_node)
326
+ @tree_break.insert('end', _file_node ,_line_node, {
327
+ 'fill'=>'#f94867',
328
+ 'open'=>true,
329
+ 'anchor'=>'w',
330
+ 'font' => @controller.conf('font.bold'),
331
+ 'text' => "line: #{_line}"
332
+ })
333
+ end
334
+ end
335
+
336
+ def break_list_del(_file, _line)
337
+ _file_node = file2node_name(_file)
338
+ _line_node = line2node_name(_file_node, _line)
339
+ if @tree_break.exist?(_line_node)
340
+ @tree_break.delete(_line_node)
341
+ _bro = @tree_break.nodes(_file_node)
342
+ if _bro && _bro.length > 0
343
+ @tree_break.delete(_file_node)
344
+ end
345
+ end
346
+ end
347
+
348
+ def break_list_select(_file, _line)
349
+ _file_node = file2node_name(_file)
350
+ _line_node = line2node_name(_file_node, _line)
351
+ @tree_break.selection_clear
352
+ if @tree_break.exist?(_line_node)
353
+ @tree_break.selection_add(_line_node)
354
+ @tree_break.see(_line_node)
355
+ end
356
+ end
357
+
358
+
359
+ def break_list_free
360
+ @tree_break.delete(@tree_break.nodes('root'))
361
+ end
362
+
363
+ def clear
364
+ tree_var_free
365
+ tree_process_free
366
+ break_list_free
367
+ end
368
+
369
+
370
+ def rdebug_client_update(_command, _result)
371
+ #MsgContract.instance.out_debug(self,"on command #{_command}")
372
+ return if !@controller.rdc.is_debugging_ready?
373
+ begin
374
+ if _command == 'quit'
375
+ msg = "Really quit debug ? (y/n)"
376
+ ans = Tk.messageBox('icon' => 'question', 'type' => 'yesno',
377
+ 'title' => '(Arcadia) Debug', 'message' => msg)
378
+ if ans == 'yes'
379
+ debug_send(:quit_yes)
380
+ clear
381
+ else
382
+ debug_send(:quit_no)
383
+ end
384
+ elsif _command == 'quit_yes'
385
+ clear
386
+ elsif _command == 'quit_no'
387
+ command_enabled(true)
388
+ elsif _command != 'where' && _command != 'quit_yes'
389
+ begin
390
+ update_position
391
+ update_variables('local_var', @controller.rdc.variables('local_variables')) if @local_on
392
+ update_variables('instance_var', @controller.rdc.variables('instance_variables')) if @instance_on
393
+ #MsgContract.instance.out_debug(self,"on command #{_command}:global_variables")
394
+ update_variables('global_var', @controller.rdc.variables('global_variables')) if @global_on
395
+ ensure
396
+ command_enabled(true) if @controller.rdc.is_debugging_ready? && (!_command.include?('quit') || _command.include?('quit_no'))
397
+ end
398
+ end
399
+ rescue Exception => e
400
+ MsgContract.instance.out_debug(self,"on command #{_command}:#{e.inspect}")
401
+ end
402
+ end
403
+
404
+ def match_position_from_stack(_line)
405
+ ret = Array.new
406
+ _target = _line.sub("-->",'').strip
407
+ matchline = _target.match(/#[0-9]*.*:([0-9]*)/)
408
+ line_no = matchline[1].to_i if !matchline.nil? && matchline.length==2
409
+ matchfile = _target.match(/#[0-9]*.(.*):[0-9]*/)
410
+ filename = matchfile[1].to_s if !matchfile.nil? && matchfile.length==2
411
+ if filename && line_no
412
+ ret << filename << line_no
413
+ end
414
+ ret
415
+ end
416
+
417
+ def update_position
418
+ stack = @controller.rdc.where
419
+ #MsgContract.instance.out_debug(self,stack)
420
+ if !stack.nil?
421
+ stack = stack.split(/\n/)
422
+ line_no = -1
423
+ if !stack[0].nil?
424
+ pos = match_position_from_stack(stack[0])
425
+ #matchline = stack[0].match(/-->.#[0-9]*.*:([0-9]*)/)
426
+ ##matchline = stack[0].match(/.*:([0-9]*)/)
427
+ #line_no = matchline[1].to_i if !matchline.nil? && matchline.length==2
428
+
429
+ #matchfile = stack[0].match(/-->.#[0-9]*.(.*):[0-9]*/)
430
+ ##matchfile = stack[0].match(/.(.*):[0-9]*/)
431
+
432
+ #filename = matchfile[1].to_s if !matchfile.nil? && matchfile.length==2
433
+ end
434
+ if pos.length > 0
435
+ #MsgContract.instance.out_debug(self,"'file'=> #{pos[0]}, 'line'=>#{pos[1]}")
436
+ _file = File.expand_path(pos[0])
437
+ DebugContract.instance.debug_step(self, 'file'=> _file, 'line'=>pos[1])
438
+ break_list_select(_file, pos[1].to_s)
439
+ end
440
+ i = 0
441
+ @tree_process.delete(@stack_nodes)
442
+ stack.each do |line|
443
+ _node = "c#{i.to_s}"
444
+ @tree_process.insert('end', 'client' ,_node, {
445
+ # 'deltax' => 0,
446
+ # 'padx'=>2,
447
+ 'font' => @controller.conf('font'),
448
+ 'text' => line,
449
+ 'helptext' => line
450
+ })
451
+ @stack_nodes << _node
452
+ i = i+1
453
+ end
454
+ end
455
+ end
456
+
457
+ def is_simple_class?(_class)
458
+ ['Numeric','Fixnum','String','FalseClass','TrueClass','NilClass'].include?(_class)
459
+ # _class == Numeric || _class.superclass == Numeric ||
460
+ # _class == String || _class.superclass == String ||
461
+ # _class == FalseClass || _class.superclass == FalseClass||
462
+ # _class == TrueClass || _class.superclass == TrueClass||
463
+ # _class == NilClass || _class.superclass == NilClass
464
+ end
465
+
466
+ def show_expression(_exp, _hash)
467
+ if !@tree_var.exist?('eval')
468
+ @tree_var.insert('end', 'root' ,'eval', {
469
+ 'fill'=>'#4aadf7',
470
+ 'open'=>true,
471
+ 'anchor'=>'w',
472
+ 'font' => @controller.conf('font.bold'),
473
+ 'text' => "Eval selection"
474
+ })
475
+ end
476
+ update_variables('eval', _hash)
477
+ end
478
+
479
+ def inspect_node(_node)
480
+ command_enabled(false)
481
+ begin
482
+ _var = var_name(_node)
483
+ _o = @controller.rdc.debug_dump(_var)
484
+ #@tree_var.delete(@tree_var.nodes(_node))
485
+ var_deep(_node, _o)
486
+ ensure
487
+ command_enabled(true)
488
+ end
489
+ end
490
+
491
+ def var_deep(_var, _hash)
492
+ # _var_cla = _hash['__CLASS__']
493
+ # _var_len = _hash['__LENGTH__']
494
+ # @tree_var.itemconfigure(_var, 'text' => "#{_var_cla}:#{_var_len}")
495
+ return nil if _hash.nil?
496
+ return _hash.to_s if _hash.class != Hash
497
+ _hash.keys.sort.each{|k|
498
+ v = _hash[k]
499
+ next if k=='__CLASS__'
500
+ _complex = v.class == Hash
501
+ if _complex
502
+ _text = var_format(k,v['__CLASS__'])
503
+ elsif (k=='__LENGTH__') && v=='0'
504
+ _text = '{...}'
505
+ elsif (k=='__LENGTH__') && v!='0'
506
+ next
507
+ else
508
+ _text = var_format(k,nil,v)
509
+ end
510
+ _node = node_name(k, _var)
511
+ if @tree_var.exist?(_node)
512
+ @tree_var.itemconfigure(_node, 'text' => _text)
513
+ else
514
+ @tree_var.insert('end', _var ,_node, {
515
+ 'font' => @controller.conf('font'),
516
+ 'text' => _text,
517
+ 'helptext' => v,
518
+ 'anchor'=>'w'
519
+ })
520
+ end
521
+ var_deep(_node,v) if _complex
522
+ }
523
+ end
524
+
525
+ def var_format(_name, _class, _value=nil)
526
+ if !_value.nil? && !_class.nil?
527
+ return "#{_name.to_s.strip} => #{_value.to_s.strip} [#{_class.to_s.strip}]"
528
+ elsif _value.nil? && !_class.nil?
529
+ return "#{_name.to_s.strip} [#{_class.to_s.strip}]"
530
+ elsif !_value.nil? && _class.nil?
531
+ return "#{_name.to_s.strip} => #{_value.to_s.strip}"
532
+ elsif _value.nil? && _class.nil?
533
+ return "#{_name.to_s.strip} => {...}"
534
+ end
535
+ end
536
+
537
+ def node_name(_node, _parent)
538
+ return "#{_parent}@@@#{_node.gsub('$','__S__').gsub('&','__E__').gsub(':','__D__').gsub('!','__A__')}"
539
+ end
540
+
541
+ def var_name(_node)
542
+ #_parent = @tree_var.parent(_node)
543
+ #return _node.sub("#{_parent}_", '')
544
+ return _node.split('@@@')[-1].gsub('__S__','$').gsub('__E__','&').gsub('__D__',':').gsub('__A__','!')
545
+ end
546
+
547
+ def command_enabled(_value)
548
+ #MsgContract.instance.out_debug(self,"command_enabled= #{_value.to_s}")
549
+
550
+ @c_on = _value
551
+ _value ? _state = 'normal':_state = 'disabled'
552
+ @debug_button_box.configure(:state=>_state)
553
+ @b_local_onoff.configure(:state=>_state)
554
+ @b_instance_onoff.configure(:state=>_state)
555
+ @b_global_onoff.configure(:state=>_state)
556
+ Tk.update
557
+ end
558
+
559
+ def update_variables(_parent_node, _var)
560
+ if _var.keys.sort == @tree_var.nodes(_parent_node).collect! {|x| var_name(x).to_s}.sort
561
+ _var.each{|k,v|
562
+ _n = node_name(k, _parent_node)
563
+ if is_simple_class?(v.value_class)
564
+ _text = var_format(k,v.value_class,v.value)
565
+ else
566
+ _text = var_format(k,v.value_class)
567
+ end
568
+ _node = @tree_var.itemconfigure(_n, 'text' => _text)
569
+ }
570
+ else
571
+ @nodes_to_open.clear
572
+ @tree_var.delete(@tree_var.nodes(_parent_node))
573
+ #@nodes[_parent_node].clear
574
+ _var.each{|k,v|
575
+ _n = node_name(k, _parent_node)
576
+ if is_simple_class?(v.value_class)
577
+ #MsgContract.instance.out_simple(self,"#{k} : simple")
578
+ _text = var_format(k,v.value_class,v.value)
579
+ _drawcross = 'auto'
580
+ else
581
+ #MsgContract.instance.out_simple(self,"#{k} : complex")
582
+ _text = var_format(k,v.value_class)
583
+ _drawcross = 'always'
584
+ @nodes_to_open << _n
585
+ end
586
+ @tree_var.insert('end', _parent_node ,_n, {
587
+ 'font' => @controller.conf('font'),
588
+ 'text' => _text,
589
+ 'helptext' => v.value,
590
+ 'drawcross' => _drawcross,
591
+ 'anchor'=>'w'
592
+ # 'deltax' => 1
593
+ })
594
+ #@nodes[_parent_node] << k
595
+ }
596
+ end
597
+ Tk.update
598
+ end
599
+
600
+ def debug_send(_command)
601
+ if @controller.rdc
602
+ begin
603
+ command_enabled(false)
604
+ #@debug_button_box.configure(:state=>'disabled')
605
+ Thread.new{@controller.rdc.send(_command)}
606
+ #@controller.rdc.send(_command)
607
+ rescue Exception => e
608
+ MsgContract.instance.out_debug(self,"---> "+e.to_s)
609
+ end
610
+ end
611
+ end
612
+ end
613
+
614
+ class RubyDebugException < Exception
615
+ end
616
+
617
+ class RubyDebugServer
618
+ include Observable
619
+ RDS_QUIET = 'RDS_QUIET'
620
+ def initialize(_caller)
621
+ if _caller.respond_to? :rdebug_server_update
622
+ ObserverCallback.new(self,_caller,:rdebug_server_update)
623
+ end
624
+ end
625
+
626
+ def start_session(_filename, _host='localhost', _remote_port='8989')
627
+ if is_windows?
628
+ commandLine = "rdebug.cmd --port #{_remote_port} -sw #{_filename}"
629
+ else
630
+ commandLine = "rdebug --host #{_host} --port #{_remote_port} -sw #{_filename}"
631
+ end
632
+ #MsgContract.instance.out_debug(self,commandLine)
633
+ begin
634
+ if is_windows?
635
+ @tid = Thread.new {
636
+ Kernel.system(commandLine)
637
+ Kernel.system('y')
638
+ notify(RDS_QUIET)
639
+ }
640
+ else
641
+ @pid = Process.fork {
642
+ Kernel.system(commandLine)
643
+ Kernel.exit!
644
+ notify(RDS_QUIET)
645
+ }
646
+ end
647
+ rescue Exception => e
648
+ MsgContract.instance.out_debug(self,"Error on start_server : #{e.class}:#{e.message}")
649
+ end
650
+ end
651
+
652
+ def kill
653
+ begin
654
+ if is_windows?
655
+ @tid.join(2)
656
+ @tid.kill!
657
+ else
658
+ Process.kill('QUIT',@pid)
659
+ end
660
+ notify(RDS_QUIET)
661
+ rescue Exception => e
662
+ MsgContract.instance.out_debug(self,"Error on start_server : #{e.class}:#{e.message}")
663
+ end
664
+ end
665
+
666
+ def is_windows?
667
+ !(RUBY_PLATFORM =~ /(win|w)32$/).nil?
668
+ #RUBY_PLATFORM.include?('win')
669
+ end
670
+
671
+ def notify(_state)
672
+ changed
673
+ notify_observers(_state)
674
+ end
675
+
676
+ end
677
+
678
+ #Ruby-debug commands
679
+
680
+ # * b[reak]
681
+ # list breakpoints
682
+ # * b[reak] [file|class:]LINE|METHOD [if expr]
683
+ # * b[reak] [class.]LINE|METHOD [if expr]
684
+ # set breakpoint to some position, optionally if expr == true
685
+ # * cat[ch]
686
+ # show catchpoint
687
+ # * cat[ch] EXCEPTION
688
+ # set catchpoint to an exception
689
+ # * disp[lay] EXPRESSION add expression into display expression list
690
+ # * undisp[lay][ nnn]
691
+ # delete one particular or all display expressions if no expression number given
692
+ # * del[ete][ nnn]
693
+ # delete some or all breakpoints (get the number using “break”)
694
+ # * c[ont]
695
+ # run until program ends or hit breakpoint
696
+ # * r[un]
697
+ # alias for cont
698
+ # * s[tep][ nnn]
699
+ # step (into methods) one line or till line nnn
700
+ # * n[ext][ nnn]
701
+ # go over one line or till line nnn
702
+ # * w[here]
703
+ # displays stack
704
+ # * f[rame]
705
+ # alias for where
706
+ # * l[ist][ (-|nn-mm)]
707
+ # list program, - list backwards, nn-mm list given lines. No arguments keeps listing
708
+ # * up[ nn]
709
+ # move to higher frame
710
+ # * down[ nn]
711
+ # move to lower frame
712
+ # * fin[ish]
713
+ # return to outer frame
714
+ # * q[uit]
715
+ # exit from debugger
716
+ # * v[ar] g[lobal]
717
+ # show global variables
718
+ # * v[ar] l[ocal]
719
+ # show local variables
720
+ # * v[ar] i[nstance] OBJECT
721
+ # show instance variables of object
722
+ # * v[ar] c[onst] OBJECT
723
+ # show constants of object
724
+ # * m[ethod] i[nstance] OBJECT
725
+ # show methods of object
726
+ # * m[ethod] CLASS|MODULE
727
+ # show instance methods of class or module
728
+ # * th[read] l[ist]
729
+ # list all threads
730
+ # * th[read] c[ur[rent]]
731
+ # show current thread
732
+ # * th[read] [sw[itch]] nnn
733
+ # switch thread context to nnn
734
+ # * th[read] stop nnn
735
+ # stop thread nnn
736
+ # * th[read] resume nnn
737
+ # resume thread nnn
738
+ # * p EXPRESSION
739
+ # evaluate expression and print its value
740
+ # * pp EXPRESSSION
741
+ # evaluate expression and print its value
742
+ # * h[elp]
743
+ # print this help
744
+ # * RETURN KEY
745
+ # redo previous command. Convenient when using list, step, next, up, down,
746
+ # * EVERYHTING ELSE
747
+ # evaluate
748
+
749
+
750
+ class RubyDebugClient
751
+ require 'socket'
752
+ require 'yaml'
753
+ include Observable
754
+ Var = Struct.new("Var",
755
+ :value,
756
+ :value_class
757
+ )
758
+
759
+ def initialize(_server='localhost', _port=8989, _timeout=0)
760
+ @session = nil
761
+ @server = _server
762
+ @port = _port
763
+ @timeout = _timeout.to_i
764
+ @busy = false
765
+ @pend = false
766
+ end
767
+
768
+ def add_listener(_caller, _method=:rdebug_client_update)
769
+ if _caller.respond_to? :rdebug_client_update
770
+ ObserverCallback.new(self,_caller,:rdebug_client_update)
771
+ end
772
+ end
773
+
774
+ def notify(_command, _result=nil)
775
+ #MsgContract.instance.out_debug(self,"notify=>#{_command}")
776
+ @busy = false
777
+ changed
778
+ notify_observers(_command, _result)
779
+ _result
780
+ end
781
+
782
+ def is_debugging_ready?
783
+ is_alive? && !is_busy?
784
+ end
785
+
786
+ def is_busy?
787
+ @busy
788
+ end
789
+
790
+ def is_alive?
791
+ !@session.nil? && !@session.closed? && !@pend
792
+ end
793
+
794
+ def socket_session
795
+ if @session.nil?
796
+ begin
797
+ #sleep(2)
798
+ @session = TCPSocket.new(@server, @port)
799
+ @pend = false
800
+ rescue Errno::ECONNREFUSED => e
801
+ sleep(1)
802
+ @t = @t -1
803
+ if @t > 0
804
+ socket_session
805
+ else
806
+ MsgContract.instance.out_debug(self,"socket_session : #{e.inspect}")
807
+ end
808
+ end
809
+ end
810
+ #MsgContract.instance.out_debug(self,"session : #{@session.inspect}")
811
+ return @session
812
+ end
813
+
814
+ def kill
815
+ begin
816
+ @session.close if is_alive?
817
+ @session = nil
818
+ rescue Exception => e
819
+ MsgContract.instance.out_debug(self,"Error on close session : #{e.class}:#{e.message}")
820
+ end
821
+ end
822
+
823
+ def start_session
824
+ begin
825
+ @t = @timeout
826
+ if socket_session
827
+ #MsgContract.instance.out_debug(self,"session : #{@session.inspect}")
828
+ notify('start', read)
829
+ read("eval require 'yaml'")
830
+ end
831
+ return @session
832
+ rescue Exception => e
833
+ MsgContract.instance.out_debug(self,"Error on start_session : #{e.class}:#{e.message}")
834
+ end
835
+ end
836
+
837
+ def stop_session
838
+ begin
839
+ quit if is_debugging_ready?
840
+ @session.close if is_alive?
841
+ rescue Exception => e
842
+ MsgContract.instance.out_debug(self,"Error on stop_session : #{e.class}:#{e.inspect}")
843
+ end
844
+ end
845
+
846
+ # send a command to the debugger via socket
847
+ def command(_command)
848
+ #MsgContract.instance.out_debug(self,"command=>#{_command}")
849
+ begin
850
+ return false if @busy
851
+ if is_alive?
852
+ @busy = true
853
+ socket_session.puts(_command)
854
+ else
855
+ start_session if !@pend
856
+ end
857
+ true
858
+ rescue Errno::ECONNABORTED => e
859
+ #kill
860
+ notify("quit_yes")
861
+ DebugContract.instance.debug_end(self)
862
+ MsgContract.instance.out_debug(self,"Debugged has finished executing")
863
+ @session = nil
864
+ @pend = true
865
+ false
866
+ #raise RubyDebugException.new("Debugged has finished executing")
867
+ rescue Exception => e
868
+ MsgContract.instance.out_debug(self,"Error on command #{_command}: #{e.class}:#{e.inspect}")
869
+ false
870
+ end
871
+ end
872
+ private :command
873
+
874
+ def read(_command=nil)
875
+ return nil if _command && !command(_command)
876
+ socket_session.flush
877
+ result = ""
878
+ while _command !='y' && is_alive? && line = socket_session.gets
879
+ #MsgContract.instance.out_debug(self, "read: letta riga => #{line}")
880
+ break if line =~ /^PROMPT (.*)$/ || line =~ /.(y\/n)./
881
+ result << line
882
+ #break if _command =~ /^eval./
883
+ end
884
+ #MsgContract.instance.out_simple(self, "read(#{_command}): result => #{result}")
885
+ @busy = false
886
+ result
887
+
888
+ rescue Errno::ECONNABORTED
889
+ raise RubyDebugException.new("Debugged has finished executing")
890
+ rescue Errno::ECONNRESET
891
+ raise RubyDebugException.new("Debugged has finished executing")
892
+ rescue Exception => e
893
+ raise RubyDebugException.new("Error: on command '#{_command}' => #{e.class} : #{e.inspect}")
894
+ end
895
+ private :read
896
+
897
+
898
+ def step_over
899
+ notify("next", read("next"))
900
+ end
901
+
902
+ def step_into
903
+ notify("step", read("step"))
904
+ end
905
+
906
+ def step_out
907
+ notify("fin", read("fin"))
908
+ end
909
+
910
+ def resume
911
+ notify("cont", read("cont"))
912
+ end
913
+
914
+ def where
915
+ notify("where", read("where"))
916
+ end
917
+
918
+ def quit
919
+ notify("quit", read("q"))
920
+ end
921
+
922
+ def quit_yes
923
+ notify("quit_yes", read("y"))
924
+ DebugContract.instance.debug_end(self)
925
+ kill
926
+ end
927
+
928
+ def quit_no
929
+ notify("quit_no", read("n"))
930
+ end
931
+
932
+ # return the current stack trace
933
+ def stacktrace
934
+ notify("backtrace", read("backtrace"))
935
+ end
936
+
937
+
938
+ def yaml_pseudo_load(_obj)
939
+ #MsgContract.instance.out_simple(self,"_obj="+_obj.inspect)
940
+ just_present = @valuobjs.include?(_obj)
941
+ @valuobjs << _obj
942
+ if _obj.class == YAML::DomainType
943
+ #MsgContract.instance.out_simple(self,"_obj DomainType="+_obj.inspect)
944
+ return _obj.type_id if just_present
945
+ ret = Hash.new
946
+ ret['__CLASS__']=_obj.type_id
947
+ l = _obj.value.length
948
+ ret['__LENGTH__']= l.to_s
949
+ if l > 0
950
+ _obj.value.each{|k,v|
951
+ ret["@#{k}"]=yaml_pseudo_load(v)
952
+ }
953
+ end
954
+ ret
955
+ elsif _obj.class == Hash
956
+ #MsgContract.instance.out_simple(self,"_obj Hash="+_obj.inspect)
957
+ return 'Hash' if just_present
958
+ ret = Hash.new
959
+ ret['__CLASS__']= 'Hash'
960
+ l = _obj.length
961
+ ret['__LENGTH__']= l.to_s
962
+ if l > 0
963
+ _obj.each{|k,v|
964
+ ret[k]=yaml_pseudo_load(v)
965
+ }
966
+ end
967
+ ret
968
+ elsif _obj.class == Array
969
+ #MsgContract.instance.out_simple(self,"_obj Array="+_obj.inspect)
970
+ return 'Array' if just_present
971
+ ret = Hash.new
972
+ ret['__CLASS__']= 'Array'
973
+ l = _obj.length
974
+ ret['__LENGTH__']= l.to_s
975
+ if l > 0
976
+ _obj.each_with_index{|v,i|
977
+ ret[i.to_s]=yaml_pseudo_load(v)
978
+ }
979
+ end
980
+ ret
981
+ elsif _obj.class == Struct
982
+ #MsgContract.instance.out_simple(self,"_obj Array="+_obj.inspect)
983
+ return 'Struct' if just_present
984
+ ret = Hash.new
985
+ ret['__CLASS__']= 'Struct'
986
+ l = _obj.length
987
+ ret['__LENGTH__']= l.to_s
988
+ if l > 0
989
+
990
+ _obj.members.each{|m|
991
+ ret[m]=yaml_pseudo_load(_obj[m])
992
+ }
993
+ end
994
+ ret
995
+ else
996
+ #MsgContract.instance.out_simple(self,"_obj ="+_obj.inspect)
997
+
998
+ _obj
999
+ end
1000
+
1001
+ end
1002
+
1003
+
1004
+ def debug_dump(_exp)
1005
+ var = nil
1006
+ if @valuobjs.nil?
1007
+ @valuobjs = Array.new
1008
+ else
1009
+ @valuobjs.clear
1010
+ end
1011
+ begin
1012
+ _str = eval(read("eval YAML::dump(#{_exp})"))
1013
+ #MsgContract.instance.out_simple(self,"value passato 1 ="+_str.to_s)
1014
+ _str.gsub!('!ruby/object:', '!')
1015
+ #MsgContract.instance.out_simple(self,"value passato 2 ="+_str.to_s)
1016
+ _obj = YAML::load(_str)
1017
+ var = yaml_pseudo_load(_obj)
1018
+ rescue Exception => e
1019
+ MsgContract.instance.out_simple(self,"exception on eval #{_exp} :#{e.inspect}")
1020
+ var = nil
1021
+ end
1022
+ return var
1023
+ end
1024
+
1025
+
1026
+ # returns the instance variables and there values
1027
+ def instance_variables_new(_this='self')
1028
+ command("eval #{_this}.instance_variables")
1029
+ variables = []
1030
+ begin
1031
+ variables = eval(read)
1032
+ rescue Exception
1033
+ variables = []
1034
+ end
1035
+ @consider = Array.new
1036
+ variable_values = Hash.new
1037
+ variables.each do |var|
1038
+ #next if var != '@objs'
1039
+ # command("eval require 'pp'; #{var}.pretty_inspect() + '|||' + #{var}.class.to_s")
1040
+ command("eval YAML::dump(#{var})")
1041
+ _str = eval read
1042
+ #MsgContract.instance.out_simple(self,"value passato 1 ="+_str)
1043
+
1044
+ _str.gsub!('!ruby/object:', '!')
1045
+
1046
+ #MsgContract.instance.out_simple(self,"value passato 2 ="+_str)
1047
+
1048
+ _obj = YAML::load(_str)
1049
+
1050
+ _xvalue = yaml_pseudo_load(_obj)
1051
+ if _xvalue.class == Hash
1052
+ _xclass = _xvalue['__CLASS__']
1053
+ else
1054
+ _xclass = _xvalue.class.to_s
1055
+ end
1056
+ #_vvv = eval(_value)
1057
+
1058
+ #MsgContract.instance.out_simple(self,"vvv class="+_vvv.class.to_s)
1059
+
1060
+ #MsgContract.instance.out_simple(self,"value="+_xvalue.inspect)
1061
+ #MsgContract.instance.out_simple(self,"class="+_xclass)
1062
+ variable_values[var] = Var.new(_xvalue, _xclass)
1063
+ end
1064
+ return variable_values
1065
+ end
1066
+
1067
+ # returns the local variables and there values
1068
+ def variables(_type)
1069
+ begin
1070
+ #variables = read[1..-2].split(', ').collect!{|x| x[1..-2]}
1071
+ to_eval = read("eval #{_type}")
1072
+ #MsgContract.instance.out_simple(self,"to_eval="+to_eval.to_s)
1073
+ variables = eval(to_eval)
1074
+ #MsgContract.instance.out_simple(self,"variables="+variables.to_s)
1075
+ rescue Exception => e
1076
+ variables = []
1077
+ #p "on command eval #{_type}:#{e.inspect}"
1078
+ #MsgContract.instance.out_debug(self,"on command eval #{_type}:#{e.inspect}")
1079
+ end
1080
+ variables = [] if variables.nil?
1081
+ variable_values = Hash.new
1082
+ variables.each do |var|
1083
+ next if var=='$;'
1084
+ # command("eval #{var}.to_s + '|||' + #{var}.class.to_s")
1085
+ # _str = eval(read)
1086
+ # _value, _class = _str.split('|||')
1087
+ # variable_values[var] = Var.new(_value, _class)
1088
+ variable_values[var] = debug_eval(var)
1089
+ end
1090
+ return variable_values
1091
+ end
1092
+
1093
+ def debug_eval(_exp)
1094
+ command("eval #{res=_exp}.to_s + '|||' + #{res}.class.to_s")
1095
+ _str = eval(read)
1096
+ _value, _class = _str.split('|||')
1097
+ return Var.new(_value, _class)
1098
+ end
1099
+
1100
+ # returns the local variables and there values
1101
+ def local_variables
1102
+ command("eval local_variables")
1103
+ variables = []
1104
+ begin
1105
+ variables = eval(read)
1106
+ rescue Exception
1107
+ variables = []
1108
+ end
1109
+ variable_values = Hash.new
1110
+ variables.each do |var|
1111
+ command("eval #{var}.to_s + '|||' + #{var}.class.to_s")
1112
+ _str = eval(read)
1113
+ _value, _class = _str.split('|||')
1114
+ variable_values[var] = Var.new(_value, eval(_class))
1115
+ end
1116
+ return variable_values
1117
+ end
1118
+
1119
+
1120
+ # returns the global variables and there values
1121
+ def global_variables
1122
+ command("eval global_variables")
1123
+ variables = []
1124
+ begin
1125
+ variables = eval(read)
1126
+ rescue Exception
1127
+ variables = []
1128
+ end
1129
+ variable_values = Hash.new
1130
+ variables.each do |var|
1131
+ command("eval #{var}.to_s")
1132
+ variable_values[var] = read
1133
+ end
1134
+ return variable_values
1135
+ end
1136
+
1137
+
1138
+ def set_breakpoint(_file, _line)
1139
+ #_line = _line + 1
1140
+ text = read("break #{_file}:#{_line}")
1141
+ breakpoint_no = -1
1142
+ matches = text.match(/Set breakpoint ([0-9]*)?/)
1143
+ breakpoint_no = matches[1].to_i if (matches.length == 2)
1144
+ return breakpoint_no
1145
+ end
1146
+
1147
+ def unset_breakpoint(_id)
1148
+ read("delete #{_id}")
1149
+ end
1150
+ end
1151
+
1152
+ class RubyDebug < ArcadiaExt
1153
+ attr_reader :rds
1154
+ attr_reader :rdc
1155
+ def before_build
1156
+ ArcadiaContractListener.new(self, EditorContract, :do_editor_event)
1157
+ @breakpoints = Hash.new
1158
+ @static_breakpoints = Array.new
1159
+ end
1160
+
1161
+ def build
1162
+ end
1163
+
1164
+ def do_editor_event(_event)
1165
+ case _event.signature
1166
+ when EditorContract::BREAKPOINT_AFTER_CREATE
1167
+ self.breakpoint_add(File.expand_path(_event.context.file), _event.context.line)
1168
+ when EditorContract::BREAKPOINT_AFTER_DELETE
1169
+ self.breakpoint_del(File.expand_path(_event.context.file), _event.context.line)
1170
+ when EditorContract::BUFFER_AFTER_RAISE
1171
+ @raised_file=_event.context.file
1172
+ when EditorContract::EVAL_EXPRESSION
1173
+ eval_expression(_event.context.text)
1174
+ end
1175
+ end
1176
+
1177
+ def eval_expression(_exp)
1178
+ res = @rdc.debug_eval(_exp) if @rdc && @rdc.is_debugging_ready?
1179
+ hash = Hash.new
1180
+ hash[_exp]=res
1181
+ @rdv.show_expression(_exp, hash) if res
1182
+ end
1183
+
1184
+ def start_debug_server
1185
+ end
1186
+ private :start_debug_server
1187
+
1188
+ def start_debug_client
1189
+ end
1190
+ private :start_debug_client
1191
+
1192
+
1193
+ def breakpoint_suf(_file,_line)
1194
+ return _line.to_s + "-" + _file.to_s
1195
+ end
1196
+ private :breakpoint_suf
1197
+
1198
+ def break_name(_file,_line)
1199
+ "#{_file}:#{_line}"
1200
+ end
1201
+
1202
+ def breakpoint_add_live(_file,_line)
1203
+ if @rdc
1204
+ @breakpoints[breakpoint_suf(_file,_line)] = @rdc.set_breakpoint(_file, _line.to_i)
1205
+ @rdv.break_list_add(_file,_line) if @rdv
1206
+ end
1207
+ end
1208
+
1209
+ def breakpoint_del_live(_file,_line)
1210
+ if @rdc
1211
+ @rdc.unset_breakpoint(@breakpoints.delete(breakpoint_suf(_file,_line)))
1212
+ @rdv.break_list_del(_file,_line) if @rdv
1213
+ end
1214
+ end
1215
+
1216
+ def breakpoint_free_live
1217
+ @breakpoints.clear
1218
+ @rdv.break_list_free if @rdv
1219
+ end
1220
+
1221
+ def breakpoint_add(_file,_line)
1222
+ breakpoint_add_live(_file,_line)
1223
+ @static_breakpoints << {:file=>_file,:line=>_line}
1224
+ end
1225
+ #private :breakpoint_add
1226
+
1227
+ def breakpoint_del(_file,_line)
1228
+ breakpoint_del_live(_file,_line)
1229
+ @static_breakpoints.delete_if{|b| (b[:file]==_file && b[:line]==_line)}
1230
+ end
1231
+ #private :breakpoint_del
1232
+
1233
+
1234
+ def can_exit_query
1235
+ if @rdc
1236
+ query = (Tk.messageBox('icon' => 'question', 'type' => 'yesno',
1237
+ 'title' => '(Arcadia) Debug',
1238
+ 'message' => "Debug in course, do you want to exit?")=='yes')
1239
+ if query
1240
+ debug_quit
1241
+ return true
1242
+ else
1243
+ return false
1244
+ end
1245
+ else
1246
+ return true
1247
+ end
1248
+ end
1249
+
1250
+
1251
+
1252
+ def debug_begin
1253
+ breakpoint_free_live
1254
+ DebugContract.instance.debug_begin(self)
1255
+ end
1256
+
1257
+ def debug_last
1258
+ debug($arcadia['pers']['run.file.last'])
1259
+ end
1260
+
1261
+ def debug_current
1262
+ debug(@raised_file) if @raised_file!=nil
1263
+ end
1264
+ def debugging?
1265
+ !@rdc.nil? && @rdc.is_alive?
1266
+ end
1267
+ def debug(_filename=nil)
1268
+ if _filename && !debugging?
1269
+ begin
1270
+ self.debug_begin
1271
+ @arcadia['pers']['run.file.last']=_filename
1272
+ @rds = RubyDebugServer.new(self) if @rds.nil?
1273
+ @rds.start_session(_filename, conf('server.host'), conf('server.port'))
1274
+ #MsgContract.instance.out_simple(self,@rds.to_s)
1275
+ @rdc = RubyDebugClient.new(conf('server.host'), conf('server.port'), conf('server.timeout')) if @rdc.nil?
1276
+ @rdv = RubyDebugView.new(self.frame, self) if @rdv.nil?
1277
+ @rdv.start_process(_filename)
1278
+ if @rdc.start_session
1279
+ @static_breakpoints.each{|_b|
1280
+ #MsgContract.instance.out_simple(self," breakpoint_add #{_b[:file]}:#{_b[:line]}")
1281
+ breakpoint_add_live(_b[:file], _b[:line])
1282
+ }
1283
+ end
1284
+ #MsgContract.instance.out_simple(self,"\n<begin debug>")
1285
+
1286
+ rescue Exception => e
1287
+ MsgContract.instance.out_debug(self,"---> "+e.to_s)
1288
+ end
1289
+ end
1290
+ end
1291
+
1292
+
1293
+ def rdebug_server_update(_state)
1294
+ case _state
1295
+ when RubyDebugServer::_RDS_QUIT_
1296
+ debug_quit
1297
+ end
1298
+ p _state
1299
+ end
1300
+
1301
+ def debug_free
1302
+ self.frame_free
1303
+ @rdc = nil
1304
+ @rdv = nil
1305
+ end
1306
+
1307
+ def debug_quit
1308
+ if @rdc
1309
+ if @rdc.is_alive?
1310
+ Thread.new{
1311
+ Tk.messageBox('icon' => 'info',
1312
+ 'type' => 'ok',
1313
+ 'title' => '(Arcadia) Debug',
1314
+ 'message' => "Debug in course, stop it before exit")
1315
+ }
1316
+ else
1317
+ begin
1318
+ debug_free
1319
+ rescue Exception => e
1320
+ MsgContract.instance.out_debug(self, "debug_quit:---> "+e.to_s)
1321
+ #@arcadia['shell'].outln("debug_quit:---> "+e.to_s )
1322
+ end
1323
+ end
1324
+ end
1325
+ end
1326
+
1327
+
1328
+
1329
+ end