summaryrefslogtreecommitdiff
path: root/gdb/gdbtk/library/debugwin.itb
blob: baeadab300e30a5aec91a4aaf4d6d1b308ca1f16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
59
60
61
62
63
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
147
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
173
174
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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# Debug window for GDBtk.
# Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License (GPL) as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.


# -----------------------------------------------------------------------------
# NAME:		DebugWin::constructor
#	
# SYNOPSIS:	constructor::args
#
# DESC:		Creates the debug window  
#
# ARGS:		None are used yet.
# -----------------------------------------------------------------------------
itcl::body DebugWin::constructor {args} {
  debug $args
  window_name "Insight Debug" "Debug"

  build_win
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::destructor
#	
# SYNOPSIS:	Not called by hand
#
# DESC:		Destroys the debug window
#
# ARGS:		None
# -----------------------------------------------------------------------------
itcl::body DebugWin::destructor {} {
  # notify debug code that window is going away
  ::debug::debugwin ""
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::build_win
#
# SYNOPSIS:	build_win
#	
# DESC:		Creates the Debug Window. Reads the contents of the debug log
#		file, if it exists. Notifies the debug functions in ::debug
#		to send output here.
# -----------------------------------------------------------------------------
itcl::body DebugWin::build_win {} {
  global gdb_ImageDir GDBTK_LIBRARY

  set top [winfo toplevel $itk_interior]
  
  # initialize the gdbtk_de array
  if {![info exists ::gdbtk_de]} {
    set ::gdbtk_de(ALL) 1
    set ::gdbtk_de(ERRORS_ONLY) 0
    set ::gdbtk_de(others) 0
    set ::gdbtk_de(filter_var) ALL
  }

  # create menubar
  set menu [menu $itk_interior.m  -tearoff 0]
  $menu add cascade -menu $menu.file -label "File" -underline 0
  set m [menu $menu.file] 
  $m add command -label "Clear" -underline 1 \
    -command [code $this _clear]
  $m add command -label "Mark Old" -underline 1 \
    -command [code $this _mark_old]
  $m add separator
  $m add command -label "Save" -underline 0 \
    -command [code $this _save_contents]
  $m add separator
  $m add command -label "Close" -underline 0 \
    -command "::debug::debugwin {};delete object $this"
  $menu add cascade -menu $menu.trace -label "Trace"
  set m [menu $menu.trace]
  $m add radiobutton -label Start -variable ::debug::tracing -value 1
  $m add radiobutton -label Stop -variable ::debug::tracing -value 0
  $menu add cascade -menu $menu.rs -label "ReSource"
  set m [menu $menu.rs]
  foreach f [lsort [glob [file join $GDBTK_LIBRARY *.itb]]] {
    $m add command -label "Source [file tail $f]"\
      -command [list source $f]
  }
  $m add separator
  $m add command -label "Source ALL" -command [code $this _source_all]

  $menu add cascade -menu $menu.opt -label "Options"
  set m [menu $menu.opt]
  $m add command -label "Display" -underline 0 \
    -command [list ManagedWin::open DebugWinDOpts -over $this]
  if {!$::debug::initialized} {
    $menu entryconfigure 1 -state disabled
    $menu add cascade -label "     Tracing Not Initialized" -foreground red \
      -activeforeground red
  }
  $menu add cascade -menu $menu.help -label "Help" -underline 0
  set m [menu $menu.help]
  $m add command -label "Debugging Functions" -underline 0 \
    -command {open_help debug.html}

  $top configure -menu $menu
  
  iwidgets::scrolledtext $itk_interior.s -hscrollmode static \
    -vscrollmode static -wrap none -textbackground black -foreground white
  set _t [$itk_interior.s component text]
  pack $itk_interior.s -expand 1 -fill both

  # define tags
  foreach color $_colors {
    $_t tag configure [lindex $color 0] -foreground [lindex $color 1]
  }
  $_t tag configure trace -foreground gray
  $_t tag configure args -foreground blue
  $_t tag configure marked -background grey20

  loadlog

  # now notify the debug functions to use this window
  ::debug::debugwin $this

  # override the window delete procedure so the messages are
  # turned off first.
  wm protocol $top WM_DELETE_WINDOW "::debug::debugwin {};destroy $top"
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::puts
#	
# SYNOPSIS:	puts {level cls func msg}
#
# DESC:		Writes debugging information into the DebugWin. A filter
#		will be applied to determine if the message should be
#		displayed or not.  
#
# ARGS:		level - priority level. See debug::dbug for details.
#		cls   - class name of caller, for example "SrcWin"
#		func  - function name of caller
#		msg   - message to display
# -----------------------------------------------------------------------------
itcl::body DebugWin::puts {level cls func msg} {
  # filter. check if we should display this message
  # for now we always let high-level messages through
  if {$level == "I"} {

    # errors and warnings only
    if {$::gdbtk_de(ERRORS_ONLY)} { return }

    # ALL classes except those set
    if {$::gdbtk_de(ALL)} {
      if {[info exists ::gdbtk_de($cls)]} {
	if {$::gdbtk_de($cls)} {
	  return
	}
      } elseif {$::gdbtk_de(others)} {
	return
      }
    }

    # ONLY the classes set
    if {!$::gdbtk_de(ALL)} {
      if {[info exists ::gdbtk_de($cls)]} {
	if {!$::gdbtk_de($cls)} {
	  return
	}
      } elseif {!$::gdbtk_de(others)} {
	return
      }
    }
  }

  if {$func != ""} {
    append cls ::$func
  }
  $_t insert end "($cls) " {} "$msg\n" $level
  $_t see insert
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::put_trace
#	
# SYNOPSIS:	put_trace {enter level func ar}
#	
# DESC:		Writes trace information into the DebugWin. A filter
#		will be applied to determine if the message should be
#		displayed or not.
#
# ARGS:		enter - 1 if this is a function entry, 0 otherwise.
#		level - stack level
#		func  - function name
#		ar    - function arguments
# -----------------------------------------------------------------------------
itcl::body DebugWin::put_trace {enter level func ar} {
  set x [expr {$level * 2 - 2}]
  if {$enter} {
    $_t insert end "[string range $_bigstr 0 $x]$func " trace "$ar\n" args
  } else {
    $_t insert end "[string range $_bigstr 0 $x]<- $func " trace "$ar\n" args
  }
  $_t see insert
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::loadlog
#
# SYNOPSIS:	loadlog
#	
# DESC:		Reads the contents of the debug log file, if it exists, into 
#		the DebugWin. 
# -----------------------------------------------------------------------------
itcl::body DebugWin::loadlog {} {
  $_t delete 0.0 end
  # Now load in log file, if possible.
  # this is rather rude, using the logfile variable in the debug namespace
  if {$::debug::logfile != "" && $::debug::logfile != "stdout"} {
    flush $::debug::logfile
    seek $::debug::logfile 0 start
    while {[gets $::debug::logfile line] >= 0} {
      while {[catch {set f [lindex $line 0]} f]} {
	# If the lindex failed its because the remainder of the
	# list is on the next line.  Get it.
	if {[gets $::debug::logfile line2] < 0} {
	  break
	}
	append line \n $line2
      }
      if {$f == "T"} {
	put_trace [lindex $line 1] [lindex $line 2] [lindex $line 3] \
	  [lindex $line 4]
      } else {
	puts $f [lindex $line 1] [lindex $line 2] [lindex $line 3]
      }
    }
  }
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::_source_all
#
# SYNOPSIS:	_source_all
#	
# DESC:		Re-sources all the .itb files.
# -----------------------------------------------------------------------------
itcl::body DebugWin::_source_all {} {
  foreach f [glob [file join $::GDBTK_LIBRARY *.itb]] {
    source $f
  }
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::_clear
#
# SYNOPSIS:	_clear
#	
# DESC:		Clears out the content of the debug window.
# -----------------------------------------------------------------------------
itcl::body DebugWin::_clear {} {
  $_t delete 1.0 end
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::_mark_old
#
# SYNOPSIS:	_mark_old
#	
# DESC:		Changes the background of the current contents of the window.
# -----------------------------------------------------------------------------
itcl::body DebugWin::_mark_old {} {
  $_t tag add marked 1.0 "end - 1c"
}

# -----------------------------------------------------------------------------
# NAME:		DebugWin::_save_contents
#
# SYNOPSIS:	_save_contents
#	
# DESC:		Changes the background of the current contents of the window.
# -----------------------------------------------------------------------------
itcl::body DebugWin::_save_contents {} {
  set file [tk_getSaveFile -title "Choose debug window dump file" \
	      -parent [winfo toplevel $itk_interior]]
  if {$file == ""} {
    return
  }

  if {[catch {::open $file w} fileH]} {
    tk_messageBox -type ok -icon error -message \
      "Can't open file: \"$file\". \n\nThe error was:\n\n\"$fileH\""
    return
  }
  ::puts $fileH [$_t get 1.0 end]

}

###############################################################################
# -----------------------------------------------------------------------------
# NAME:		DebugWinDOpts::constructor
#
# SYNOPSIS:	constructor
#	
# DESC:		Creates the Debug Window Options Dialog.
# -----------------------------------------------------------------------------
itcl::body DebugWinDOpts::constructor {args} {
    window_name "Debug Window Options"
    build_win
    eval itk_initialize $args 
}

###############################################################################
# -----------------------------------------------------------------------------
# NAME:		DebugWinDOpts::destructor
#
# SYNOPSIS:	Not called by hand
#	
# DESC:		Destroys the Debug Window Options Dialog.
# -----------------------------------------------------------------------------
itcl::body DebugWinDOpts::destructor {} {
}


# -----------------------------------------------------------------------------
# NAME:		DebugWinDOpts::build_win
#
# SYNOPSIS:	build_win
#	
# DESC:		Creates the Debug Window Options Dialog. This dialog allows the
#		user to select which information is displayed in the debug 
#		window and (eventually) how it looks.
# -----------------------------------------------------------------------------
itcl::body DebugWinDOpts::build_win {} {
  wm title [winfo toplevel $itk_interior] "Debug Display Options"
  # initialize here so we can resource this file and update the list
  set _classes {DebugWin RegWin SrcBar SrcWin ToolBar WatchWin EmbeddedWin \
		  ManagedWin GDBWin StackWin SrcTextWin global \
		  BpWin TargetSelection ModalDialog ProcessWin \
		  GDBEventHandler MemWin VarTree}
  set _classes [concat [lsort $_classes] others]

  set f [frame $itk_interior.f]
  set btns [frame $itk_interior.buttons]

  iwidgets::Labeledframe $f.display -labelpos nw -labeltext {Classes}
  set fr [$f.display childsite]
  radiobutton $fr.0 -text "Messages from ALL classes EXCEPT those selected below" \
    -variable ::gdbtk_de(filter_var) -value ALL -command [code $this _all]
  radiobutton $fr.1 -text "Messages from ONLY those classes selected below" \
    -variable ::gdbtk_de(filter_var) -value ONLY -command [code $this _all]
  radiobutton $fr.2 -text "Only WARNINGS and ERRORS" \
    -variable ::gdbtk_de(filter_var) -value ERRORS -command [code $this _all]

  grid $fr.0 -sticky w -padx 5 -pady 5
  grid $fr.1 -sticky w -padx 5 -pady 5
  grid $fr.2 -sticky w -padx 5 -pady 5

  iwidgets::Labeledframe $f.classes 
  set fr [$f.classes childsite]

  set i 0
  foreach cls $_classes {
    if {![info exists ::gdbtk_de($cls)]} {
      set ::gdbtk_de($cls) 0
    }
    checkbutton $fr.$i -text $cls -variable ::gdbtk_de($cls)
    incr i
  }

  set k [expr 3*(int($i/3))]
  set more [expr $i - $k]
  set j 0
  while {$j < $k} {
    grid $fr.$j $fr.[expr $j+1] $fr.[expr $j+2] -sticky w -padx 5 -pady 5
    incr j 3
  }
  switch $more {
    1 { grid $fr.$j x x -sticky w -padx 5 -pady 5}
    2 { grid $fr.$j $fr.[expr $j+1] x -sticky w -padx 5 -pady 5}
  }

  pack $f.display -side top -expand 1 -fill both
  pack $f.classes -side top -expand 1 -fill both

  button $btns.ok -text [gettext OK] -width 7 -command [code $this _apply 1] \
    -default active
  button $btns.apply -text "Apply to All"  -width 7 \
    -command [code $this _apply 0]
  if {$::debug::logfile == "" || $::debug::logfile == "stdout"} {
    $btns.apply configure -state disabled
  }
  button $btns.help -text [gettext Help] -width 10 -command [code $this help] \
    -state disabled
  standard_button_box $btns
  bind $btns.ok <Return> "$btns.ok flash; $btns.ok invoke"
  bind $btns.apply <Return> "$btns.apply flash; $btns.apply invoke"
  bind $btns.help <Return> "$btns.help flash; $btns.help invoke"
  
  pack $btns $f -side bottom -expand 1 -fill both -anchor e
  focus $btns.ok
}

# -----------------------------------------------------------------------------
# NAME:		DebugWinDOpts::_all
#
# SYNOPSIS:	_all
#	
# DESC:		Callback for selecting ALL classes. If the user selects ALL,
#		deselect all the individual class checkbuttons.
# -----------------------------------------------------------------------------
itcl::body DebugWinDOpts::_all {} {
  switch $::gdbtk_de(filter_var) {
    ALL {
      set ::gdbtk_de(ALL) 1
      set ::gdbtk_de(ERRORS_ONLY) 0
      #enable class buttons
      set num 0
      foreach class $_classes {
	[$itk_interior.f.classes childsite].$num configure -state normal
	incr num
      }
    }
    ONLY {
      set ::gdbtk_de(ALL) 0
      set ::gdbtk_de(ERRORS_ONLY) 0
      #enable class buttons
      set num 0
      foreach class $_classes {
	[$itk_interior.f.classes childsite].$num configure -state normal
	incr num
      }
    }
    ERRORS {
      set ::gdbtk_de(ALL) 0
      set ::gdbtk_de(ERRORS_ONLY) 1
      # disable class buttons
      set num 0
      foreach class $_classes {
	[$itk_interior.f.classes childsite].$num configure -state disabled
	incr num
      }
    }
  }
}


# -----------------------------------------------------------------------------
# NAME:		DebugWinDOpts::_apply
#
# SYNOPSIS:	_apply
#	
# DESC:		Callback for the "Apply" button. Loads the contents of the
#		log file through the new filter into the debug window. The
#		button is disabled if there is no log file.
# -----------------------------------------------------------------------------
itcl::body DebugWinDOpts::_apply { done } {
  set dw [ManagedWin::find DebugWin]
  debug $dw
  if {$dw != ""} {
    $dw loadlog
  }
  if {$done} {
    delete object $this
  }
}