arcadia 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ name=debug
2
+ label=Debug
3
+ frame=1.0
4
+ active=yes
5
+ require=ext/ae-debug/ae-debug
6
+ class=ArcadiaDebug
7
+
@@ -0,0 +1,582 @@
1
+ #
2
+ # ae-debug.rb - Arcadia Ruby ide
3
+ # by Antonio Galeone <antonio-galeone@rubyforge.org>
4
+ #
5
+
6
+ require "observer"
7
+
8
+ class ArcadiaDebugWrapper
9
+ include Observable
10
+ attr_reader :last_command
11
+
12
+ def initialize
13
+ (RUBY_PLATFORM == 'i386-mswin32')?_cmd="cmd":_cmd='sh'
14
+ @io = IO.popen(_cmd,'w')
15
+ @last_command = _cmd
16
+ @stop = false
17
+ @transfer_file=ArcadiaDebugWrapper.transfer_file
18
+ @threads = Array.new
19
+ end
20
+
21
+ def ArcadiaDebugWrapper.transfer_file
22
+ '~transfer-debug-file.tmp'
23
+ end
24
+
25
+ def start_debug(_file=nil)
26
+ @breakpoint_id=0
27
+ @file=_file
28
+ if File.exist?(@transfer_file)
29
+ File.delete(@transfer_file)
30
+ end
31
+ if _file
32
+ @main_thread = Thread.new{
33
+ command($arcadia['conf']['shell.ruby']+" -r ext/ae-debug/debug1.57 "+_file)
34
+ @last_command = 'debug'
35
+ read
36
+ }
37
+ end
38
+ end
39
+
40
+ def quit_debug
41
+ command("q\ny\n")
42
+ command("exit\n")
43
+ @threads.each{|t|
44
+ if t.alive?
45
+ t.kill
46
+ end
47
+ }
48
+ @main_thread.kill
49
+ end
50
+
51
+ def step_over
52
+ @threads << Thread.new{
53
+ command("n")
54
+ read
55
+ }
56
+ end
57
+
58
+ def step_into
59
+ @threads << Thread.new{
60
+ command("s")
61
+ read
62
+ }
63
+ end
64
+
65
+ def resume
66
+ Thread.new{
67
+ command("c")
68
+ read
69
+ }
70
+ end
71
+
72
+ def finish
73
+ Thread.new{
74
+ command("fin")
75
+ read
76
+ }
77
+ end
78
+
79
+ def v_global
80
+ @threads << Thread.new{
81
+ command("v g")
82
+ read
83
+ }
84
+ end
85
+
86
+ def v_local
87
+ @threads << Thread.new{
88
+ command("v l")
89
+ read
90
+ }
91
+ end
92
+
93
+ def v_instance(_obj)
94
+ @threads << Thread.new{
95
+ command("v i "+_obj)
96
+ read
97
+ }
98
+ end
99
+
100
+ def breakpoint_set(_pos, _context=nil)
101
+ @threads << Thread.new{
102
+ if _context
103
+ command("b "+_context+':'+_pos)
104
+ else
105
+ command("b "+_pos)
106
+ end
107
+ read
108
+ }
109
+ @breakpoint_id = @breakpoint_id + 1 if @breakpoint_id
110
+ end
111
+
112
+ def breckpoint_del(_id)
113
+ @threads << Thread.new{
114
+ if _id
115
+ command("del "+_id)
116
+ else
117
+ command("del")
118
+ end
119
+ read
120
+ }
121
+ end
122
+
123
+ def command(_command)
124
+ begin
125
+ @io.puts(_command)
126
+ @last_command = _command
127
+ rescue Exception => e
128
+ $arcadia.outln("\n"+" error on :"+" command >>> "+_command+' : '+e.to_s ) if $arcadia
129
+ end
130
+ end
131
+
132
+ def stop
133
+ @stop = true
134
+ end
135
+
136
+ def read
137
+ begin
138
+ while !File.exist?(@transfer_file)
139
+ end
140
+ if File.exist?(@transfer_file)
141
+ while !File.stat(@transfer_file).readable?
142
+ end
143
+ File.open(@transfer_file) do |f|
144
+ $ppp = Marshal.load(f)
145
+ end
146
+ while !File.stat(@transfer_file).writable?
147
+ end
148
+ File.delete(@transfer_file) if File.exist?(@transfer_file)
149
+ changed
150
+ notify_observers($ppp)
151
+ end
152
+ rescue Exception => e
153
+ MsgContract.instance.out_debug(self, "\n"+'Error on : '+" read >>> "+@transfer_file+" : "+e.to_s )
154
+ #$arcadia.outln("\n read >>> "+@transfer_file+" � andato in errore :"+e.to_s ) if $arcadia
155
+ end
156
+ end
157
+ end
158
+
159
+ class ArcadiaDebug < ArcadiaExt
160
+
161
+ def before_build
162
+ ArcadiaContractListener.new(self, EditorContract, :do_editor_event)
163
+ @breakpoints = Hash.new
164
+ @static_breakpoints = Array.new
165
+ end
166
+
167
+ def build
168
+ end
169
+
170
+ def debug_state
171
+ end
172
+
173
+ def breakpoint_suf(_file,_line)
174
+ return _line.to_s + "-" + _file.to_s
175
+ end
176
+
177
+ def breakpoint_add(_file,_line)
178
+ if @adw
179
+ @breakpoints[breakpoint_suf(_file,_line)] = @adw.breakpoint_set(_line, _file)
180
+ else
181
+ @static_breakpoints << {:file=>_file,:line=>_line}
182
+ end
183
+ end
184
+
185
+ def breakpoint_del(_file,_line)
186
+ if @adw
187
+ @adw.breakpoint_del(@breakpoints.delete(breakpoint_suf(_file,_line)))
188
+ end
189
+ @static_breakpoints.delete_if{|b| (b[:file]==_file && b[:line]==_line)}
190
+ end
191
+
192
+ def do_editor_event(_event)
193
+ #@arcadia.outln('in debug _sender ----> '+_sender.to_s)
194
+ #@arcadia.outln('in debug _event.signature ----> '+_event.signature)
195
+ case _event.signature
196
+ when EditorContract::BREAKPOINT_AFTER_CREATE
197
+ self.breakpoint_add(_event.context.file, _event.context.line)
198
+ when EditorContract::BREAKPOINT_AFTER_DELETE
199
+ self.breakpoint_del(_event.context.file, _event.context.line)
200
+ when EditorContract::BUFFER_AFTER_RAISE
201
+ @raised_file=_event.context.file
202
+ end
203
+ end
204
+
205
+ def can_exit_query
206
+ if @adw
207
+ query = (Tk.messageBox('icon' => 'question', 'type' => 'yesno',
208
+ 'title' => '(Arcadia) Debug',
209
+ 'message' => "Debug in course, do you want to exit?")=='yes')
210
+ if query
211
+ debug_quit
212
+ return true
213
+ else
214
+ return false
215
+ end
216
+ else
217
+ return true
218
+ end
219
+ end
220
+
221
+ class VariablesViewText < TkTitledFrame
222
+ attr_reader :text
223
+
224
+ def initialize(parent=nil, title='...', maximize_to=nil ,keys=nil)
225
+ super(parent, title, maximize_to, keys)
226
+ @top_label.configure(:background => 'red')
227
+ @text = TkText.new(self.frame,
228
+ 'relief' => 'flat',
229
+ 'wrap' => 'none'
230
+ ){|j|
231
+ parent = TkWinfo.parent(j)
232
+ TkScrollbar.new(parent){|s|
233
+ command proc{|*args| j.yview(*args)}
234
+ j.yscrollcommand proc{|first,last| s.set first,last}
235
+ }.pack('side'=>'right', 'fill'=>'y')
236
+ TkScrollbar.new(parent){|s|
237
+ command proc{|*args| j.xview(*args)}
238
+ orient 'horizontal'
239
+ j.xscrollcommand proc{|first,last| s.set first,last}
240
+ }.pack('side'=>'bottom', 'fill'=>'x')
241
+ }.place(
242
+ 'relwidth' => '1',
243
+ 'relx' => 0,
244
+ 'x' => '0',
245
+ 'y' => '0',
246
+ 'relheight' => '1',
247
+ 'rely' => 0,
248
+ 'height' => '-15',
249
+ 'bordermode' =>
250
+ 'inside',
251
+ 'width' => '-15'
252
+ )
253
+ place('x'=>0, 'y'=>0,'relheight'=>1, 'relwidth'=>1)
254
+ end
255
+ end
256
+
257
+ class VariablesViewProperties < TkTitledScrollFrame
258
+ attr_reader :inspector
259
+
260
+ def initialize(parent=nil, title='...', maximize_to=nil ,keys=nil)
261
+ super(parent, title, maximize_to, keys)
262
+ @inspector=InspectListReadOnly.new(self.frame.cwin)
263
+ place('x'=>0, 'y'=>0,'relheight'=>1, 'relwidth'=>1)
264
+ end
265
+
266
+ end
267
+
268
+
269
+ class ArcadiaDebugInfo
270
+
271
+ def initialize(_parent=nil)
272
+ @nb = Tk::BWidget::NoteBook.new(_parent){
273
+ tabbevelsize 0
274
+ internalborderwidth 2
275
+ activeforeground 'red'
276
+ activebackground 'yellow'
277
+ borderwidth 1
278
+ side $arcadia['conf']['editor.tabs.side']
279
+ font $arcadia['conf']['editor.tabs.font']
280
+ pack('fill'=>'both', :expand => 'yes')
281
+ }
282
+
283
+ @nb_variables = @nb.insert('end','var' ,'text'=>'Variables' )
284
+
285
+ @hsplitter = AGTkOSplittedFrames.new(@nb_variables,220)
286
+
287
+ @hsplitter2 = AGTkOSplittedFrames.new(@hsplitter.top_frame,80)
288
+ @vvl=VariablesViewText.new(@hsplitter2.top_frame,'Local')
289
+ @vvi=VariablesViewText.new(@hsplitter2.bottom_frame,'Instance(self)')
290
+ @vvg=VariablesViewText.new(@hsplitter.bottom_frame,'Global')
291
+ font = $arcadia['conf']['inspectors.debug.tabs.font']
292
+ font_b = $arcadia['conf']['inspectors.debug.tabs.font.bold']
293
+ @vvl.text.tag_configure('key',
294
+ 'foreground' => 'blue',
295
+ 'font'=> font
296
+ )
297
+ @vvl.text.tag_configure('value',
298
+ 'foreground' => 'black',
299
+ 'font'=> font
300
+ )
301
+ @vvl.text.tag_configure('sep',
302
+ 'foreground' => 'gray',
303
+ 'font'=> font
304
+ )
305
+
306
+ @vvi.text.tag_configure('key',
307
+ 'foreground' => 'blue',
308
+ 'font'=> font
309
+ )
310
+
311
+ @vvi.text.tag_configure('value',
312
+ 'foreground' => 'black',
313
+ 'font'=> font
314
+ )
315
+
316
+ @vvi.text.tag_configure('sep',
317
+ 'foreground' => 'gray',
318
+ 'font'=> font
319
+ )
320
+
321
+ @vvg.text.tag_configure('key',
322
+ 'foreground' => '#018869',
323
+ 'font'=> font
324
+ )
325
+
326
+ @vvg.text.tag_configure('value',
327
+ 'foreground' => 'black' ,
328
+ 'font'=> font
329
+ )
330
+
331
+ @vvg.text.tag_configure('sep',
332
+ 'foreground' => 'gray',
333
+ 'font'=> font
334
+ )
335
+
336
+ @nb.raise('var')
337
+ end
338
+
339
+ def hash_to_str(_hash, _ind=0)
340
+ str = ''
341
+ _hash.each{|key,val|
342
+ str = str + "/s"*_ind+ key.to_s+' => '+val.to_s+"\n"
343
+ if val.kind_of?(Hash)
344
+ str = str + hash_to_str(val,_ind+2)
345
+ end
346
+ }
347
+ return str
348
+ end
349
+
350
+ def update_globals(_vars)
351
+ @vvg.text.delete('1.0','end')
352
+ if _vars != nil
353
+ str = ''
354
+ _vars.each{|key,val|
355
+ @vvg.text.insert('end',key.to_s.ljust(18),'key')
356
+ @vvg.text.insert('end','','sep')
357
+ @vvg.text.insert('end',val.to_s+"\n",'value')
358
+ }
359
+ end
360
+ end
361
+ def update_locals(_vars)
362
+ @vvl.text.delete('1.0','end')
363
+ if _vars != nil
364
+ # @vvl.inspector.updatelines(_vars)
365
+ _vars.each{|key,val|
366
+ @vvl.text.insert('end',key.to_s.ljust(18),'key')
367
+ @vvl.text.insert('end','','sep')
368
+ @vvl.text.insert('end',val.to_s+"\n",'value')
369
+ }
370
+ end
371
+ end
372
+
373
+ def update_instances(_vars)
374
+ @vvi.text.delete('1.0','end')
375
+ if _vars != nil
376
+ _vars.each{|key,val|
377
+ @vvi.text.insert('end',key.to_s.ljust(18),'key')
378
+ @vvi.text.insert('end','','sep')
379
+ @vvi.text.insert('end',val.to_s+"\n",'value')
380
+ }
381
+ end
382
+ end
383
+
384
+ end
385
+
386
+
387
+ def debug_begin
388
+ @breakpoints.clear
389
+ DebugContract.instance.debug_begin(DebugContract::TDebugObj.new(self))
390
+ end
391
+
392
+
393
+ def debug_last
394
+ debug($arcadia['pers']['run.file.last'])
395
+ end
396
+
397
+ def debug_current
398
+ debug(@raised_file) if @raised_file!=nil
399
+ end
400
+
401
+ def debug(_filename=nil)
402
+ if _filename
403
+ begin
404
+ self.debug_begin
405
+ @debug_button_box = Tk::BWidget::ButtonBox.new(self.frame){
406
+ homogeneous true
407
+ }.pack('anchor'=>'w')#('fill'=>'x')
408
+ @debug_button_box.add(
409
+ 'name'=>'debug_next',
410
+ 'command'=>proc{self.debug_next},
411
+ 'helptext'=>'step next',
412
+ 'image'=> TkPhotoImage.new('dat' => DEBUG_NEXT_GIF),
413
+ 'relief'=>'flat'
414
+ )
415
+ @debug_button_box.add(
416
+ 'name'=>'debug_into',
417
+ 'command'=>proc{self.debug_into},
418
+ 'helptext'=>'step into',
419
+ 'image'=> TkPhotoImage.new('dat' => DEBUG_INTO_GIF),
420
+ 'relief'=>'flat'
421
+ )
422
+ @debug_button_box.add(
423
+ 'name'=>'debug_fin',
424
+ 'helptext'=>'step over',
425
+ 'command'=>proc{self.debug_fin},
426
+ 'image'=> TkPhotoImage.new('dat' => DEBUG_OUT_GIF),
427
+ 'relief'=>'flat'
428
+ )
429
+ @debug_button_box.add(
430
+ 'name'=>'debug_resume',
431
+ 'helptext'=>'resume',
432
+ 'image'=> TkPhotoImage.new('dat' => DEBUG_RESUME_GIF),
433
+ 'command'=>proc{self.debug_resume},
434
+ 'relief'=>'flat'
435
+ )
436
+
437
+ @debug_button_box.configure(:state=>'disabled')
438
+ @debug_info = ArcadiaDebugInfo.new(self.frame)
439
+ $arcadia['pers']['run.file.last']=_filename
440
+ @adw = ArcadiaDebugWrapper.new
441
+ @adw.add_observer(self)
442
+ @adw.start_debug(_filename)
443
+ #@arcadia['editor'].debug_begin
444
+ MsgContract.instance.out_simple(self,"\n<begin debug>")
445
+
446
+ #@arcadia['shell'].outln("\n<begin debug>")
447
+ rescue Exception => e
448
+ MsgContract.instance.out_debug(self,"---> "+e.to_s)
449
+ #@arcadia['shell'].outln("---> "+e.to_s )
450
+ end
451
+ end
452
+ end
453
+
454
+ def debug_next
455
+ if @adw
456
+ begin
457
+ @debug_button_box.configure(:state=>'disabled')
458
+ @adw.step_over
459
+ rescue Exception => e
460
+ MsgContract.instance.out_debug(self,"---> "+e.to_s)
461
+ #@arcadia['shell'].outln("---> "+e.to_s )
462
+ end
463
+ end
464
+ end
465
+
466
+ def debug_resume
467
+ if @adw
468
+ begin
469
+ @debug_button_box.configure(:state=>'disabled')
470
+ @adw.resume
471
+ rescue Exception => e
472
+ MsgContract.instance.out_debug(self, "debug_resume:---> "+e.to_s)
473
+ #@arcadia['shell'].outln("debug_resume:---> "+e.to_s )
474
+ end
475
+ end
476
+ end
477
+
478
+ def debug_into
479
+ if @adw
480
+ begin
481
+ @debug_button_box.configure(:state=>'disabled')
482
+ @adw.step_into
483
+ rescue Exception => e
484
+ MsgContract.instance.out_debug(self, "---> "+e.to_s)
485
+ # @arcadia['shell'].outln("---> "+e.to_s )
486
+ end
487
+ end
488
+ end
489
+
490
+ def debug_fin
491
+ if @adw
492
+ begin
493
+ @debug_button_box.configure(:state=>'disabled')
494
+ @adw.finish
495
+ rescue Exception => e
496
+ MsgContract.instance.out_debug(self, "---> "+e.to_s)
497
+ #@arcadia['shell'].outln("---> "+e.to_s )
498
+ end
499
+ end
500
+ end
501
+
502
+ def debug_quit
503
+
504
+ if @adw
505
+ begin
506
+ self.frame_free
507
+ #self.debug_end
508
+ @adw.quit_debug
509
+ @adw = nil
510
+ #$arcadia['editor'].debug_end
511
+ MsgContract.instance.out_debug(self, "\n<end debug>")
512
+
513
+ #@arcadia['shell'].outln("\n<end debug>")
514
+ rescue Exception => e
515
+ MsgContract.instance.out_debug(self, "debug_quit:---> "+e.to_s)
516
+ #@arcadia['shell'].outln("debug_quit:---> "+e.to_s )
517
+ end
518
+ end
519
+ end
520
+ def debug_wrapper
521
+ return @adw
522
+ end
523
+
524
+ def update(dbg)
525
+ tobj = DebugContract::TDebugObj.new(self)
526
+ tobj.file = dbg[:file]
527
+ tobj.line = dbg[:line]
528
+ #sobj = @ae_editor_talker.info
529
+ if dbg[:file] != nil
530
+ DebugContract.instance.debug_step(tobj)
531
+ #$arcadia['editor'].open_file_in_debug(dbg[:file], dbg[:line])
532
+ end
533
+ if @adw.last_command == 'debug' && @static_breakpoints.length > 0
534
+ #set breakpoint
535
+ @sindex = 0
536
+ _line = @static_breakpoints[@sindex][:line]
537
+ _file = @static_breakpoints[@sindex][:file]
538
+ self.breakpoint_add(_file, _line)
539
+ @sindex = @sindex + 1
540
+ return
541
+ elsif @adw.last_command[0..1] == 'b ' && @sindex < @static_breakpoints.length
542
+ _line = @static_breakpoints[@sindex][:line]
543
+ _file = @static_breakpoints[@sindex][:file]
544
+ self.breakpoint_add(_file, _line)
545
+ @sindex = @sindex + 1
546
+ return
547
+ end
548
+ if dbg[:error_text] != nil
549
+ str = "\n"+dbg[:file]+':'+dbg[:line].to_s
550
+ str = str + ":\t" +dbg[:error_text].to_s+'('+dbg[:error_class].to_s+')'
551
+ MsgContract.instance.out_debug(self, str)
552
+ #@arcadia['shell'].outln(str,'error')
553
+ end
554
+ if dbg[:callers] != nil
555
+ str = ''
556
+ dbg[:callers].each{|caller|
557
+ str = str+"\n from:"+caller.to_s
558
+ }
559
+
560
+ end
561
+ if str
562
+ MsgContract.instance.out_debug(self, str)
563
+ #@arcadia['shell'].outln(str)
564
+ end
565
+ update_variables(dbg)
566
+ @debug_button_box.configure(:state=>'normal')
567
+ end
568
+
569
+ def update_variables(dbg)
570
+ if @adw.last_command == 'v g'
571
+ @debug_info.update_globals(dbg[:variables])
572
+ @adw.v_local
573
+ elsif @adw.last_command == 'v l'
574
+ @debug_info.update_locals(dbg[:variables])
575
+ @adw.v_instance('self')
576
+ elsif @adw.last_command == 'v i self'
577
+ @debug_info.update_instances(dbg[:variables])
578
+ elsif @adw.last_command[0..1] !='v '
579
+ @adw.v_global
580
+ end
581
+ end
582
+ end