1#! /bin/sh 2# \ 3 exec wish $0 ${1+"$@"} 4 5# BEGIN LICENSE BLOCK 6# Version: CMPL 1.1 7# 8# The contents of this file are subject to the Cisco-style Mozilla Public 9# License Version 1.1 (the "License"); you may not use this file except 10# in compliance with the License. You may obtain a copy of the License 11# at www.eclipse-clp.org/license. 12# 13# Software distributed under the License is distributed on an "AS IS" 14# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 15# the License for the specific language governing rights and limitations 16# under the License. 17# 18# The Original Code is The ECLiPSe Constraint Logic Programming System. 19# The Initial Developer of the Original Code is Cisco Systems, Inc. 20# Portions created by the Initial Developer are 21# Copyright (C) 1999 - 2006 Cisco Systems, Inc. All Rights Reserved. 22# 23# Contributor(s): 24# 25# END LICENSE BLOCK 26# 27# ECLiPSe Development Tools in Tcl 28# 29# 30# $Id: eclipse_tools.tcl,v 1.43 2015/01/14 01:31:10 jschimpf Exp $ 31# 32# Code in this file must only rely on primitives in eclipse.tcl. 33# Don't assume these tools to be embedded into a particular 34# application (like the tkeclipse toplevel)! 35# 36# All tools in this package has .ec_tools as the root frame. New 37# tools should be added under .ec_tools, and the code should be 38# placed after the creation and initialisation of the widget defaults 39 40#---------------------------------------------------------------------- 41# Find and load the eclipse package 42# Also determines font preferences 43#---------------------------------------------------------------------- 44 45package provide eclipse_tools 1.0 46 47set tkecl(version) 6.2 ;# update also in tkeclipse and examples! 48# including mapdebugdemo.tcl in <ECLiPSe>/document/tutorial/mapdebugdemo.tcl 49 50 51switch $tcl_platform(platform) { 52 unix { 53 set tkecl(ECLIPSEDIR) $env(ECLIPSEDIR) 54 lappend tkecl(preferences) \ 55 {monofont_family fixed font tkeclipsetoolsrc \ 56 "Font used for monospaced font (Tk font family)"} \ 57 {monofont_size "" fontsize tkeclipsetoolsrc \ 58 "Font size used for monospace font in points (+ integer)" } \ 59 {labelfont_family helvetica font tkeclipsetoolsrc \ 60 "Font used for labels (Tk font family)"} \ 61 {labelfont_size "" fontsize tkeclipsetoolsrc \ 62 "Font size used for labels in points (+ integer)" } 63 } 64 windows { 65 # For Windows 64 bit, the 64 bit version of Tcl must be run to 66 # access the correct (i.e. 64 bit) set of registry entries! 67 package require registry 68 set tkecl(ECLIPSEDIR) [registry get \ 69 HKEY_LOCAL_MACHINE\\SOFTWARE\\IC-Parc\\Eclipse\\$tkecl(version) ECLIPSEDIR] 70 # fixed does not alias to a mono-spaced font in Windows! 71 set tkecl(windows_registry_path) HKEY_CURRENT_USER\\Software\\IC-Parc\\ECLiPSe\\ 72 lappend tkecl(preferences) \ 73 {monofont_family courier font tkeclipsetoolsrc \ 74 "Font used for monospaced font (Tk font family)"} \ 75 {monofont_size 8 fontsize tkeclipsetoolsrc \ 76 "Font size used for monospace font in points (+ integer)" } \ 77 {labelfont_family helvetica font tkeclipsetoolsrc \ 78 "Font used for labels (Tk font family)"} \ 79 {labelfont_size 8 fontsize tkeclipsetoolsrc \ 80 "Font size used for labels in points (+ integer)"} 81 } 82 default { 83 error "$tcl_platform(platform) not supported" 84 exit 85 } 86} 87 88lappend auto_path [file join $tkecl(ECLIPSEDIR) lib_tcl] 89 90 91#---------------------------------------------------------------------- 92# Setup the defaults for preferences and set them to the defaults 93# Note fonts preferences have already been set 94#---------------------------------------------------------------------- 95 96set tkecl(pref,editor) "" 97if [info exists env(VISUAL)] { set tkecl(pref,editor) $env(VISUAL) } 98if {$tkecl(pref,editor) == ""} { 99 if [catch {set pf $env(PROGRAMFILES)}] { set pf "C:\\Program Files" } 100 if [file exists "$pf\\Windows NT\\Accessories\\wordpad.exe"] { 101 set tkecl(pref,editor) "$pf\\Windows NT\\Accessories\\wordpad.exe" 102 } elseif [file exists "$pf\\Accessories\\wordpad.exe"] { 103 set tkecl(pref,editor) "$pf\\Accessories\\wordpad.exe" 104 } 105} 106 107switch -glob $tkecl(pref,editor) { 108 *emacs - 109 *emacs.* - 110 *vile { 111 set tkecl(pref,edit_line_option) "+" 112 } 113 *notepad++ { 114 set tkecl(pref,edit_line_option) "-n" 115 } 116 default { 117 set tkecl(pref,edit_line_option) "" 118 } 119} 120 121# the preferences are defined in tkecl(preferences), which is a list of the 122# preferences and information on them. To add a preference, append the 123# following list of information for the perference to the the variable: 124# {<name> <default value> <type> <family> <description>} 125# 126# <name> Name of the preference parameter. 127# <default value> The system default value for the parameter. 128# <type> Type of the parameter. This will determine how the 129# initialisation routines and preference editor will 130# handle the parameter. 131# <family> The family the parameter belongs to. Currently 132# either tkeclipsetoolsrc or tkeclipserc. The 133# preference values for the family will be stored in 134# a file named .<family> in Unix, or with <family> 135# being the last path of the registry path. 136# <description> This is the description that will be displayed 137# with the parameter in the editor 138# 139# A corresponding variable tkecl(pref,<name>) will be created for each 140# parameter in the development tools, storing its current value. The 141# variable need to be created for the other families. 142 143lappend tkecl(preferences) \ 144 {background_colour "" colour tkeclipsetoolsrc \ 145 "Default background colour for widgets (colour)" } \ 146 {defaultextension .ecl string tkeclipsetoolsrc \ 147 "Default extension for file browser (string)"} \ 148 {stats_interval 1 stats_interval tkeclipsetoolsrc \ 149 "Interval for updating statistics tool (+ float)"} \ 150 {text_truncate 2000 +integer tkeclipsetoolsrc \ 151 "Threshold length for truncation of text lines (+ int)" } \ 152 {tracer_prdepth 5 tracer_prdepth tkeclipsetoolsrc \ 153 "Print depth used by tracer tool (+ int)"} \ 154 {balloonhelp 1 boolean tkeclipsetoolsrc \ 155 "Balloon help"} \ 156 {trace_source 1 boolean tkeclipsetoolsrc \ 157 "Show source while tracing"} \ 158 {trace_refresh_dg 1 boolean tkeclipsetoolsrc \ 159 "Refresh delayed goals display at every trace line"} \ 160 {trace_refresh_stack 0 boolean tkeclipsetoolsrc \ 161 "Refresh tracer stack display at every trace line"} \ 162 {trace_raise_tracer 1 boolean tkeclipsetoolsrc \ 163 "Raise tracer window at every trace line"} \ 164 {dgf_spiedonly 0 boolean tkeclipsetoolsrc \ 165 "Show spied goals in delayed goals tool"} \ 166 {dgf_tracedonly 1 boolean tkeclipsetoolsrc \ 167 "Show traced goals in delayed goals tool"} \ 168 {dgf_wakeonly 0 boolean tkeclipsetoolsrc \ 169 "Show scheduled goals in delayed goals tool"} \ 170 {inspect_prdepth 5 +integer tkeclipsetoolsrc \ 171 "Print depth for inspector tool"} \ 172 {inspect_ldepth 20 +integer tkeclipsetoolsrc \ 173 "List depth for inspector tool"} \ 174 {inspect_nosymbols 1 boolean tkeclipsetoolsrc \ 175 "Display symbols for inspector tool"} \ 176 [list editor $tkecl(pref,editor) string tkeclipsetoolsrc {Text editor to use (command)}] \ 177 [list edit_line_option $tkecl(pref,edit_line_option) string tkeclipsetoolsrc \ 178 "Editor's command line option to start at a specific line"] 179 180# use procedure to avoid creating extra global variables 181proc tkecl:set_initial_prefs {} { 182 global tkecl 183 184 foreach preference $tkecl(preferences) { 185 foreach {option default type family help} $preference { 186 set tkecl(pref,$option) $default 187 } 188 } 189} 190 191tkecl:set_initial_prefs 192 193#---------------------------------------------------------------------- 194# Load packages and initialise global settings 195#---------------------------------------------------------------------- 196 197package require AllWidgets 198package require tkinspect 199package require eclipse_peer_multitask 200 201balloonhelp enable . 202balloonhelp delay 1000 203 204# other global variables 205 206set tkecl(last_source_file) {} 207 208set tkecl(filetypes) { 209 {{ECLiPSe Files} {.ecl .pl}} 210 {{ECLiPSe specific Files} {.ecl}} 211 {{Prolog Files} {.pl}} 212 {{ECLiPSe Precompiled Files} {.eco}} 213 {{All Files} {*}} 214} 215 216#-------------------------------------------- 217# setting tk-based preferences/defaults 218#------------------------------------------- 219 220# don't set size, use default instead; tk seems to have a bug with size 12 221# fonts are created here; their settings can be changed later to the user 222# defaults 223font create tkeclmono -family $tkecl(pref,monofont_family) 224font create tkeclmonobold -family $tkecl(pref,monofont_family) -weight bold 225font create tkecllabel -family $tkecl(pref,labelfont_family) -weight bold 226 227if ![regexp "^\[ \t]*$" $tkecl(pref,background_colour)] { 228 tk_setPalette background $tkecl(pref,background_colour) 229} 230 231# this sets the Tk defaults for widgets that has $root as a parent. This 232# should be called before any widgets of root are created! 233proc tkecl:set_tkecl_tkdefaults {root} { 234 option add *$root*font tkecllabel userDefault ;# the default 235 option add *$root*Text.font tkeclmono 236 option add *$root*Entry.font tkeclmono 237 option add *$root*Hierarchy.font tkeclmono 238 option add *$root*Text.font tkeclmono 239} 240 241tkecl:set_tkecl_tkdefaults ec_tools 242 243frame .ec_tools ;# dummy toplevel frame for all eclipse tools 244 245#---------------------------------------------------------------------- 246# Testing code 247#---------------------------------------------------------------------- 248 249proc tkecl:test {} { 250 ec_rpcq_check {exit_block abort} (()) 251} 252 253proc tkecl:rpc {} { 254 global tkecl 255 256 set ec_rpc .ec_tools.ec_rpc 257 if ![winfo exists $ec_rpc] { 258 toplevel $ec_rpc 259 wm title $ec_rpc "ECLiPSe Simple Query" 260 pack [label $ec_rpc.entrylabel -justify left -text "Enter a goal in ECLiPSe syntax:"] -fill x 261 pack [entry $ec_rpc.entry -bg white -textvariable tkecl(rpc_goal)] \ 262 -fill x 263 pack [label $ec_rpc.textlabel -text "Reply:"] -fill x 264 pack [text $ec_rpc.text -bg white -height 8] -expand 1 -fill both 265 bind $ec_rpc.entry <Return> tkecl:run_rpc 266 button $ec_rpc.run -text "Run (once)" -command tkecl:run_rpc 267 button $ec_rpc.close -text Close -command "destroy $ec_rpc" 268 pack $ec_rpc.run $ec_rpc.close -side left -expand 1 -fill x 269 focus $ec_rpc.entry 270 balloonhelp $ec_rpc.run "Execute an ECLiPSe goal once at a new break level." 271 bind $ec_rpc <Alt-h> "tkecl:Get_helpfileinfo rpc $ec_rpc" 272 } else { 273 tkinspect:RaiseWindow $ec_rpc 274 } 275} 276 277proc tkecl:run_rpc {} { 278 global tkecl 279 .ec_tools.ec_rpc.text insert end [ec_rpc $tkecl(rpc_goal)] 280 .ec_tools.ec_rpc.text insert end "\n" 281 .ec_tools.ec_rpc.text see end 282} 283 284proc ec_rpc_check {goal {format S}} { 285 set result [ec_rpc $goal $format] 286 switch $result { 287 fail { 288 tk_messageBox -type ok -message "ECLiPSe goal failed: $goal" 289 } 290 throw { 291 tk_messageBox -type ok -message "ECLiPSe goal aborted: $goal" 292 } 293 } 294 return $result 295} 296 297# Call a module-qualified (default:eclipse_language) predicate. 298# Return fail, throw, or module-less goal term on success. 299proc ec_rpcq {goal exdr_type {module eclipse_language}} { 300# .tkecl.pane.stdio.tout insert end "qcall $goal\n" 301 set result [ec_rpc [list : $module $goal] (()$exdr_type)] 302# .tkecl.pane.stdio.tout insert end "qexit $result\n" 303 update 304 switch $result { 305 fail - 306 throw {return $result} 307 } 308 lindex $result 2 309} 310 311# Like ec_rpcq, but message on fail/throw 312proc ec_rpcq_check {goal exdr_type {module eclipse_language}} { 313# .tkecl.pane.stdio.tout insert end "ccall $goal\n" 314 set result [ec_rpc [list : $module $goal] (()$exdr_type)] 315# .tkecl.pane.stdio.tout insert end "cexit $result\n" 316 update 317 switch $result { 318 fail { 319 tk_messageBox -type ok -message "ECLiPSe goal failed: $goal" 320 return $result 321 } 322 throw { 323 tk_messageBox -type ok -message "ECLiPSe goal aborted: $goal" 324 return $result 325 } 326 } 327 lindex $result 2 328} 329 330# Call a goal with given context-module (and optional lookup-module) 331# Return fail, throw, or module-less goal term on success. 332# We call lm:(lm:goal@cm) because @/2 may not be visible (ISO). 333proc ec_rpcatq {goal exdr_type at_module {module eclipse_language} } { 334# .tkecl.pane.stdio.tout insert end "atqcall $goal\n" 335 set result [ec_rpc [list : $module [list @ [list : $module $goal] $at_module]]\ 336 (()((()$exdr_type)())) ] 337# .tkecl.pane.stdio.tout insert end "atqexit $result\n" 338 switch $result { 339 fail - 340 throw {return $result} 341 } 342 lindex $result 2 1 2 343} 344 345 346#---------------------------------------------------------------------- 347# Library browser and help tool 348#---------------------------------------------------------------------- 349 350proc tkecl:library_browser {} { 351 global tkecl 352 353 set lb .ec_tools.ec_libbrowse 354 set tkecl(lbloadtext) "No library selected" 355 set tkecl(lbmodule) "" 356 if ![winfo exists $lb] { 357 toplevel $lb 358 ec_rpcq init_library_info () tracer_tcl 359 set htmldoc [lindex [ec_rpcq {return_html_root _} (_) tracer_tcl] 1] 360 wm title $lb "ECLiPSe Library Browser and Help" 361 362 set htmlinfo [text $lb.ref -relief groove -borderwidth 3 -height 3 ] 363 364 bind $htmlinfo <Any-Key> "tkecl:readonly_keypress %A" 365 bind $htmlinfo <ButtonRelease-2> {break} ;# disable paste 366 $htmlinfo tag configure highlight -justify center -font tkecllabel 367 $htmlinfo insert end "To obtain more information on ECLiPSe, point your browser at:\n$htmldoc" highlight 368 369 set close [button $lb.close -text "Close" -command "destroy $lb"] 370 371 set top [frame $lb.top -width 700 -height 500] 372 set treeframe [frame $top.tframe] 373 374 set tree [hierarchy $treeframe.tree -browsecmd tkecl:lb_getchildren \ 375 -nodelook tkecl:lbnode_look -expand 2 -selectmode single \ 376 -selectcmd tkecl:lbnode_info \ 377 -background white -selectbackground gray -root top \ 378 -paddepth 20 -padstack 3] 379 380 set loadsel [button $treeframe.load -textvariable tkecl(lbloadtext) \ 381 -state disabled -command "tkecl:lb_load_module $tree"] 382 383 set tf [frame $top.tf] 384 set tlabel [label $tf.label -justify left -text \ 385 "Type in a string to match, or predicate_name/arity:"] 386 387 set tinput [entry $tf.input -bg white -width 86 \ 388 -textvariable tkecl(help_input)] 389 390 set t [text $tf.t -setgrid true -relief sunken \ 391 -background white -width 86 \ 392 -yscrollcommand "$tf.y set" -xscrollcommand "$tf.x set"] 393 394 bind $tinput <Return> "tkecl:display_help $tinput $t" 395 396 bind $t <Any-Key> "tkecl:readonly_keypress %A" ;# read only 397 bind $t <ButtonRelease-2> {break} ;# disable paste 398 bind $t <Button-1> "tkecl:lb_insert_input $tinput $t" 399 bind $t <Double-Button-1> "tkecl:display_help $tinput $t; break" 400 401 $t configure -cursor left_ptr 402 $t tag configure highlight -foreground blue -wrap none 403 $t tag configure normal -lmargin2 0 -wrap none 404 $t tag configure heading -underline 1 -spacing1 5 -spacing3 5 405 406 407 pack $close -side bottom -fill x -expand true 408 pack $htmlinfo -side bottom -fill x -expand true 409 pack $top -side top -fill both -expand true 410 pane $treeframe $tf -orient horizontal -initfrac [list 0.4 0.6] 411 pack $loadsel -side top -fill x 412 pack $tree -side bottom -expand 1 -fill both 413 414 pack $tlabel -side top -fill x 415 pack $tinput -side top -fill x 416 scrollbar $tf.y -orient vert -command "$t yview" 417 pack $tf.y -side right -fill y 418 scrollbar $tf.x -orient hori -command "$t xview" 419 pack $tf.x -side bottom -fill x 420 pack $t -side right -fill both -expand true 421 422 ;#pack $treeframe -expand true -fill both -side left 423 ;#pack $tf -expand true -fill both -side right 424 425 bind $lb <Alt-h> "tkecl:Get_helpfileinfo help $lb" 426 focus $tinput 427 428 429 balloonhelp $t "Help Information Window: displays description of ECLiPSe libraries or predicates\n selected from either the tree display or the entry window.\nSelect item from tree display to obtain short description here,\n or type in entry window for longer description of predicates.\nLeft click on any word to put it in entry\nDouble left-click to look word up directly" 430 balloonhelp $tinput "Entry window: enter a string to match built-in predicates, or Name/Arity for exact match." 431 balloonhelp $tree "Hierarchical tree display of available libraries and their exported interface.\nLibraries in blue are currently loaded, green are unloaded libraries.\n Left-click to select an item; Double left-click to expand and item;\n select an expanded item to display more information in information window." 432 balloonhelp $loadsel "This shows the currently selected library (if any) of the tree display.\nClick the load button to load the library." 433 balloonhelp $htmlinfo "On-line webpages of the ECLiPSe manual should be available at this URL.\nCopy it to a browser to view." 434 balloonhelp $close "Close this window." 435 436 } else { 437 tkinspect:RaiseWindow $lb 438 } 439} 440 441 442proc tkecl:lb_insert_input {tinput t} { 443 $tinput delete 0 end 444 $tinput insert end [$t get "current wordstart" "current wordend"] 445} 446 447proc tkecl:lb_load_module {tree} { 448 global tkecl 449 450 if {$tkecl(lbmodule) != ""} { 451 ec_rpcq_check [list lbnode_loadmodule $tkecl(lbmodule)] (()) tracer_tcl 452 $tree refresh 453 } 454} 455 456proc tkecl:lb_getchildren {tree path} { 457 return [lindex [ec_rpcq\ 458 [list expand_lbnode $path _] {([S*]_)} tracer_tcl] 2] 459 460} 461 462proc tkecl:lbnode_look {tree path isopen} { 463 foreach {pred in nodetext highlight isopen} \ 464 [ec_rpcq [list lbnode_display $path _ _] {([S*]__)} tracer_tcl] { 465 switch -exact -- $highlight { 466 highlight { 467 set colour #00b000 468 } 469 current { 470 set colour blue 471 } 472 none { 473 set colour black 474 } 475 } 476 } 477 return [list $nodetext {} {} $colour] 478} 479 480proc tkecl:lbnode_info {t selected prevsel} { 481 global tkecl 482 483 set lb .ec_tools.ec_libbrowse 484 $t centreitem $selected 0.1 0.9 0.0 1.0 485 set path [lindex [$t get $selected] 0] 486 set isopen [$t isopen $path] 487 foreach {infoitems tkecl(lbmodule)} [lrange \ 488 [ec_rpcq [list lbnode_info $path $isopen _ _] {([S*]I__)} tracer_tcl]\ 489 3 4] {break} 490 if {$tkecl(lbmodule) != ""} { 491 set toplevel [lindex [ec_rpcq {get_flag toplevel_module _} (()_)] 2] 492 set tkecl(lbloadtext) "load $tkecl(lbmodule) library into module $toplevel" 493 $lb.top.tframe.load configure -state normal 494 } else { 495 set tkecl(lbloadtext) "No library selected" 496 $lb.top.tframe.load configure -state disabled 497 } 498 499 $lb.top.tf.t tag remove highlight 1.0 end 500 501 foreach item $infoitems { 502 503 foreach {format text} $item { 504 break 505 } 506 $lb.top.tf.t insert end $text [list $format highlight] 507 $lb.top.tf.t insert end "\n" 508 } 509 if {$infoitems != ""} { 510 ;# only insert newline if there are some infoitems 511 $lb.top.tf.t insert end "\n" 512 $lb.top.tf.t see end 513 } 514} 515 516proc tkecl:display_help {input text} { 517 global tkecl 518 $input selection range 0 end 519 $text tag remove highlight 1.0 end 520 $text configure -cursor watch ; update idletasks 521 $text insert end [lindex [ec_rpcq\ 522 [list gui_help_string $tkecl(help_input) _] (S_) tracer_tcl] 2]\ 523 highlight 524 $text see end 525 $text configure -cursor left_ptr 526 527} 528 529 530#---------------------------------------------------------------------- 531# Predicate properties window 532#---------------------------------------------------------------------- 533 534set tkecl(predproppred) "" 535set tkecl(predpropmodule) "" 536 537proc tkecl:combo_add_modules {w} { 538 foreach item [tkecl:list_modules] { 539 $w add $item 540 } 541} 542 543proc tkecl:list_modules {} { 544 # use string because of shared variable 545 # fullstop at end in case we are in strict_iso context 546 lindex [ec_rpc_check {eclipse_language:setof(X,eclipse_language:current_module(X),L).}] 2 3 547} 548 549proc tkecl:popup_pred_prop {} { 550 global tkecl 551 552 set predprop .ec_tools.predprop 553 if ![winfo exists $predprop] { 554 toplevel $predprop 555 wm title $predprop "ECLiPSe Predicate Browser" 556 557 set tkecl(predpropwhich) defined 558 set tkecl(predpropauxfilter) 1 559 frame $predprop.f1 -relief raised -bd 1 560 combobox $predprop.which -click single \ 561 -list {defined exported imported local visible} \ 562 -listheight 5 \ 563 -labeltext "Predicates " \ 564 -textvariable tkecl(predpropwhich) -editable 0 \ 565 -command tkecl:display_predicates 566 pack $predprop.which -in $predprop.f1 -side left -expand 1 -fill x 567 568 pack [checkbutton $predprop.filter -text "filter aux." \ 569 -variable tkecl(predpropauxfilter) \ 570 -command {tkecl:display_predicates dummy} \ 571 ] -in $predprop.f1 -side right -expand 1 -fill x 572 573 set modules [tkecl:list_modules] 574 combobox $predprop.modules -list $modules -click single \ 575 -labeltext " in module: " \ 576 -listheight 6 \ 577 -textvariable tkecl(predpropmodule) -editable 0 \ 578 -command tkecl:display_predicates 579 pack $predprop.modules -in $predprop.f1 -side left -expand 1 -fill x 580 581 listbox $predprop.preds -width 20 \ 582 -yscrollcommand "$predprop.vscroll set" 583 scrollbar $predprop.vscroll -command "$predprop.preds yview" 584 bind $predprop.preds <<ListboxSelect>> {+tkecl:display_predprops .ec_tools.predprop.preds} 585 586 bind $predprop.preds <Enter> "tkecl:listbox_search_init $predprop.preds" 587 bind $predprop.preds <Leave> "tkecl:listbox_search_exit $predprop.preds" 588 bind $predprop.preds <Control-KeyPress> {continue} 589 bind $predprop.preds <Control-Key-s> "tkecl:listbox_search $predprop.preds %A Control_S %X %Y" 590 bind $predprop.preds <KeyPress> "tkecl:listbox_search $predprop.preds %A %K %X %Y" 591 592 button $predprop.close -text Close -command "destroy $predprop" 593 594 frame $predprop.f2 -relief groove -bd 1 595 pack [label $predprop.predlabel -text "Properties of Predicate:"] -in $predprop.f2 -side top -fill x 596 pack [label $predprop.predname -relief sunken] -in $predprop.f2 -side top -fill x 597 tkecl:add_rb $predprop.f2 disabled auxiliary {off on} 598 tkecl:add_rb $predprop.f2 disabled defined {off on} 599 tkecl:add_rb $predprop.f2 disabled debugged {off on} 600 tkecl:add_rb $predprop.f2 disabled stability {static dynamic} 601 tkecl:add_rb $predprop.f2 disabled call_type {prolog external} 602 tkecl:add_rb $predprop.f2 disabled type {built_in user} 603 tkecl:add_rb $predprop.f2 disabled tool {off on} 604# tkecl:add_rb $predprop.f2 disabled visibility {local imported exported global} 605 tkecl:add_rb $predprop.f2 disabled demon {off on} 606 tkecl:add_rb $predprop.f2 disabled parallel {off on} 607# tkecl:add_rb $predprop.f2 disabled statistics {off on} 608 tkecl:add_rb $predprop.f2 active leash {stop notrace} 609 tkecl:add_rb $predprop.f2 active skip {off on} 610 tkecl:add_rb $predprop.f2 active start_tracing {off on} 611 tkecl:add_rb $predprop.f2 active spy {off on} 612 613 button $predprop.f2.show -text "Show source" -command tkecl:display_source 614 pack $predprop.f2.show -side top -fill x 615 616 pack $predprop.f1 -side top -expand 1 -fill x 617 pack $predprop.preds -side left -expand 1 -fill both 618 pack $predprop.vscroll -side left -fill y 619 pack $predprop.f2 -side top -expand 1 -fill x -padx 3 -pady 3 -ipadx 3 -ipady 3 620 pack $predprop.close -side top -fill x 621 622 balloonhelp $predprop.preds "Predicates list - select one to view its \ 623 properties\n (see manual for details on properties)\n\ 624 Typing in this window will search for matching predicate.\n\ 625 Type escape to stop search, or Control-S to find next." 626 balloonhelp $predprop.which "Type of predicates listed in predicates list.\n\ 627 click arrow on right to change type" 628 balloonhelp $predprop.modules "Module of predicates listed in predicates list.\n\ 629 click arrow on right to change module" 630 balloonhelp $predprop.predname "Name, operator and mode information for predicate if known" 631 bind $predprop <Alt-h> "tkecl:Get_helpfileinfo pred $predprop" 632 tkecl:display_predicates dummy 633 } else { 634 tkinspect:RaiseWindow $predprop 635 } 636 637} 638 639proc tkecl:display_predicates {dummy} { 640 global tkecl 641 642 set predprop .ec_tools.predprop 643 $predprop.preds delete 0 end 644 set preds [lindex [ec_rpcq_check [list \ 645 list_predicates $tkecl(predpropwhich) $tkecl(predpropmodule) $tkecl(predpropauxfilter) _] \ 646 (()()I_) tracer_tcl] 4] 647 foreach item $preds { 648 $predprop.preds insert end $item 649 } 650} 651 652proc tkecl:add_rb {parent state name values} { 653 global tkecl 654# frame $parent.$name -relief groove -bd 1 655 frame $parent.$name 656 label $parent.$name.label -text $name -anchor w -width 20 657 pack $parent.$name.label -side left 658 foreach val $values { 659 radiobutton $parent.$name.$val -text $val -variable tkecl(pp_$name) \ 660 -value $val -anchor w -state $state -command "tkecl:update_predprop $name" 661 pack $parent.$name.$val -side left 662 } 663 pack $parent.$name -side top -fill x 664} 665 666proc tkecl:update_predprop {name} { 667 global tkecl 668 if {$tkecl(predproppred) != ""} { 669 ;# only update if a predicate has been selected... 670 tkecl:set_pred_flag $tkecl(predproppred) $tkecl(predpropmodule) $name $tkecl(pp_$name) 671 } 672} 673 674proc tkecl:display_predprops {w} { 675 global tkecl 676 677 set selected [$w curselection] 678 if ![string match "" $selected] { 679 set tkecl(predproppred) [$w get $selected] 680 } 681 set home [tkecl:pred_flag_value $tkecl(predproppred) $tkecl(predpropmodule) definition_module] 682 set mode [tkecl:pred_flag_value $tkecl(predproppred) $tkecl(predpropmodule) mode] 683 .ec_tools.predprop.predname configure -text "$home : $mode" 684 foreach name {auxiliary call_type debugged defined leash \ 685 skip spy stability tool type demon parallel statistics start_tracing} { 686 set tkecl(pp_$name) [tkecl:pred_flag_value $tkecl(predproppred) $tkecl(predpropmodule) $name] 687 } 688 if [winfo exists .ec_source] { 689 tkecl:display_source 690 } 691} 692 693proc tkecl:pred_flag_value {pred module name} { 694 set result [ec_rpcq \ 695 [list flag_value $pred $name $module _] (S()()_) tracer_tcl] 696 # rpc can fail, return "" in that case 697 lindex $result 4 698} 699 700proc tkecl:set_pred_flag {pred module name value} { 701 ec_rpcq [list set_flag_string $pred $name $value $module] (S()()()) tracer_tcl 702} 703 704 705#---------------------------------------------------------------------- 706# Predicate source window 707#---------------------------------------------------------------------- 708 709proc tkecl:display_source {} { 710 global tkecl 711 712 if {$tkecl(predproppred) == ""} return 713 714 set res [ec_rpcq [list get_source_info $tkecl(predproppred) $tkecl(predpropmodule) _ _] (S()__) tracer_tcl] 715 switch $res { 716 throw - 717 fail { 718 if [winfo exists .ec_tools.ec_tracer] { 719 set parent .ec_tools.ec_tracer 720 } else { 721 set parent . 722 } 723 tk_messageBox -type ok -parent $parent -icon info -message "No source information found for $tkecl(predproppred) in module $tkecl(predpropmodule)." 724 return 725 } 726 default { 727 set file [lindex [lindex $res 3] 0] ;# atom type (singleton list) 728 set offset [lindex $res 4] 729 } 730 } 731 732 tkecl:popup_tracer 733 if {$tkecl(source_debug,file) != $file} { 734 if {[tkecl:load_source_debug_file $file] == 0} { 735 tk_messageBox -type ok -parent .ec_tools.ec_tracer -icon info -message "Can't load source file $file" 736 return 737 } 738 } 739 740 set ec_tracer .ec_tools.ec_tracer.tab 741 $ec_tracer activate "Source Context" 742 incr offset ;# increment to get pass newline normally at end of last item 743 set idx [$ec_tracer.source.context.text index "1.0 + $offset chars"] 744 $ec_tracer.source.context.text see $idx 745} 746 747 748proc tkecl:set_and_display_source {pred module} { 749 global tkecl 750 set tkecl(predproppred) $pred 751 set tkecl(predpropmodule) $module 752 tkecl:display_source 753} 754 755proc tkecl:display_source_for_callport {t} { 756 global tkecl 757 758 if {$tkecl(source_debug,file) == ""} return 759 set line [tkecl:get_current_text_line $t] 760 # Caution: the predicate expects an atom. For quoting-sensitive arguments 761 # like file names, we have to pass a 1-element list with the () type. 762 set res [ec_rpcq [list find_exact_callinfo [list $tkecl(source_debug,file)] $line _] (()I_) tracer_tcl] 763 764 switch $res { 765 throw - 766 fail { 767 # no port at line, no action 768 return 769 } 770 default { 771 set callport [lindex $res 3] 772 } 773 } 774 set calldefmodule [lindex $callport 1] 775 set callspec [lindex $callport 2] 776 # need to convert spec to a string as that is expected 777 # no modle needed for call as only need '/'/2 to be defined normally 778 set predspecs [lindex [ec_rpcq \ 779 [list term_string $callspec _] ((()I)_)] 2] 780 tkecl:set_and_display_source $predspecs $calldefmodule 781} 782 783#---------------------------------------------------------------------- 784# Global settings window 785#---------------------------------------------------------------------- 786 787proc tkecl:popup_global_state {} { 788 global tkecl 789 790 set gstate .ec_tools.gstate 791 if ![winfo exists $gstate] { 792 toplevel $gstate 793 wm withdraw $gstate 794 wm title $gstate "ECLiPSe Global Settings" 795 796 tkecl:add_radiobutton $gstate after_event_timer "real virtual" 797 tkecl:add_radiobutton $gstate breal_exceptions "off on" 798 tkecl:add_radiobutton $gstate coroutine "off on" 799 tkecl:add_radiobutton $gstate debugging "nodebug creep leap" 800 tkecl:add_radiobutton $gstate debug_compile "off on" 801 tkecl:add_radiobutton $gstate enable_interrupts "off on" 802 tkecl:add_radiobutton $gstate gc "off on verbose" 803 tkecl:add_radiobutton $gstate gc_policy "adaptive fixed" 804 tkecl:add_radiobutton $gstate goal_expansion "off on" 805 tkecl:add_radiobutton $gstate macro_expansion "off on" 806 tkecl:add_radiobutton $gstate prefer_rationals "off on" 807 tkecl:add_radiobutton $gstate variable_names "off on check_singletons" 808 809 tkecl:add_popupentry $gstate output_mode "tkecl:edit_output_mode global" Change {} 810 tkecl:add_entry $gstate gc_interval number I 811 tkecl:add_entry $gstate gc_interval_dict number I 812# tkecl:add_entry $gstate output_mode none S 813 tkecl:add_entry $gstate print_depth number I 814# tkecl:add_entry $gstate cwd none S 815 tkecl:add_popupentry $gstate cwd {tkecl:get_newcwd} Change S 816 tkecl:add_menuentry $gstate library_path tkecl:paths_menu Change S 817 button $gstate.close -text Close -command "destroy $gstate" 818 pack $gstate.close -side top -fill x 819 wm minsize $gstate 380 30 820 wm resizable $gstate 1 0 821 wm deiconify $gstate 822 823 balloonhelp $gstate "ECLiPSe global state - see manual for descriptions of flags" 824 balloonhelp $gstate.library_path "left click in entry to see all paths" 825 bind $gstate <Alt-h> "tkecl:Get_helpfileinfo glob $gstate" 826 } else { 827 tkinspect:RaiseWindow $gstate 828 } 829} 830 831 832proc tkecl:add_radiobutton {parent name values} { 833 global tkecl 834 835 set tkecl($name) [lindex [ec_rpcq_check [list get_flag $name _] (()_)] 2] 836# frame $parent.$name -relief groove -bd 1 837 frame $parent.$name 838 label $parent.$name.label -text $name -anchor w -width 20 839 pack $parent.$name.label -side left 840 foreach val $values { 841 radiobutton $parent.$name.$val -text $val -variable tkecl($name) \ 842 -value $val -anchor w -command "tkecl:set_flag $name ()" 843 pack $parent.$name.$val -side left 844 } 845 pack $parent.$name -side top -fill x 846} 847 848proc tkecl:add_popupentry {parent name command ctext exdr_type} { 849 global tkecl 850 851 set f [frame $parent.$name] 852 pack [label $f.label -text $name -anchor w -width 20] -side left 853 if {$exdr_type == ""} { 854 set info [label $f.val -justify right -relief groove -textvariable tkecl($name)] 855 } else { 856 set info [entry $f.val -bg white -justify right -relief sunken -textvariable tkecl($name)] 857 bind $f.val <Return> "tkecl:set_flag $name $exdr_type" 858 } 859 pack $info -side left -expand 1 -fill x 860# bind $parent.$name.val <Return> "tkecl:set_flag $name S" 861 set tkecl($name) [lindex [ec_rpcq_check [list get_flag $name _] (()_)] 2] 862 pack [button $f.b -anchor e -text $ctext -command $command] -side right 863 pack $f -side top -fill x 864} 865 866proc tkecl:add_menuentry {parent name buildmenu mtext exdr_type} { 867 global tkecl 868 869 set f [frame $parent.$name] 870 pack [label $f.label -text $name -anchor w -width 20] -side left 871 if {$exdr_type == ""} { 872 set info [label $f.val -justify right -relief groove -textvariable tkecl($name)] 873 } else { 874 set info [entry $f.val -bg white -justify right -relief sunken -textvariable tkecl($name)] 875 bind $f.val <Return> "tkecl:set_flag $name $exdr_type" 876 } 877 pack $info -side left -expand 1 -fill x 878# bind $parent.$name.val <Return> "tkecl:set_flag $name S" 879 set tkecl($name) [lindex [ec_rpcq_check [list get_flag $name _] (()_)] 2] 880 pack [menubutton $f.b -text $mtext -menu $f.b.m -relief raised] -side right 881 $buildmenu $f.b $name 882 pack $f -side top -fill x 883} 884 885proc tkecl:add_entry {parent name vtype exdr_type} { 886 global tkecl 887# frame $parent.$name -relief groove -bd 1 888 switch -exact -- $vtype { 889 number { 890 set vstring {regexp {^[0-9]*$} %P} 891 } 892 none { 893 set vstring {regexp {.*} %P} 894 } 895 } 896 frame $parent.$name 897 label $parent.$name.label -text $name -anchor w -width 20 898 set tkecl($name) [lindex [ec_rpcq_check [list get_flag $name _] (()_)] 2] 899 if {$exdr_type != ""} { 900 ventry $parent.$name.val -bg white -justify right -relief sunken -textvariable tkecl($name) -validate key -invalidcmd bell -vcmd $vstring 901 bind $parent.$name.val <Return> "tkecl:set_flag $name $exdr_type" 902 } else { 903 entry $parent.$name.val -relief groove -justify right -textvariable tkecl($name) 904 bind $parent.$name.val <Any-Key> {break} 905 bind $parent.$name.val <Button-2> {break} 906 bind $parent.$name.val <ButtonRelease-2> {break} 907 bind $parent.$name.val <Button-1> {break} 908 } 909 pack $parent.$name.label -side left 910 pack $parent.$name.val -side right -expand 1 -fill x 911 pack $parent.$name -side top -fill x 912} 913 914# Set eclipse flag name from the tcl variable $tkecl(name) 915proc tkecl:set_flag {name exdr_type} { 916 global tkecl 917 ec_rpcq_check [list set_flag $name $tkecl($name)] (()$exdr_type) 918} 919 920 921#---------------------------------------------------------------------- 922# Change output modes and print depth (both global and tracer settings) 923#---------------------------------------------------------------------- 924 925set tkecl(output_mode_spec_nr) 7 926set tkecl(output_mode_spec) { 927 {{Variables} {"" v V _} {"X" "_123" "X_123" "_"}} 928 {{Attributes} {"" m M} {none pretty full}} 929 {{Operators} {"" O} {1+2 +(1,2)}} 930 {{Spaces} {"" K} {"a, b" "a,b"}} 931 {{Quoting} {"" Q} {A 'A'}} 932 {{Lists} {"" .} {{[a,b|_]} {.(a,.(b,_))}}} 933 {{Use portray/1,2 } {"" P} {no yes}} 934 {{Transformations } {T ""} {no yes}} 935} 936# These are almost never used and mostly confusing for the user: 937# {{Treat as clause} {"" C} {no yes}} 938# {{Treat as goal} {"" G} {no yes}} 939 940 941proc tkecl:edit_output_mode {which} { 942 global tkecl 943 set w .ec_tools.ec_om_$which 944 if [winfo exists $w] { 945 tkinspect:RaiseWindow $w 946 return 947 } 948 949 # get the old settings 950 switch -- $which { 951 tracer { 952 set title "Tracer Output Options" 953 set tkecl(prdepth_$which) [lindex [ec_rpcatq\ 954 {getval dbg_print_depth _} (()_) tracer_tcl] 2] 955 set oldmode [lindex [ec_rpcq_check {get_tracer_output_modes _}\ 956 (_) tracer_tcl] 1] 957 } 958 global { 959 set title "Global Output Options" 960 set tkecl(prdepth_$which) [lindex [ec_rpcq_check\ 961 {get_flag print_depth _} (()_) ] 2] 962 set oldmode [lindex [ec_rpcq_check\ 963 {get_flag output_mode _} (()_) ] 2] 964 } 965 } 966 967 toplevel $w 968 wm transient $w . 969 wm title $w $title 970 971 # Make radiobuttons for the different options, linked to 972 # variables tkecl(om_$which0)..tkecl(om_$which$tkecl(output_mode_spec_nr)) 973 frame $w.flags -relief raised -bd 1 974 set row 0 975 foreach descr $tkecl(output_mode_spec) { 976 # set the button variables according to the old mode 977 set tkecl(om_$which$row) "" 978 foreach letter [lindex $descr 1] { 979 set occ [string first $letter $oldmode] 980 if {$occ >= 0} { 981 set oldmode [string replace $oldmode $occ $occ {}] 982 set tkecl(om_$which$row) $letter 983 } 984 } 985 grid [label $w.flags.label$row -text [lindex $descr 0]] -row $row -column 0 -sticky w 986 set rb_name $w.flags.rb$row 987 append rb_name _ 988 set col 1 989 foreach val [lindex $descr 1] what [lindex $descr 2] { 990 grid [radiobutton $rb_name$col -text $what -value $val -variable tkecl(om_$which$row)] \ 991 -row $row -column $col -sticky w 992 incr col 993 } 994 incr row 995 } 996 # Make a scale and a "full"-checkbutton for the print depth 997 label $w.label$row -text "Print depth" 998 scale $w.scale -from 0 -to 100 -orient horizontal \ 999 -tickinterval 10 -length 60m -sliderlength 4m \ 1000 -variable tkecl(prdepth_$which) 1001 set occ [string first "D" $oldmode] 1002 if {$occ >= 0} { 1003 set oldmode [string replace $oldmode $occ $occ {}] 1004 set tkecl(om_fullpd$which) D 1005 } else { 1006 set tkecl(om_fullpd$which) {} 1007 } 1008 checkbutton $w.fulldepth -text full -offvalue {} -onvalue D \ 1009 -variable tkecl(om_fullpd$which) -command "tkecl:toggle_scale om_fullpd$which $w.scale" 1010 1011 frame $w.buttons 1012 pack [button $w.buttons.apply -text Apply -command [list tkecl:apply_output_mode $which $oldmode]] -side left -expand 1 -fill both 1013 pack [button $w.buttons.cancel -text Cancel -command "destroy $w"] -side left -expand 1 -fill both 1014 pack [button $w.buttons.ok -text Ok -command "[list tkecl:apply_output_mode $which $oldmode] ; destroy $w"] -side left -expand 1 -fill both 1015 1016 pack $w.flags -side top -expand 1 -fill both 1017 pack $w.buttons -side bottom -expand 1 -fill both 1018 pack $w.label$row -side left -expand 1 -fill both 1019 pack $w.scale -side left 1020 pack $w.fulldepth -side left 1021} 1022 1023# the scale is only active if the "full" button is not checked 1024proc tkecl:toggle_scale {var scale} { 1025 global tkecl 1026 if [string match "" $tkecl($var)] { 1027 $scale configure -state normal -foreground black 1028 } else { 1029 $scale configure -state disabled -foreground grey 1030 } 1031} 1032 1033proc tkecl:apply_output_mode {which newmode} { 1034 global tkecl 1035 # newmode contains the remainder of oldmode that was ignored by the gui 1036 for {set i 0} {$i <= $tkecl(output_mode_spec_nr)} {incr i} { 1037 append newmode $tkecl(om_$which$i) 1038 } 1039 append newmode $tkecl(om_fullpd$which) 1040 1041 switch -- $which { 1042 tracer { 1043 ec_rpcq_check [list set_tracer_output_modes $newmode] (S) tracer_tcl 1044 ec_rpcq_check [list set_tracer_print_depth $tkecl(prdepth_$which)] (I) tracer_tcl 1045 tkecl:refresh_current_trace_line 1046 } 1047 global { 1048 ec_rpcq_check [list set_flag output_mode $newmode] (()S) 1049 ec_rpcq_check [list set_flag print_depth $tkecl(prdepth_$which)] (()I) 1050 # these two are only for updating the Global Settings window: 1051 set tkecl(output_mode) $newmode 1052 set tkecl(print_depth) $tkecl(prdepth_$which) 1053 } 1054 } 1055} 1056 1057 1058#---------------------------------------------------------------------- 1059# Files window 1060#---------------------------------------------------------------------- 1061 1062proc tkecl:compile_popup {dir} { 1063 1064 set file [tkecl:getEcFile $dir "Compile File"] 1065 1066 if {$file != ""} { 1067 tkecl:compile_file $file 1068 } 1069} 1070 1071proc tkecl:xref_popup {} { 1072 1073 set file [tkecl:getEcFile [pwd] "Xref File"] 1074 1075 if {$file != ""} { 1076 if {[file exists $file] && [file readable $file]} { 1077 set file [lindex [ec_rpcq [list os_file_name _ $file] (_S)] 1] 1078 ec_rpcq [list xref $file [list [list : output graphviz]]] \ 1079 {(S[(()())])} xref 1080 } else { 1081 tk_messageBox -icon error -type ok -message "Cannot access file $file" 1082 } 1083 } 1084} 1085 1086proc tkecl:lint_popup {} { 1087 1088 set file [tkecl:getEcFile [pwd] "Lint File"] 1089 1090 if {$file != ""} { 1091 if {[file exists $file] && [file readable $file]} { 1092 set file [lindex [ec_rpcq [list os_file_name _ $file] (_S)] 1] 1093 ec_rpcq [list lint $file] (S) lint 1094 } else { 1095 tk_messageBox -icon error -type ok -message "Cannot access file $file" 1096 } 1097 } 1098} 1099 1100proc tkecl:compile_file {file {module ""}} { 1101 if {$file != ""} { 1102 if {$module == ""} { 1103 set module [lindex [ec_rpcq_check {get_flag toplevel_module _} (()_) ] 2] 1104 } 1105 if {[file exists $file] && [file readable $file]} { 1106 ec_rpcq [list compile_os_file $file $module] (S()) tracer_tcl 1107 } else { 1108 tk_messageBox -icon error -type ok -message "Cannot access file $file" 1109 } 1110 tkecl:refresh_file_window 1111 } 1112} 1113 1114proc tkecl:use_module_popup {} { 1115 1116 set file [tkecl:getEcFile [pwd] "Use Module"] 1117 1118 if {$file != ""} { 1119 tkecl:use_module $file 1120 } 1121} 1122 1123proc tkecl:use_module {file {module ""}} { 1124 if {$file != ""} { 1125 if {$module == ""} { 1126 set module [lindex [ec_rpcq_check {get_flag toplevel_module _} (()_) ] 2] 1127 } 1128 if {[file exists $file] && [file readable $file]} { 1129 ec_rpcq [list use_module_os $file $module] (S()) tracer_tcl 1130 } else { 1131 tk_messageBox -icon error -type ok -message "Cannot access file $file" 1132 } 1133 tkecl:refresh_file_window 1134 } 1135} 1136 1137proc tkecl:edit_popup {} { 1138 1139 set file [tkecl:getEcFile [pwd] "Edit File"] 1140 1141 if {$file != ""} { 1142 tkecl:edit_file $file 1143 tkecl:add_source_file $file 1144 } 1145} 1146 1147proc tkecl:edit_new_popup {} { 1148 1149 set file [tkecl:getNewEcFile [pwd] "New Source File"] 1150 1151 if {$file != ""} { 1152 tkecl:edit_file $file 1153 tkecl:add_source_file $file 1154 } 1155} 1156 1157proc tkecl:edit_file {file {line -1}} { 1158 global tkecl 1159 1160 if {$tkecl(pref,editor) == ""} { 1161 tk_messageBox -icon error -type ok -message "Cannot start an editor, as none is defined.\nDefine a third-party text editor using\nTools->'TkECLiPSe Preference Editor'\nto edit programs." 1162 return 1163 } 1164 if {![file exists $file]} { 1165 # Create the file (some editors require it) 1166 close [open $file w] 1167 } 1168 if {$line != -1 && $tkecl(pref,edit_line_option) != ""} { 1169 eval [list exec $tkecl(pref,editor) $tkecl(pref,edit_line_option)$line $file &] 1170 } else { 1171 eval [list exec $tkecl(pref,editor) $file &] 1172 } 1173} 1174 1175proc tkecl:popup_file_window {} { 1176 1177 set ec_files .ec_tools.ec_files 1178 if ![winfo exists $ec_files] { 1179 toplevel $ec_files 1180 wm title $ec_files "ECLiPSe Source File Manager" 1181 1182 listbox $ec_files.names -selectmode single -width 20 -height 25\ 1183 -yscrollcommand "tkecl:scroll_lb_sb $ec_files.state $ec_files.vscroll" 1184 listbox $ec_files.state -selectmode browse -width 11 -height 25\ 1185 -yscrollcommand "tkecl:scroll_lb_sb $ec_files.names $ec_files.vscroll" 1186 scrollbar $ec_files.vscroll -command "tkecl:scroll_lb_lb $ec_files.names $ec_files.state" 1187 bind $ec_files.names <Double-Button-1> { 1188 tkecl:edit_file [.ec_tools.ec_files.names get [.ec_tools.ec_files.names curselection]] 1189 } 1190 1191 frame $ec_files.buttons 1192 button $ec_files.buttons.browse -text "Add file" -command { 1193 set file [tkecl:getEcFile [pwd] "Add Source File"] 1194 1195 if {$file != ""} [list tkecl:add_source_file $file] 1196 } 1197 pack $ec_files.buttons.browse -side left -fill x -expand 1 1198 button $ec_files.buttons.edit -text Edit -command { 1199 set sel [.ec_tools.ec_files.names curselection] 1200 if {$sel != ""} { 1201 tkecl:edit_file [.ec_tools.ec_files.names get $sel] 1202 } else { 1203 set file [tkecl:getNewEcFile "" "New Source File"] 1204 1205 if {$file != ""} { 1206 ;# add_source done later in case edit_file fails 1207 tkecl:edit_file $file 1208 tkecl:add_source_file $file 1209 } 1210 }} 1211 pack $ec_files.buttons.edit -side left -fill x -expand 1 1212 button $ec_files.buttons.compile -text Compile -command { 1213 set sel [.ec_tools.ec_files.names curselection] 1214 if {$sel != ""} { 1215 tkecl:compile_file [.ec_tools.ec_files.names get $sel] 1216 } else { 1217 tkecl:compile_popup [pwd] 1218 }} 1219 pack $ec_files.buttons.compile -side left -fill x -expand 1 1220 button $ec_files.buttons.refresh -text Redisplay -command tkecl:refresh_file_window 1221 pack $ec_files.buttons.refresh -side left -fill x -expand 1 1222 button $ec_files.buttons.make -text Make -command { 1223 ec_rpcq_check make () 1224 ec_rpcq_check {flush output} (()) 1225 ec_rpcq_check {flush error} (()) 1226 tkecl:refresh_file_window } 1227 pack $ec_files.buttons.make -side left -fill x -expand 1 1228 button $ec_files.buttons.close -text Close -command "destroy $ec_files" 1229 pack $ec_files.buttons.close -side left -fill x -expand 1 1230 1231 pack $ec_files.buttons -side bottom -fill x 1232 pack $ec_files.vscroll -side left -fill y 1233 pack $ec_files.names -side left -fill both -expand 1 1234 pack $ec_files.state -side left -fill y 1235 balloonhelp $ec_files.names "ECLiPSe source files - files tracked by ECLiPSe for compilation by `make'" 1236 balloonhelp $ec_files.state "`ok' - previously compiled file\n \ 1237 `modified' - previously compiled file that has been modified \ 1238 (will be recompiled with `make')\n `new' - file names added to source list \ 1239 (will not be compiled by `make' until it is explicitly compiled first)" 1240 balloonhelp $ec_files.buttons.browse "Add a file to list" 1241 balloonhelp $ec_files.buttons.edit "edit a file. If file is not in source list, it will be added." 1242 balloonhelp $ec_files.buttons.compile "compile selected file from source list" 1243 balloonhelp $ec_files.buttons.refresh "Refresh display - update status of files in source list" 1244 bind $ec_files <Alt-h> "tkecl:Get_helpfileinfo file $ec_files " 1245 } else { 1246 tkinspect:RaiseWindow $ec_files 1247 } 1248 tkecl:refresh_file_window 1249} 1250 1251proc tkecl:add_source_file {file} { 1252 ec_rpcq_check [list record_source_file $file] (S) tracer_tcl 1253 tkecl:refresh_file_window 1254} 1255 1256proc tkecl:scroll_lb_lb {lb1 lb2 args} { 1257 eval "$lb1 yview $args" 1258 eval "$lb2 yview $args" 1259} 1260 1261proc tkecl:scroll_lb_sb {lb sb from to} { 1262 $lb yview moveto $from 1263 $sb set $from $to 1264} 1265 1266proc tkecl:refresh_file_window {} { 1267 1268 set ec_files .ec_tools.ec_files 1269 if [winfo exists $ec_files] { 1270 $ec_files.names delete 0 end 1271 $ec_files.state delete 0 end 1272 set files [lindex [ec_rpcq_check {list_files _} (_) tracer_tcl] 1] 1273 foreach item [lsort -index 0 $files] { 1274 $ec_files.names insert end [lindex $item 0] 1275 $ec_files.state insert end [lindex $item 1] 1276 } 1277 # adjust view such that nothing is hidden to the right 1278 set current [.ec_tools.ec_files.names xview] 1279 .ec_tools.ec_files.names xview moveto [expr 1 - [lindex $current 1] + [lindex $current 0]] 1280 } 1281} 1282 1283 1284#---------------------------------------------------------------------- 1285# Delayed goals 1286#---------------------------------------------------------------------- 1287 1288proc tkecl:popup_dg_window {} { 1289 global tkecl 1290 1291 set ec_dg .ec_tools.ec_dg 1292 if ![winfo exists $ec_dg] { 1293 toplevel $ec_dg 1294 wm title $ec_dg "ECLiPSe Delayed Goals" 1295 1296 set tkecl(dg_select_triggers) 0 1297 set tkecl(dg_trigger) postponed 1298 1299 text $ec_dg.text -bg white -yscrollcommand "$ec_dg.vscroll set" -wrap none -xscrollcommand "$ec_dg.hscroll set" 1300 scrollbar $ec_dg.vscroll -command "$ec_dg.text yview" 1301 scrollbar $ec_dg.hscroll -command "$ec_dg.text xview" -orient horizontal 1302 1303 set ff [frame $ec_dg.filters] 1304 pack [checkbutton $ff.traced -text "traced only" -variable tkecl(pref,dgf_tracedonly)] -side left 1305 pack [checkbutton $ff.spied -text "spied only" -variable tkecl(pref,dgf_spiedonly)] -side left 1306 pack [checkbutton $ff.wake -text "scheduled only" -variable tkecl(pref,dgf_wakeonly)] -side left 1307 set tf [frame $ff.triggers -relief ridge -borderwidth 2] 1308 pack [combobox $tf.triggers -click single -listheight 5 -bg white \ 1309 -postcommand "tkecl:dg_get_triggers $tf.triggers" \ 1310 -textvariable tkecl(dg_trigger) -editable 0 -click single \ 1311 -labeltext "Select from triggers:" -state disabled] \ 1312 -expand y -side right -fill x 1313 pack [checkbutton $tf.select_trig -variable tkecl(dg_select_triggers) \ 1314 -command "tkecl:select_dg_triggers $tf.triggers"] -side left 1315 pack $tf -side right -expand y -fill x 1316 1317 menu $ec_dg.mbar 1318 $ec_dg config -menu $ec_dg.mbar 1319 menu $ec_dg.mbar.options 1320 $ec_dg.mbar add cascade -label Options -menu $ec_dg.mbar.options 1321 $ec_dg.mbar.options add command -label "Change print options ..." -command "tkecl:edit_output_mode tracer" 1322 $ec_dg.mbar.options add check -label "Refresh delayed goals at every trace line" -variable tkecl(pref,trace_refresh_dg) 1323 menu $ec_dg.mbar.help 1324 $ec_dg.mbar add cascade -label Help -menu $ec_dg.mbar.help 1325 $ec_dg.mbar.help add command -label "Delayed Goals Help" -command "tkecl:Get_helpfileinfo dela $ec_dg" 1326 1327 frame $ec_dg.buttons 1328 button $ec_dg.buttons.refresh -text Refresh -command {tkecl:refresh_dg} 1329 pack $ec_dg.buttons.refresh -side left -fill x -expand 1 1330 button $ec_dg.buttons.close -text Close -command "destroy $ec_dg" 1331 pack $ec_dg.buttons.close -side left -fill x -expand 1 1332 1333 pack $ec_dg.filters -side top -fill x 1334 pack $ec_dg.buttons -side bottom -fill x 1335 pack $ec_dg.vscroll -side left -fill y 1336 pack $ec_dg.hscroll -side bottom -fill x 1337 pack $ec_dg.text -expand 1 -fill both 1338 bind $ec_dg.text <Any-Key> "tkecl:readonly_keypress %A" 1339 bind $ec_dg.text <ButtonRelease-2> {break} 1340 1341 balloonhelp $ec_dg.text "Delayed goals are displayed here. Green indicates goal has been scheduled.\n Right (or control-left) click on goal for a popup menu related to that goal and\n double left click to inspect goal (only if goal has invocation number)." 1342 balloonhelp $ec_dg.buttons "List of goals that are currently being delayed.\n\ 1343 Can be set to automatically refresh at every trace line from tracer window." 1344 balloonhelp $ff "Filter options for filtering displayed delayed goals." 1345 balloonhelp $ff.traced "Show only goals which can be traced when selected." 1346 balloonhelp $ff.spied "Show only goals which are being spied when selected." 1347 balloonhelp $ff.wake "Show only goals which have been scheduled when selected." 1348 balloonhelp $tf "Show only goals which have been suspended on a global trigger.\n Select the trigger from the list." 1349 bind $ec_dg <Alt-h> "tkecl:Get_helpfileinfo dela $ec_dg" 1350 } else { 1351 tkinspect:RaiseWindow $ec_dg 1352 } 1353 tkecl:refresh_dg 1354} 1355 1356proc tkecl:refresh_dg {} { 1357 global tkecl 1358 1359 set ec_dg .ec_tools.ec_dg 1360 if [winfo exists $ec_dg] { 1361 $ec_dg.text delete 1.0 end 1362 eval $ec_dg.text tag delete [$ec_dg.text tag names] 1363 $ec_dg.text tag configure highlight -foreground #00b000 1364 $ec_dg.text tag configure truncated -background pink 1365 ec_rpcq_check [list gui_dg\ 1366 $tkecl(dg_select_triggers)\ 1367 $tkecl(dg_trigger)\ 1368 [list dg_filter\ 1369 $tkecl(pref,dgf_tracedonly)\ 1370 $tkecl(pref,dgf_spiedonly)\ 1371 $tkecl(pref,dgf_wakeonly)]]\ 1372 (I()(III)) tracer_tcl 1373 } 1374} 1375 1376proc tkecl:handle_dg_print {stream {length {}}} { 1377 global tkecl 1378 1379 set gui_dg_info [ec_streamnum_to_channel $stream] 1380 set info [ec_read_exdr $gui_dg_info] 1381 while {$info != "end"} { 1382 set state [lindex $info 1] 1383 set prio [lindex $info 2] 1384 set invoc [lindex $info 3] 1385 set linelength [lindex $info 4] 1386 set line [lindex $info 5] 1387 if {$state == 1} { 1388 set Tag highlight 1389 } else { 1390 set Tag {} 1391 } 1392 1393 set ec_dg .ec_tools.ec_dg 1394 if [winfo exists $ec_dg] { 1395 if {[string length $line] >= $tkecl(pref,text_truncate)} { 1396 set line [string range $line 0 $tkecl(pref,text_truncate)] 1397 set truncated 1 1398 } else { 1399 set truncated 0 1400 } 1401 set gstart [$ec_dg.text index end] 1402 $ec_dg.text insert end $line $Tag 1403 if $truncated { 1404 $ec_dg.text insert end "..." truncated 1405 } 1406 $ec_dg.text tag bind g$invoc <Button-3> "tkecl:popup_delaymenu $ec_dg.text $invoc $prio %X %Y; break" 1407 $ec_dg.text tag bind g$invoc <Control-Button-1> "tkecl:popup_delaymenu $ec_dg.text $invoc $prio %X %Y; break" 1408 $ec_dg.text tag bind g$invoc <Double-Button-1> "tkinspect:Inspect_term_init invoc($invoc); break" 1409 $ec_dg.text tag add g$invoc $gstart "$gstart lineend" 1410 $ec_dg.text tag raise g$invoc 1411 } 1412 set info [ec_read_exdr $gui_dg_info] 1413 } 1414} 1415 1416proc tkecl:select_dg_triggers {w} { 1417 global tkecl 1418 1419 if {$tkecl(dg_select_triggers) == 1} { 1420 $w configure -state normal 1421 $w configure -editable 0 1422 } else { 1423 $w configure -state disabled 1424 } 1425} 1426 1427proc tkecl:dg_get_triggers {w} { 1428 1429 $w configure -list [lindex [ec_rpcq [list get_triggers _] (_) tracer_tcl] 1] 1430} 1431 1432proc tkecl:popup_delaymenu {w invoc prio x y} { 1433 global tkecl 1434 1435 if [winfo exists $w.gpopup] { 1436 destroy $w.gpopup 1437 } 1438 set m [menu $w.gpopup -tearoff 0] 1439 1440 if {$invoc != 0} { 1441 set greturn [ec_rpcq_check [list get_goal_info_by_invoc $invoc _ _ _ _ _ _ _] (I_______) tracer_tcl] 1442 set spec [lindex $greturn 2] 1443 set tspec [lindex $greturn 3] 1444 set module [lindex $greturn 4] 1445 ;# spec should be Name/Arity if valid 1446 if {$spec != "unknown"} { 1447 set spied [tkecl:pred_flag_value $spec $module spy] 1448 if {$spied == "on"} { 1449 set spytext "Nospy $spec" 1450 set spyval off 1451 } else { 1452 set spytext "Spy $spec" 1453 set spyval on 1454 } 1455 if {$invoc != 0} { 1456 set invtext "($invoc)" 1457 } else { 1458 set invtext "" 1459 } 1460 $m add command -label "$tspec @ $module $invtext <$prio>" -state disabled 1461 $m add command -label $spytext -command \ 1462 [list tkecl:set_pred_flag $spec $module spy $spyval] 1463 $m add command -label "Display source for this predicate" -command \ 1464 [list tkecl:set_and_display_source $spec $module] 1465 $m add command -label "Inspect this goal" -command \ 1466 "tkinspect:Inspect_term_init invoc($invoc)" 1467 $m add command -label "Observe this goal" -command "tkecl:observe_goal $invoc" 1468 } else { 1469 $m add command -label "No goal found for invocation $invoc. Please refresh." \ 1470 -state disabled 1471 } 1472 } else { 1473 $m add command -label "Goal information unavailable: please use tracer." \ 1474 -state disabled 1475 } 1476 1477 tk_popup $m $x $y 1478} 1479 1480 1481#---------------------------------------------------------------------- 1482# Tracer 1483#---------------------------------------------------------------------- 1484 1485proc tkecl:set_fail_invoc {invoc} { 1486 global tkecl 1487 1488 set tkecl(fail_invoc) $invoc 1489 tkecl:set_tracercommand f 1490} 1491 1492proc tkecl:set_jumpto_invoc {invoc} { 1493 global tkecl 1494 1495 if [regexp -- {^[0-9]+$} $invoc] { 1496 set tkecl(cont_invoc) $invoc 1497 tkecl:set_tracercommand i 1498 } 1499} 1500 1501proc tkecl:set_jumpto_depth {depth} { 1502 global tkecl 1503 1504 if [regexp -- {^[0-9]+$} $depth] { 1505 set tkecl(cont_mindepth) $depth 1506 set tkecl(cont_maxdepth) $depth 1507 tkecl:set_tracercommand j 1508 } 1509} 1510 1511proc tkecl:setup_creep {} { 1512 global tkecl 1513 1514 set tkecl(press_creep) 1 1515 tkecl:set_tracercommand c 1516} 1517 1518proc tkecl:end_creep {} { 1519 global tkecl 1520 1521 after cancel $tkecl(creepwaitevent) 1522 set tkecl(press_creep) 0 1523 set tkecl(creepwaitover) 1 1524} 1525 1526proc tkecl:analyze_failure {parent} { 1527 global tkecl 1528 1529 set result [ec_rpcq {failure_culprit _ _} (__) sepia_kernel] 1530 switch $result { 1531 throw - 1532 fail { 1533 tk_messageBox -type ok -icon info -parent $parent \ 1534 -message "No failure culprit stored yet" 1535 } 1536 default { 1537 set fculprit [lindex $result 1] 1538 set invoc [lindex $result 2] 1539 if { $fculprit > $invoc } { 1540 set answer [ tk_messageBox -type yesno -icon question -parent $parent \ 1541 -message "Most recent failure was caused by goal with invocation number ($fculprit).\ 1542 Do you want to jump there now?" ] 1543 switch $answer { 1544 yes { tkecl:set_jumpto_invoc $fculprit } 1545 } 1546 } elseif {[string match $tkecl(tracer_state) disabled]} { 1547 tk_messageBox -type ok -icon info -parent $parent \ 1548 -message "Most recent failure was caused by goal with invocation number ($fculprit).\ 1549 To jump there\n\ 1550 1. re-run the query\n\ 1551 2. select \"Analyze failure\" immediately" 1552 } elseif {$fculprit == $invoc && ![regexp $tkecl(current_port) fail|leave] } { 1553 tk_messageBox -type ok -icon info -parent $parent \ 1554 -message "Most recent failure was caused by goal with invocation number ($fculprit).\ 1555 This is the goal you are currently at." 1556 } else { 1557 tk_messageBox -type ok -icon info -parent $parent \ 1558 -message "Most recent failure was caused by goal with invocation number ($fculprit).\ 1559 To jump there\n\ 1560 1. click \"Abort\" or \"Nodebug\"\n\ 1561 2. re-run the query\n\ 1562 3. select \"Analyze failure\" immediately" 1563 } 1564 } 1565 } 1566} 1567 1568proc tkecl:kill_tracer {} { 1569 set ec_tracer .ec_tools.ec_tracer 1570 1571 if [winfo exists $ec_tracer] { 1572 destroy $ec_tracer 1573 } 1574} 1575 1576proc tkecl:refresh_current_trace_line {} { 1577 global tkecl 1578 1579 set ec_tracer .ec_tools.ec_tracer 1580 if ![winfo exists $ec_tracer] return 1581 1582 tkecl:edit_output_mode tracer 1583 set trace_info [ec_rpcq [list get_current_traceline _ _ _ _] (____) tracer_tcl] 1584 set invoc [lindex $trace_info 4] 1585 set style [lindex $trace_info 2] 1586 if {$style == "fail_style"} return ;# no point refreshing if failure/abort 1587 set depth [expr [lindex $trace_info 1] + 1] 1588 set line [lindex $trace_info 3] 1589 if {[string length $line] >= $tkecl(pref,text_truncate)} { 1590 set truncated 1 1591 set line [string range $line 0 $tkecl(pref,text_truncate)] 1592 } else { 1593 set truncated 0 1594 } 1595 1596 ;# only refresh current trace line if the current line has the same tag 1597 ;# (invocation number) as the current debug goal from ECLiPSe 1598 if {[lsearch [$ec_tracer.stack.text tag names $depth.0] $invoc] != -1} { 1599 $ec_tracer.stack.text delete $depth.0 "$depth.end+1 char" 1600 $ec_tracer.stack.text insert $depth.0 $line $style 1601 if $truncated { 1602 $ec_tracer.stack.text insert end "..." truncate_style 1603 } 1604 $ec_tracer.stack.text insert $depth.end "\n" $style 1605 ;# add the tag back to the refreshed line... 1606 $ec_tracer.stack.text tag add $invoc $depth.0 $depth.end 1607 $ec_tracer.stack.text tag raise $invoc 1608 } 1609} 1610 1611proc tkecl:popup_tracer {} { 1612 global tkecl 1613 1614 set ec_tracer .ec_tools.ec_tracer 1615 if ![winfo exists $ec_tracer] { 1616 toplevel $ec_tracer 1617 wm title $ec_tracer "ECLiPSe Tracer" 1618 1619 # initialize global tracer variables 1620 set tkecl(tracercommand) N 1621 set tkecl(tracercommand_issued) 0 1622 set tkecl(current_port) .... 1623 set tkecl(next_trace_line_depth) 1 1624 set tkecl(press_creep) 0 1625 set tkecl(creepwaitevent) 0 1626 set tkecl(cont_invoc) 0 1627 set tkecl(cont_mindepth) 0 1628 set tkecl(cont_maxdepth) 9999 1629 set tkecl(zap_port) {Not Current} 1630 set tkecl(filter_predtype) any 1631 set tkecl(filter_predmodule2) eclipse 1632 set tkecl(filter_mininvoc) 0 1633 set tkecl(filter_maxinvoc) 999999999 1634 set tkecl(filter_mindepth) 0 1635 set tkecl(filter_maxdepth) 999999999 1636 set tkecl(filter_count) 1 1637 set tkecl(filter_hits) 0 1638 set tkecl(portlist) [lindex [ec_rpcq_check {debug_port_names _} (_) sepia_kernel] 1] 1639 set tkecl(portsets) {all none current previous entering exiting failing} 1640 set tkecl(portset,current) $tkecl(portlist) 1641 set tkecl(portset,previous) $tkecl(portlist) 1642 set tkecl(portset,all) $tkecl(portlist) 1643 set tkecl(portset,none) {} 1644 set tkecl(portset,entering) {call redo resume} 1645 set tkecl(portset,exiting) {exit *exit fail leave} 1646 set tkecl(portset,failing) {fail next else} 1647 foreach port $tkecl(portlist) { 1648 set tkecl(filter_port,$port) 1 1649 } 1650 1651 # filter,changable is a list of filter properties for the tracer filter 1652 # that can be changed for a filter command. Each property is 1653 # represented by the variables tkecl(filter_<name>) (current value) and 1654 # tkecl(filter_last<name>) (previous value). The last values are for 1655 # determining if the property has been changed since the last filter 1656 set tkecl(filter,changable) \ 1657 [list mininvoc maxinvoc mindepth maxdepth wanted_ports predtype] 1658 # filterpred are the properties for the `specific predicate instance' 1659 # filter. These are treated separately from the other filter properties 1660 set tkecl(filterpred,changable) \ 1661 [list predcondition predmatch predmodule predmodule2] 1662 foreach filterprop $tkecl(filter,changable) { 1663 set tkecl(filter_last$filterprop) {} 1664 } 1665 foreach filterprop $tkecl(filterpred,changable) { 1666 set tkecl(filter_last$filterprop) {} 1667 } 1668 1669 set tmbar [menu $ec_tracer.menubar] 1670 $ec_tracer config -menu $tmbar 1671 $tmbar add cascade -label "Windows" -menu $tmbar.win -underline 0 1672 menu $tmbar.win 1673 $tmbar.win add command -label "Raise top-level" -command "tkinspect:RaiseWindow ." 1674 $tmbar.win add command -label "Predicate Browser" -command tkecl:popup_pred_prop 1675 $tmbar.win add command -label "Delayed Goals" -command tkecl:popup_dg_window 1676 $tmbar.win add separator 1677 $tmbar.win add command -label "Close Tracer" -command "destroy $ec_tracer" 1678 $tmbar add cascade -label "Options" -menu $tmbar.opt -underline 0 1679 menu $tmbar.opt 1680 $tmbar.opt add command -label "Configure filter ..." -command tkecl:popup_filter 1681 $tmbar.opt add command -label "Change print options ..." -command "tkecl:edit_output_mode tracer" 1682 $tmbar.opt add command -label "Analyze failure ..." -command "tkecl:analyze_failure $ec_tracer" 1683 $tmbar.opt add command -label "Refresh goal stack now" -command tkecl:refresh_goal_stack 1684 $tmbar.opt add check -label "Refresh goal stack at every trace line" -variable tkecl(pref,trace_refresh_stack) 1685 $tmbar.opt add check -label "Refresh delayed goals at every trace line" -variable tkecl(pref,trace_refresh_dg) 1686 $tmbar.opt add check -label "Raise tracer window at every trace line" -variable tkecl(pref,trace_raise_tracer) 1687 $tmbar add cascade -label "Help" -menu $tmbar.help -underline 0 1688 menu $tmbar.help 1689 $tmbar.help add command -label "Tracer Help" -command "tkecl:Get_helpfileinfo trac $ec_tracer" 1690 1691 set ec_tracertab $ec_tracer.tab 1692 tabnotebook $ec_tracertab -padx 14 -pady 4 -background darkgray \ 1693 -activebackground #f0f0f0 -disabledbackground darkgray \ 1694 -normalbackground gray -borderwidth 0 -font tkecllabel 1695 frame $ec_tracertab.trace 1696 $ec_tracertab add "Trace Log" -window $ec_tracertab.trace 1697# $ec_tracertab activate "Trace Log" 1698# label $ec_tracertab.trace.label -text "Trace Log" 1699 text $ec_tracertab.trace.text -bg white -yscrollcommand "$ec_tracertab.trace.vscroll set" -wrap none -xscrollcommand "$ec_tracertab.trace.hscroll set" 1700 $ec_tracertab.trace.text tag configure call_style -foreground blue 1701 $ec_tracertab.trace.text tag configure exit_style -foreground #00b000 1702 $ec_tracertab.trace.text tag configure fail_style -foreground red 1703 $ec_tracertab.trace.text tag configure truncate_style -background pink 1704 scrollbar $ec_tracertab.trace.vscroll -command "$ec_tracertab.trace.text yview" 1705 scrollbar $ec_tracertab.trace.hscroll -command "$ec_tracertab.trace.text xview" -orient horizontal 1706 pack $ec_tracertab.trace.vscroll -side left -fill y 1707 pack $ec_tracertab.trace.hscroll -side bottom -fill x 1708 pack $ec_tracertab.trace.text -side bottom -expand 1 -fill both 1709# pack $ec_tracertab.trace.label -side left -expand 1 -fill x 1710 1711 bind $ec_tracertab.trace.text <Any-Key> "tkecl:readonly_keypress %A" 1712 bind $ec_tracertab.trace.text <ButtonRelease-2> {break} 1713 1714 tkecl:setup_source_debug_window 1715 1716 frame $ec_tracer.stack 1717 label $ec_tracer.stack.label -text "Call Stack" 1718 text $ec_tracer.stack.text -height 15 -bg white -yscrollcommand "$ec_tracer.stack.vscroll set" -wrap none -xscrollcommand "$ec_tracer.stack.hscroll set" 1719 $ec_tracer.stack.text tag configure call_style -foreground blue 1720 $ec_tracer.stack.text tag configure exit_style -foreground #00b000 1721 $ec_tracer.stack.text tag configure fail_style -foreground red 1722 $ec_tracer.stack.text tag configure truncate_style -background pink 1723 $ec_tracer.stack.text configure -cursor left_ptr 1724 scrollbar $ec_tracer.stack.vscroll -command "$ec_tracer.stack.text yview" 1725 scrollbar $ec_tracer.stack.hscroll -command "$ec_tracer.stack.text xview" -orient horizontal 1726 pack $ec_tracer.stack.vscroll -side left -fill y 1727 pack $ec_tracer.stack.hscroll -side bottom -fill x 1728 pack $ec_tracer.stack.text -side bottom -expand 1 -fill both 1729 pack $ec_tracer.stack.label -side left -expand 1 -fill x 1730 1731 bind $ec_tracer.stack.text <Any-Key> "tkecl:readonly_keypress %A" 1732 bind $ec_tracer.stack.text <ButtonRelease-2> {break} 1733 1734 frame $ec_tracer.buttons 1735 bind $ec_tracer <Enter> "tkecl:enable_tracer_keys $ec_tracer" 1736 # remember underline for button if keyboard shortcut added! 1737 bind $ec_tracer.buttons <Key-c> {tkecl:set_tracercommand c} 1738 bind $ec_tracer.buttons <Key-l> {tkecl:set_tracercommand l} 1739 bind $ec_tracer.buttons <Key-s> {tkecl:set_tracercommand s} 1740 bind $ec_tracer.buttons <Key-u> {tkecl:set_tracercommand up} 1741 bind $ec_tracer.buttons <Key-p> {tkecl:set_tracercommand z} 1742 bind $ec_tracer.buttons <Key-f> {tkecl:set_tracercommand filter} 1743 bind $ec_tracer.buttons <Key-i> {tkecl:set_tracercommand i} 1744 bind $ec_tracer.buttons <Key-d> {tkecl:set_tracercommand j} 1745# bind $ec_tracer.buttons <Key-plus> {tkecl:set_tracercommand +} 1746# bind $ec_tracer.buttons <Key-minus> {tkecl:set_tracercommand -} 1747 button $ec_tracer.buttons.creep -text Creep -underline 0 -command {} 1748 bind $ec_tracer.buttons.creep <Button-1> {tkecl:setup_creep} 1749 bind $ec_tracer.buttons.creep <ButtonRelease-1> {tkecl:end_creep} 1750 pack $ec_tracer.buttons.creep -side left -fill x -expand 1 1751 ;# destroy are sent to all widgets of a window, chose one for 1752 ;# code to cope with the closing of the tracer window 1753 bind $ec_tracer.buttons.creep <Destroy> "if {![ec_running]} {tkecl:tracer_off}" 1754 button $ec_tracer.buttons.skip -text Skip -underline 0 -command {tkecl:set_tracercommand s} 1755 pack $ec_tracer.buttons.skip -side left -fill x -expand 1 1756 button $ec_tracer.buttons.up -text Up -underline 0 -command {tkecl:set_tracercommand up} 1757 pack $ec_tracer.buttons.up -side left -fill x -expand 1 1758 button $ec_tracer.buttons.leap -text Leap -underline 0 -command {tkecl:set_tracercommand l} 1759 pack $ec_tracer.buttons.leap -side left -fill x -expand 1 1760 button $ec_tracer.buttons.filter -text {Filter} -underline 0 -command {tkecl:set_tracercommand filter} 1761 pack $ec_tracer.buttons.filter -side left -fill x -expand 1 1762 button $ec_tracer.buttons.abort -text Abort -command {tkecl:set_tracercommand a} 1763 pack $ec_tracer.buttons.abort -side left -fill x -expand 1 1764 button $ec_tracer.buttons.nodebug -text Nodebug -command {tkecl:set_tracercommand n ; tkinspect:RaiseWindow .} 1765 pack $ec_tracer.buttons.nodebug -side left -fill x -expand 1 1766 1767 frame $ec_tracer.cont 1768 button $ec_tracer.cont.button -text "To Invoc:" -underline 3 -command {tkecl:set_tracercommand i} 1769 pack $ec_tracer.cont.button -side left -fill x -expand 1 1770 ventry $ec_tracer.cont.invoc \ 1771 -vcmd {regexp {^[0-9]*$} %P} -validate key -invalidcmd bell \ 1772 -width 8 -textvariable tkecl(cont_invoc) -bg white 1773 pack $ec_tracer.cont.invoc -side left 1774 bind $ec_tracer.cont.invoc <Return> "tkecl:set_tracercommand i" 1775 button $ec_tracer.cont.jump -text "To Depth:" -underline 3 -command {tkecl:set_tracercommand j} 1776 pack $ec_tracer.cont.jump -side left -fill x -expand 1 1777 ventry $ec_tracer.cont.mindepth \ 1778 -vcmd {regexp {^[0-9]*$} %P} -validate key -invalidcmd bell \ 1779 -width 5 -textvariable tkecl(cont_mindepth) -bg white 1780 pack $ec_tracer.cont.mindepth -side left 1781 ventry $ec_tracer.cont.maxdepth -labeltext .. \ 1782 -vcmd {regexp {^[0-9]*$} %P} -validate key -invalidcmd bell \ 1783 -width 5 -textvariable tkecl(cont_maxdepth) -bg white 1784 pack $ec_tracer.cont.maxdepth -side left 1785 button $ec_tracer.cont.zap -text "To Port:" -underline 3 -command {tkecl:set_tracercommand z} 1786 pack $ec_tracer.cont.zap -side left 1787 1788 combobox $ec_tracer.cont.ports -click single -listheight 16 -bg white \ 1789 -width 10 -list "{Not Current} $tkecl(portlist)" -textvariable tkecl(zap_port) 1790 pack $ec_tracer.cont.ports -side left 1791 button $ec_tracer.close -text Close -command "destroy $ec_tracer" 1792 tkecl:configure_tracer_buttons disabled 1793 1794 pack $ec_tracer.stack -side top -expand 1 -fill both 1795 pack $ec_tracer.buttons -side top -fill x 1796 pack $ec_tracer.cont -side top -fill x 1797 pack $ec_tracertab -expand 1 -fill both 1798 pack $ec_tracer.close -side top -fill x 1799 1800 ec_rpcq {set_flag debugging creep} (()()) 1801 1802#-------------------------------------------------------------------- 1803# Balloon Help for tracer 1804#-------------------------------------------------------------------- 1805 balloonhelp $ec_tracer "Tracer for ECLiPSe execution - start execution from main window" 1806 balloonhelp $ec_tracer.stack.label "Execution call stack - \ 1807 shows the current goal and its ancestors.\n \ 1808 Calls for current goal in blue, failure in red, success in green. \ 1809 Ancestors printed with non-current bindings in black\n \ 1810 Press right (or control-left) mouse button over a stack item for popup \ 1811 menu related to that goal/predicate.\n Double-click left mouse button over \ 1812 a stack item to inspect it.\n Single click left mouse button on the \ 1813 information (left) part of\n the stack item to show source contxt\n " 1814 balloonhelp $ec_tracertab.trace "Trace log: chronological log of traced goals.\n Calls in blue, successes in green, failures in red\n Leading indentation indicates depth" 1815 balloonhelp $ec_tracer.buttons.creep "Creep to next tracable goal's debug port.\n\ 1816 Keyboard shortcut: `c'\nPress and hold button for continuous creep." 1817 balloonhelp $ec_tracer.buttons.skip "Skip to exit/fail port of goal (creep\ 1818 if already at port).\nKeyboard shortcut: `s'" 1819 balloonhelp $ec_tracer.buttons.leap "Leap to next spied predicate port or next breakpoint.\n\ 1820 Keyboard shortcut: `l'" 1821 balloonhelp $ec_tracer.buttons.up "Continue until back to parent's\ 1822 depth\nKeyboard shortcut: `u'" 1823 balloonhelp $ec_tracer.buttons.filter "Continue until filter \ 1824 conditions hold.\nKeyboard shortcut: `f'.\n\ 1825 See Options for how to configure the filter." 1826 balloonhelp $ec_tracer.buttons.abort "Abort execution" 1827 balloonhelp $ec_tracer.buttons.nodebug "Turn off debugging and\ 1828 continue execution\n(Further outputs will be displayed on main window)" 1829 balloonhelp $ec_tracer.cont.button "Jump to port for goal with \ 1830 invocation number on right\nKeyboard shortcut: `i'" 1831 balloonhelp $ec_tracer.cont.jump "Jump to port for next goal with \ 1832 depth in the ranges on the right.\nKeyboard shortcut: `d'" 1833 balloonhelp $ec_tracer.cont.zap "Jump to port selected on the right\ 1834 \nKeyboard shortcut: `p'" 1835 bind $ec_tracer <Alt-h> "tkecl:Get_helpfileinfo trac $ec_tracer" 1836 } else { 1837 tkinspect:RaiseWindow $ec_tracer 1838 } 1839} 1840 1841# enable tracing via keyboard shortcuts if tracer is enabled 1842proc tkecl:enable_tracer_keys {ec_tracer} { 1843 global tkecl 1844 1845 if {$tkecl(tracer_state) == "normal"} { 1846 focus $ec_tracer.buttons 1847 } 1848} 1849 1850proc tkecl:handle_debug_output {stream {length {}}} { 1851 if {![winfo exists .ec_tools.ec_tracer]} { 1852 return 1853 } 1854 ec_stream_to_window_sync {} .ec_tools.ec_tracer.tab.trace.text $stream $length 1855} 1856 1857# CAUTION: text widgets positions are a bit weird: the text widget always 1858# has a newline at the end, and the end-index is just after that. Therefore, 1859# an empty text widget has a newline at 1.0 and end == 2.0 1860 1861proc tkecl:handle_trace_line {stream {length {}}} { 1862 global tkecl 1863 1864 set ec_tracer .ec_tools.ec_tracer 1865 if ![winfo exists $ec_tracer] { 1866 tkecl:popup_tracer 1867 } 1868 set tkecl(tracercommand_issued) 0 1869 set trace_info [ec_read_exdr [ec_streamnum_to_channel $stream]] 1870 if {[llength $trace_info] == 0} { 1871 # start of new trace session 1872 # make sure current source file is reloaded 1873 # cannot simply set file to "" as we may need the file name (for 1874 # placing breakpoints etc.) 1875 if {$tkecl(source_debug,file) != ""} { 1876 tkecl:load_source_debug_file $tkecl(source_debug,file) 1877 } 1878 return 1879 } 1880 set depth [lindex $trace_info 0] 1881 set style [lindex $trace_info 1] 1882 set line [lindex $trace_info 2] 1883 set invoc [lindex $trace_info 3] 1884 set tkecl(current_port) [lindex $trace_info 4] 1885 set prio [lindex $trace_info 5] 1886 set fpath_info [lindex $trace_info 6] 1887 set from [lindex $trace_info 7] 1888 set to [lindex $trace_info 8] 1889 set tkecl(cont_invoc) $invoc ;# defaults to current 1890 set tkecl(tracer_up_depth) [expr $depth>0 ? $depth-1 : 0] 1891 1892 if {[string length $line] >= $tkecl(pref,text_truncate)} { 1893 set truncated 1 1894 set line [string range $line 0 $tkecl(pref,text_truncate)] 1895 } else { 1896 set truncated 0 1897 } 1898 $ec_tracer.tab.trace.text tag configure $depth -lmargin1 "$depth m" 1899 $ec_tracer.tab.trace.text insert end $line "$style $depth" 1900 if $truncated { 1901 $ec_tracer.tab.trace.text insert end "..." truncate_style 1902 } 1903 ;# make sure at least a partial line at the start is visible 1904 $ec_tracer.tab.trace.text see "end -1 line linestart +40 chars" 1905 $ec_tracer.tab.trace.text insert end "\n" $style 1906 1907 set stdepth [expr $depth + 1] ;# actual depth in printed stack 1908 set next_line [lindex [split [$ec_tracer.stack.text index end-1chars] .] 0] 1909 if {$style == "fail_style" && $next_line > $stdepth} { 1910 ;# we did not jump to this fail port.. 1911 $ec_tracer.stack.text tag remove call_style $stdepth.0 end 1912 if {[$ec_tracer.stack.text compare $stdepth.end == $stdepth.0]} { 1913 ;# if the line is empty, we don't have the port, print it 1914 ;# don't bother to add a popup...not very useful here 1915 $ec_tracer.stack.text insert $stdepth.0 $line $style 1916 } 1917 $ec_tracer.stack.text tag add fail_style $stdepth.0 end 1918 $ec_tracer.stack.text see $stdepth.0 1919 set tkecl(next_trace_line_depth) $stdepth 1920 } else { 1921 if {$next_line > $tkecl(next_trace_line_depth)} { 1922 # delete leftover exit/fail lines 1923 # and tags to goals that are no longer accessible 1924 tkecl:cleanup_goal_stack_line $tkecl(next_trace_line_depth) [expr $next_line - 1] 1925 set next_line $tkecl(next_trace_line_depth) 1926 } 1927 if {$next_line < $stdepth} { 1928 while {$next_line < $stdepth} { 1929 $ec_tracer.stack.text insert end "\n" 1930 incr next_line 1931 } 1932 } elseif {$next_line > $stdepth} { 1933 tkecl:cleanup_goal_stack_line $stdepth [expr $next_line - 1] 1934 } 1935 $ec_tracer.stack.text tag remove call_style 1.0 end 1936 $ec_tracer.stack.text insert end $line $style 1937 if $truncated { 1938 $ec_tracer.stack.text insert end "..." truncate_style 1939 } 1940 $ec_tracer.stack.text insert end "\n" $style 1941 tkecl:set_goalpopup $depth $invoc $prio $line 1942 $ec_tracer.stack.text see end 1943 if {$style == "call_style"} { 1944 ;# extract into tkecl(next_trace_line_depth) the line number 1945 ;# from an index of the form line.char 1946 scan [$ec_tracer.stack.text index end-1chars] \ 1947 {%u} tkecl(next_trace_line_depth) 1948 } else { 1949 set tkecl(next_trace_line_depth) $stdepth 1950 } 1951 } 1952 1953 # Refresh stack, delayed goals and debug source displays 1954 if {$tkecl(pref,trace_refresh_stack) && $style != "fail_style"} { 1955 # don't refresh during failures because we'd lose displayed information 1956 tkecl:refresh_goal_stack 1957 } 1958 if {$tkecl(pref,trace_refresh_dg)} { tkecl:refresh_dg } 1959 tkecl:update_source_debug $style $from $to $fpath_info 1960} 1961 1962proc tkecl:handle_tracer_port_start {} { 1963 global tkecl 1964 1965 # Enable the buttons, and add some delay if repeating creep from mouse hold 1966 tkecl:configure_tracer_buttons normal 1967 if {($tkecl(press_creep) > 0) && \ 1968 [string match $tkecl(tracercommand) "c"]} { 1969 if {$tkecl(press_creep) == 1} { ;# initial press, wait longer 1970 set interval 700 1971 } else { 1972 set interval 50 1973 set tkecl(press_creep) 2 1974 } 1975 set tkecl(creepwaitevent) [after $interval {set tkecl(creepwaitover) 1}] 1976 vwait tkecl(creepwaitover) 1977 if {($tkecl(press_creep) > 0) && \ 1978 [string match $tkecl(tracercommand) "c"]} { 1979 # did not select any other tracer command during wait... 1980 set tkecl(press_creep) 2 1981 tkecl:set_tracercommand c 1982 } 1983 } 1984 # update the filter hits 1985 set tkecl(filter_hits) [lindex \ 1986 [ec_rpcatq [list getval filter_hits _] (()_) tracer_tcl] 2] 1987} 1988 1989proc tkecl:send_tracer_command {cmd {type S}} { 1990 1991 ec_rpcq [list set_tracer_command $cmd] ($type) tracer_tcl 1992} 1993 1994proc tkecl:handle_tracer_command {} { 1995 global tkecl 1996 1997 # interpret the command and configure Eclipse for continuation 1998 # tracer_state must be set to disabled before command is handled 1999 # as this indicates that we are ready to continue from the debug port 2000 switch -exact -- $tkecl(tracercommand) { 2001 N { 2002 # caution: if tracercommand = N the window is already destroyed! 2003 set tkecl(tracer_state) disabled 2004 tkecl:send_tracer_command N 2005 } 2006 i { 2007 if [regexp -- {^[0-9]+$} $tkecl(cont_invoc)] { 2008 tkecl:configure_tracer_buttons disabled 2009 ec_rpcq_check [list configure_prefilter $tkecl(cont_invoc) _ _ _ _]\ 2010 (I____) sepia_kernel 2011 tkecl:send_tracer_command i 2012 } 2013 } 2014 j { 2015 if {[regexp -- {^[0-9]+$} $tkecl(cont_mindepth)] && \ 2016 [regexp -- {^[0-9]+$} $tkecl(cont_mindepth)]} { 2017 tkecl:configure_tracer_buttons disabled 2018 ec_rpcq_check [list configure_prefilter _ [list .. $tkecl(cont_mindepth) $tkecl(cont_maxdepth)] _ _ _]\ 2019 (_(II)___) sepia_kernel 2020 tkecl:send_tracer_command j 2021 } 2022 } 2023 up { ;# jump one level up 2024 tkecl:configure_tracer_buttons disabled 2025 ec_rpcq_check [list configure_prefilter _ [list .. 0 $tkecl(tracer_up_depth)] _ _ _]\ 2026 (_(II)___) sepia_kernel 2027 tkecl:send_tracer_command j 2028 } 2029 f { ;# fail to $tkecl(fail_invoc) 2030 tkecl:configure_tracer_buttons disabled 2031 tkecl:send_tracer_command [list f $tkecl(fail_invoc)] {(I)} 2032 } 2033 z { ;# zap to $tkecl(zap_port) 2034 tkecl:configure_tracer_buttons disabled 2035 if {$tkecl(zap_port) != "Not Current"} { 2036 ec_rpcq_check [list configure_prefilter _ _ $tkecl(zap_port) _ dontcare]]\ 2037 (__()_()) sepia_kernel 2038 tkecl:send_tracer_command "" 2039 } else { 2040 tkecl:send_tracer_command z 2041 } 2042 } 2043 filter { 2044 tkecl:configure_tracer_buttons disabled 2045 2046 # for the third case we only need to stop at predicates 2047 # with spypoints as we will set one up on the template 2048 # predicate. 2049 2050 set changed 0 2051 2052 # now set the count 2053 if {$tkecl(filter_count) < 1} { set tkecl(filter_count) 1} 2054 2055 # prepare ECLiPSe side for filter command. This must be done 2056 # before setting any specialised condition (e.g. goal filtering). 2057 ec_rpcq [list prepare_filter $tkecl(filter_count)] (I) tracer_tcl 2058 2059 switch -exact -- $tkecl(filter_predtype) { 2060 any { 2061 set filter_spy all 2062 } 2063 anyspy { 2064 set filter_spy spied 2065 } 2066 goalmatching { 2067 switch [tkecl:configure_pred] { 2068 error { 2069 tkecl:reset_traceport 2070 return 2071 } 2072 spy_set { 2073 set filter_spy spied 2074 set tkecl(last_filter_spy) $filter_spy 2075 incr changed 2076 } 2077 continue { 2078 # same filter, no need to change 2079 set filter_spy $tkecl(last_filter_spy) 2080 } 2081 default { 2082 set filter_spy all 2083 set tkecl(last_filter_spy) $filter_spy 2084 incr changed 2085 } 2086 } 2087 } 2088 } 2089 2090 set tkecl(filter_wanted_ports) {} 2091 foreach port $tkecl(portlist) { 2092 if $tkecl(filter_port,$port) { 2093 lappend tkecl(filter_wanted_ports) $port 2094 } 2095 } 2096 if {$tkecl(filter_wanted_ports) != $tkecl(portset,current)} { 2097 set tkecl(portset,previous) $tkecl(portset,current) 2098 set tkecl(portset,current) $tkecl(filter_wanted_ports) 2099 } 2100 2101 # sepia_kernel:configure_prefilter(Invoc, Depth, Ports, Preds, Module) 2102 foreach filterprop $tkecl(filter,changable) { 2103 if [tkecl:check_if_changed $filterprop] { incr changed} 2104 } 2105 2106 if [catch { ec_rpcq_check [list configure_prefilter \ 2107 [list .. $tkecl(filter_mininvoc) $tkecl(filter_maxinvoc)] \ 2108 [list .. $tkecl(filter_mindepth) $tkecl(filter_maxdepth)] \ 2109 $tkecl(filter_wanted_ports) \ 2110 $filter_spy \ 2111 dontcare] \ 2112 {((II)(II)[()*]()())} sepia_kernel }\ 2113 ] { 2114 tk_messageBox -icon error -type ok -message "Filter Error: some entries for filter conditions are invalid. " 2115 tkecl:reset_traceport 2116 return 2117 } 2118 2119 if {$changed > 0} { 2120 ;# change in filter condition, reset filter count 2121 ec_rpcatq [list setval filter_hits 0] (()I) tracer_tcl 2122 } 2123 tkecl:send_tracer_command filter 2124 } 2125 default { 2126 tkecl:configure_tracer_buttons disabled 2127 tkecl:send_tracer_command $tkecl(tracercommand) 2128 } 2129 } 2130 ec_multi:terminate_phase 2131} 2132 2133proc tkecl:check_if_changed {filterprop} { 2134 global tkecl 2135 2136 if {$tkecl(filter_$filterprop) != $tkecl(filter_last$filterprop)} { 2137 set tkecl(filter_last$filterprop) $tkecl(filter_$filterprop) 2138 return 1 2139 } else { 2140 return 0 2141 } 2142} 2143 2144proc tkecl:reset_traceport {} { 2145 global tkecl 2146 2147 tkecl:configure_tracer_buttons normal 2148 set tkecl(tracercommand) N 2149 set tkecl(tracercommand_issued) 0 2150} 2151 2152proc tkecl:set_tracercommand {command} { 2153 global tkecl 2154 2155 if [winfo exists .ec_tools.ec_tracer] { 2156 set tkecl(tracercommand) $command 2157 set tkecl(tracercommand_issued) 1 2158 } 2159} 2160 2161proc tkecl:check_tracer_interaction {} { 2162 global tkecl tcl_platform 2163 2164 if {[winfo exists .ec_tools.ec_tracer]} { 2165 if {$tkecl(tracercommand_issued) == 1} { 2166 tkecl:handle_tracer_command 2167 } 2168 } 2169} 2170 2171 2172proc tkecl:tracer_off {} { 2173 global tkecl 2174 2175 if [string match $tkecl(tracer_state) disabled] { 2176 ec_rpcq {set_flag debugging nodebug} (()()) 2177 } else { 2178 # tracer window may have already disappeared, pass command directly 2179 set tkecl(tracercommand) N 2180 tkecl:handle_tracer_command 2181 } 2182} 2183 2184proc tkecl:configure_tracer_buttons {state} { 2185 global tkecl 2186 set tkecl(tracer_state) $state ;# normal or disabled 2187 set ec_tracer .ec_tools.ec_tracer 2188 $ec_tracer.buttons.creep configure -state $state 2189 $ec_tracer.buttons.leap configure -state $state 2190 $ec_tracer.buttons.up configure -state $state 2191 $ec_tracer.buttons.filter configure -state $state 2192 $ec_tracer.buttons.skip configure -state $state 2193 $ec_tracer.buttons.abort configure -state $state 2194 $ec_tracer.buttons.nodebug configure -state $state 2195 $ec_tracer.cont.button configure -state $state 2196 $ec_tracer.cont.jump configure -state $state 2197 $ec_tracer.cont.zap configure -state $state 2198 if [winfo exists $ec_tracer.filter] { 2199 $ec_tracer.filter.go configure -state $state 2200# Don't see any reason why this should be done (?) 2201# if {$tkecl(predtype) == "goalmatching"} { 2202# if {$state == "disabled"} { 2203# tkecl:fields_disable $ec_tracer 2204# } 2205# if {$state == "normal"} { 2206# tkecl:enable_pred $ec_tracer 2207# } 2208# } 2209 } 2210 if {$state == "normal"} { 2211 if {[tkecl:pointer_window] == "$ec_tracer"} { 2212 focus $ec_tracer.buttons 2213 } 2214 if {$tkecl(pref,trace_raise_tracer)} { 2215 tkinspect:RaiseWindow $ec_tracer 2216 } 2217 } else { ;# $state == "disabled" 2218 if {[focus] == "$ec_tracer.buttons"} { 2219 ;# assume buttons had focus, so remove it to ignore any 2220 ;# stray key presses while buttons are disabled 2221 focus $ec_tracer 2222 } 2223 } 2224} 2225 2226 2227proc tkecl:popup_goalmenu {w invoc depth prio greturn x y} { 2228 global tkecl 2229 2230 if [winfo exists $w.gpopup] { 2231 destroy $w.gpopup 2232 } 2233 set m [menu $w.gpopup -tearoff 0] 2234 set spec [lindex $greturn 2] 2235 set tspec [lindex $greturn 3] 2236 set module [lindex $greturn 4] 2237 set lookup_module [lindex $greturn 5] 2238 set path_info [lindex $greturn 6] 2239 2240 if {![string match unknown $spec] } { 2241 $m add command -label "$tspec @ $module <$prio>" -state disabled 2242 set spied [tkecl:pred_flag_value $spec $lookup_module spy] 2243 if {$spied == "on"} { 2244 set spytext "Nospy $spec" 2245 set spyval off 2246 } else { 2247 set spytext "Spy $spec" 2248 set spyval on 2249 } 2250 $m add command -label $spytext -command \ 2251 [list tkecl:set_pred_flag $spec $lookup_module spy $spyval] 2252 $m add command -label "Display source for this predicate" -command \ 2253 [list tkecl:set_and_display_source $spec $module] 2254 if {$path_info == "no"} {set gstate disabled} else {set gstate normal} 2255 $m add command -label "Display source context for this call" -command \ 2256 "tkecl:show_source_context $invoc {$greturn}" -state $gstate 2257 $m add command -label "Inspect this goal" -command \ 2258 "tkinspect:Inspect_term_init invoc($invoc)" 2259 $m add command -label "Observe this goal" -command "tkecl:observe_goal $invoc" 2260 $m add command -label "Force failure of this goal" -command \ 2261 "tkecl:set_fail_invoc $invoc" 2262 $m add command -label "Jump to this invocation number ($invoc)" -command \ 2263 "tkecl:set_jumpto_invoc $invoc" 2264 2265 } 2266 $m add command -label "Jump to this depth $depth" -command \ 2267 "tkecl:set_jumpto_depth $depth" 2268 $m add separator 2269 $m add command -label "Refresh goal stack" -command \ 2270 "tkecl:refresh_goal_stack" 2271 2272 tk_popup $m $x $y 2273} 2274 2275proc tkecl:cleanup_goal_stack_line {depth next_line} { 2276 set ec_tracer .ec_tools.ec_tracer 2277 2278 for {set line $depth} {$line <= $next_line} {incr line 1} { 2279 set taglist [$ec_tracer.stack.text tag names $line.0] 2280 set invocidx [lsearch -regexp $taglist {^[0-9]+$}] 2281 ;# tags in the lines are also deleted 2282 if {$invocidx >= 0} { 2283 $ec_tracer.stack.text tag delete [lindex $taglist $invocidx] 2284 } 2285 } 2286 $ec_tracer.stack.text delete $depth.0 $next_line.end+1char 2287} 2288 2289proc tkecl:refresh_goal_stack {} { 2290 global tkecl 2291 2292 foreach anc [lindex [ec_rpcq {get_ancestors _} (_) tracer_tcl] 1] { 2293 foreach {pred depth invoc prio line} $anc {break} 2294 set stdepth [expr $depth+1] 2295 ;# only clean up line if it is actually there! 2296 if [.ec_tools.ec_tracer.stack.text compare end-1char > $stdepth.0] { 2297 tkecl:cleanup_goal_stack_line $stdepth $stdepth 2298 } 2299 if {[string length $line] >= $tkecl(pref,text_truncate)} { 2300 set line [string range $line 0 $tkecl(pref,text_truncate)] 2301 .ec_tools.ec_tracer.stack.text insert $stdepth.0 "\n" 2302 ;# put in the newline first, then insert things before it 2303 .ec_tools.ec_tracer.stack.text insert $stdepth.0 $line call_style 2304 .ec_tools.ec_tracer.stack.text insert $stdepth.end "..." truncate_style 2305 } else { 2306 .ec_tools.ec_tracer.stack.text insert $stdepth.0 "\n" 2307 .ec_tools.ec_tracer.stack.text insert $stdepth.0 $line call_style 2308 } 2309 tkecl:set_goalpopup $depth $invoc $prio $line 2310 } 2311 2312 .ec_tools.ec_tracer.stack.text see end 2313} 2314 2315proc tkecl:set_goalpopup {depth invoc prio line} { 2316# print goal line in the stack display and set up the tag for it 2317 set ec_tracer .ec_tools.ec_tracer 2318 set greturn [ec_rpcq_check\ 2319 [list get_goal_info_by_invoc $invoc _ _ _ _ _ _ _] (I_______) tracer_tcl] 2320 $ec_tracer.stack.text tag bind $invoc <Button-3> \ 2321 "tkecl:popup_goalmenu $ec_tracer.stack.text $invoc $depth $prio {$greturn} %X %Y; break" 2322 $ec_tracer.stack.text tag bind $invoc <Control-Button-1> \ 2323 "tkecl:popup_goalmenu $ec_tracer.stack.text $invoc $depth $prio {$greturn} %X %Y; break" 2324 $ec_tracer.stack.text tag bind info$invoc <Button-3> \ 2325 "tkecl:popup_goalmenu $ec_tracer.stack.text $invoc $depth $prio {$greturn} %X %Y; break" 2326 $ec_tracer.stack.text tag bind info$invoc <Control-Button-1> \ 2327 "tkecl:popup_goalmenu $ec_tracer.stack.text $invoc $depth $prio {$greturn} %X %Y; break" 2328 $ec_tracer.stack.text tag bind $invoc <Double-Button-1> "tkinspect:Inspect_term_init invoc($invoc); break" 2329 $ec_tracer.stack.text tag bind info$invoc <Button-1> "tkecl:show_source_context $invoc {$greturn}; break" 2330 2331 # find the information part (the part before the goal) of the line 2332 # if the format for this part changes, the regexp may also need to change 2333 if {[regexp {[^)]+\) [^ ]+ [^ ]+} $line info] == 1} { 2334 set length [string length $info] 2335 } else { 2336 # this probably shouldn't happen 2337 set length 0 2338 } 2339 set stdepth [expr $depth + 1] 2340 # $stdepth.$length is one char after the port name 2341 $ec_tracer.stack.text tag add info$invoc $stdepth.0 $stdepth.$length 2342 $ec_tracer.stack.text tag raise info$invoc 2343 incr length 2344 $ec_tracer.stack.text tag add $invoc $stdepth.$length $stdepth.end 2345 $ec_tracer.stack.text tag raise $invoc 2346} 2347 2348proc tkecl:popup_filter {} { 2349 global tkecl 2350 2351 set ec_tracer .ec_tools.ec_tracer 2352 if [winfo exists $ec_tracer.filter] { 2353 tkinspect:RaiseWindow $ec_tracer.filter 2354 return 2355 } 2356 2357 toplevel $ec_tracer.filter 2358 wm title $ec_tracer.filter "Filter" 2359 2360 label $ec_tracer.filter.label -text "Continue to a port with all of the following properties:" 2361 pack $ec_tracer.filter.label -side top 2362 frame $ec_tracer.filter.depthsettings -relief groove -bd 1 2363 pack $ec_tracer.filter.depthsettings -side top -ipadx 3 -ipady 3 -pady 5 -padx 5 -fill x 2364 2365 set row 0 2366 set col 0 2367 set cols 4 2368 2369 label $ec_tracer.filter.depthsettings.mininvoclabel -text "Invocation number from .." 2370 2371 ventry $ec_tracer.filter.depthsettings.mininvoc \ 2372 -vcmd {regexp {^[0-9]*$} %P} -validate key -invalidcmd bell \ 2373 -width 8 -textvariable tkecl(filter_mininvoc) -bg white 2374 2375 label $ec_tracer.filter.depthsettings.maxinvoclabel -text ".. to .." 2376 2377 ventry $ec_tracer.filter.depthsettings.maxinvoc \ 2378 -vcmd {regexp {^[0-9]*$} %P} -validate key -invalidcmd bell \ 2379 -width 10 -textvariable tkecl(filter_maxinvoc) -bg white 2380 2381 grid $ec_tracer.filter.depthsettings.mininvoclabel $ec_tracer.filter.depthsettings.mininvoc $ec_tracer.filter.depthsettings.maxinvoclabel $ec_tracer.filter.depthsettings.maxinvoc 2382 2383 incr row 2384 2385 label $ec_tracer.filter.depthsettings.mindepthlabel -text "Depth from .." 2386 2387 ventry $ec_tracer.filter.depthsettings.mindepth \ 2388 -vcmd {regexp {^[0-9]*$} %P} -validate key -invalidcmd bell \ 2389 -width 8 -textvariable tkecl(filter_mindepth) -bg white 2390 2391 label $ec_tracer.filter.depthsettings.maxdepthlabel -text ".. to .." 2392 2393 ventry $ec_tracer.filter.depthsettings.maxdepth \ 2394 -vcmd {regexp {^[0-9]*$} %P} -validate key -invalidcmd bell \ 2395 -width 10 -textvariable tkecl(filter_maxdepth) -bg white 2396 2397 grid $ec_tracer.filter.depthsettings.mindepthlabel $ec_tracer.filter.depthsettings.mindepth $ec_tracer.filter.depthsettings.maxdepthlabel $ec_tracer.filter.depthsettings.maxdepth -sticky w 2398 2399 frame $ec_tracer.filter.settings -relief groove -bd 1 2400 pack $ec_tracer.filter.settings -side top -ipadx 3 -ipady 3 -pady 5 -padx 5 -fill x 2401 2402 set row 0 2403 set col 0 2404 set cols 7 2405 2406 label $ec_tracer.filter.settings.ports -anchor w -text "Port types:" 2407 grid $ec_tracer.filter.settings.ports -columnspan $cols -sticky ew 2408 incr row 2409 2410 2411 foreach port $tkecl(portlist) { 2412 checkbutton $ec_tracer.filter.settings.port_$port -text $port -variable tkecl(filter_port,$port) 2413 grid $ec_tracer.filter.settings.port_$port -row $row -column $col -sticky w 2414 set col [expr ($col+1)%$cols] 2415 set row [expr $col?$row:$row+1] 2416 } 2417 set w $ec_tracer.filter.settings.portsets 2418 combobox $w -labeltext Tick -click single -editable 0 \ 2419 -listheight [llength $tkecl(portsets)] -width 8 \ 2420 -postcommand [list tkecl:combo_add_portsets $w] \ 2421 -command tkecl:tick_portset 2422 grid $w -row $row -column $col -sticky w 2423 2424 2425 frame $ec_tracer.filter.predsettings -relief groove -bd 1 2426 pack $ec_tracer.filter.predsettings -side top -ipadx 3 -ipady 3 -pady 5 -padx 5 -fill x 2427 2428 set row 0 2429 set col 0 2430 set cols 5 2431 2432 label $ec_tracer.filter.predsettings.predtypetitle -text "Predicate specification:" 2433 grid $ec_tracer.filter.predsettings.predtypetitle -columnspan $cols -sticky w 2434 incr row 2435 2436 radiobutton $ec_tracer.filter.predsettings.predtype1 -text "Any predicate" \ 2437 -variable tkecl(filter_predtype) -value any -command "tkecl:fields_disable $ec_tracer" \ 2438 2439 grid $ec_tracer.filter.predsettings.predtype1 -columnspan $cols -sticky w 2440 incr row 2441 radiobutton $ec_tracer.filter.predsettings.predtype2 -text "Any predicate with a spypoint or call with a breakpoint" \ 2442 -variable tkecl(filter_predtype) -value anyspy -command "tkecl:fields_disable $ec_tracer" 2443 grid $ec_tracer.filter.predsettings.predtype2 -columnspan 5 -sticky w 2444 incr row 2445 radiobutton $ec_tracer.filter.predsettings.predtype3 -text "Specific predicate instance:" \ 2446 -variable tkecl(filter_predtype) -value goalmatching -command "tkecl:enable_pred $ec_tracer" 2447 grid $ec_tracer.filter.predsettings.predtype3 -columnspan $cols -sticky w 2448 2449 incr row 2450 2451 label $ec_tracer.filter.predsettings.predmodule2label -text "Defining module:" 2452 label $ec_tracer.filter.predsettings.blank -text " " 2453 2454 label $ec_tracer.filter.predsettings.predmatchlabel -text "Goal template:" 2455 2456 grid x $ec_tracer.filter.predsettings.predmodule2label $ec_tracer.filter.predsettings.blank $ec_tracer.filter.predsettings.predmatchlabel -sticky w 2457 2458 incr row 2459 2460 combobox $ec_tracer.filter.predsettings.predmodule2combo -click single -listheight 6 -width 15 -editable 0 \ 2461 -postcommand [list tkecl:combo_add_modules $ec_tracer.filter.predsettings.predmodule2combo] \ 2462 -textvariable tkecl(filter_predmodule2) 2463 2464 label $ec_tracer.filter.predsettings.predmodule2colon -text ":" 2465 2466 2467 ventry $ec_tracer.filter.predsettings.predmatch -textvariable tkecl(filter_predmatch) -state disabled -width 40 2468 2469 grid x $ec_tracer.filter.predsettings.predmodule2combo $ec_tracer.filter.predsettings.predmodule2colon $ec_tracer.filter.predsettings.predmatch -sticky w 2470 2471 incr row 2472 2473 label $ec_tracer.filter.predsettings.predconditionlabel -text "Condition:" 2474 2475 grid x $ec_tracer.filter.predsettings.predconditionlabel -sticky w 2476 2477 incr row 2478 2479 ventry $ec_tracer.filter.predsettings.predcondition -textvariable tkecl(filter_predcondition) -state disabled -width 70 2480 2481 grid x $ec_tracer.filter.predsettings.predcondition -columnspan 3 -sticky w 2482 incr row 2483 2484 label $ec_tracer.filter.predsettings.predmodulelabel -text "Calling module:" 2485 2486 grid x $ec_tracer.filter.predsettings.predmodulelabel -sticky w 2487 2488 incr row 2489 2490 combobox $ec_tracer.filter.predsettings.predmodule -click single -listheight 6 -width 15 -editable 1 \ 2491 -postcommand [list tkecl:combo_add_modules $ec_tracer.filter.predsettings.predmodule] \ 2492 -textvariable tkecl(filter_predmodule) 2493 2494 grid x $ec_tracer.filter.predsettings.predmodule -sticky w 2495 2496 2497 tkecl:fields_disable $ec_tracer 2498 2499 2500 pack [frame $ec_tracer.filter.after -relief groove -bd 1] \ 2501 -side top -ipadx 3 -ipady 3 -pady 5 -padx 5 -fill x 2502 pack [frame $ec_tracer.filter.after.hits] -fill x 2503 pack [label $ec_tracer.filter.after.hits.left -text "Conditions already met "] -side left 2504 pack [label $ec_tracer.filter.after.hits.hits -textvariable tkecl(filter_hits)] -side left 2505 pack [label $ec_tracer.filter.after.hits.right -text " times using this filter."] -side left 2506 2507 2508 pack [frame $ec_tracer.filter.after.count] -fill x 2509 pack [label $ec_tracer.filter.after.count.label -text \ 2510 "Stop after the conditions have been met"] -side left 2511 pack [ventry $ec_tracer.filter.after.count.entry \ 2512 -vcmd {regexp {^[0-9]*$} %P} \-validate key -invalidcmd bell \ 2513 -width 10 -textvariable tkecl(filter_count) -bg white \ 2514 ] -side left 2515 pack [label $ec_tracer.filter.after.count.endlabel -text "time(s)."] -side left 2516 2517 button $ec_tracer.filter.go -text "Go" -state $tkecl(tracer_state) \ 2518 -command {tkecl:set_tracercommand filter} 2519 balloonhelp $ec_tracer.filter.go "Continue program execution until filter conditions hold" 2520 button $ec_tracer.filter.close -text "Close" -command "wm withdraw $ec_tracer.filter" 2521 pack $ec_tracer.filter.go $ec_tracer.filter.close -side left -expand 1 -fill x 2522 2523 focus [$ec_tracer.filter.depthsettings.mininvoc subwidget entry] 2524 return $ec_tracer.filter 2525} 2526 2527proc tkecl:combo_add_portsets {w} { 2528 global tkecl 2529 foreach portset $tkecl(portsets) { 2530 $w add $portset 2531 } 2532} 2533 2534proc tkecl:tick_portset {portset} { 2535 global tkecl 2536 2537 foreach port $tkecl(portlist) { 2538 set tkecl(filter_port,$port) 0 2539 } 2540 foreach port $tkecl(portset,$portset) { 2541 set tkecl(filter_port,$port) 1 2542 } 2543} 2544 2545proc tkecl:configure_pred {} { 2546 global tkecl 2547 2548 set changed 0 2549 2550 if {$tkecl(filter_predcondition) == ""} then { 2551 set usepredcondition true 2552 } else { 2553 set usepredcondition $tkecl(filter_predcondition) 2554 } 2555 if {$tkecl(filter_predmatch) == ""} then { 2556 set usepredmatch "_" 2557 } else { 2558 set usepredmatch $tkecl(filter_predmatch) 2559 } 2560 if {$tkecl(filter_predmodule) == ""} then { 2561 set usepredmodule "_" 2562 } else { 2563 set usepredmodule $tkecl(filter_predmodule) 2564 } 2565 2566 foreach filterprop $tkecl(filterpred,changable) { 2567 if [tkecl:check_if_changed $filterprop] { incr changed } 2568 } 2569 2570 # set_usepred_info($usepredmatch, 2571 # $usepredmodule, 2572 # $usepredmodule2, 2573 # $usepredcondition, 2574 # Status) 2575 if {$changed > 0} { 2576 # predmodule2 cannot be undefined: it is taken from a list of modules 2577 # the eclipse side code also assumes it cannot be a variable 2578 set res [ec_rpcq [list set_usepred_info \ 2579 $usepredmatch $usepredmodule $tkecl(filter_predmodule2) $usepredcondition _] \ 2580 (SSSS_) tracer_tcl] 2581 2582 switch $res { 2583 fail - 2584 throw { 2585 tk_messageBox -icon error -type ok -message "Filter Error: Exception raised when setting the conditional goal filter. Please check goal template/condition for syntax error." 2586 set status error 2587 } 2588 default { 2589 set status [lindex $res 5] 2590 if {$status == "not_found"} { 2591 tk_messageBox -icon warning -type ok -message "Filter Error: Failed to set conditional goal filter. Goal template or module may be undefined." 2592 ;# treat as an error 2593 set status error 2594 } 2595 } 2596 } 2597 set tkecl(filter,status) $status 2598 } elseif {$tkecl(filter,status) != "error"} { 2599 # enable filter goal 2600 set res [ec_rpcq reenable_usepred () tracer_tcl] 2601 switch $res { 2602 fail - 2603 throw { 2604 tk_messageBox -icon error -type ok -message "Filter Error: Exception raised when setting the conditional goal filter. Please check goal template/condition for syntax error." 2605 set tkecl(filter,status) error 2606 } 2607 default { 2608 set tkecl(filter,status) continue 2609 } 2610 } 2611} 2612 2613 return $tkecl(filter,status) 2614} 2615 2616 2617proc tkecl:fields_disable {ec_tracer} { 2618 $ec_tracer.filter.predsettings.predmatch configure -state disabled 2619 $ec_tracer.filter.predsettings.predmatch config -foreground darkgray 2620 $ec_tracer.filter.predsettings.predmatch config -background lightgray 2621 $ec_tracer.filter.predsettings.predmodule configure -state disabled 2622 $ec_tracer.filter.predsettings.predmodule config -foreground darkgray 2623 $ec_tracer.filter.predsettings.predmodule config -background lightgray 2624 $ec_tracer.filter.predsettings.predmodule2combo configure -state disabled 2625 $ec_tracer.filter.predsettings.predmodule2combo config -foreground darkgray 2626 $ec_tracer.filter.predsettings.predmodule2combo config -background lightgray 2627 $ec_tracer.filter.predsettings.predcondition configure -state disabled 2628 $ec_tracer.filter.predsettings.predcondition config -foreground darkgray 2629 $ec_tracer.filter.predsettings.predcondition config -background lightgray 2630 2631 $ec_tracer.filter.settings.port_fail configure -state normal 2632 $ec_tracer.filter.settings.port_leave configure -state normal 2633 2634} 2635 2636proc tkecl:enable_pred {ec_tracer} { 2637 global tkecl 2638 2639 $ec_tracer.filter.predsettings.predmatch configure -state normal 2640 $ec_tracer.filter.predsettings.predmatch config -foreground black 2641 $ec_tracer.filter.predsettings.predmatch config -background white 2642 $ec_tracer.filter.predsettings.predmodule configure -state normal 2643 $ec_tracer.filter.predsettings.predmodule configure -editable 1 2644 $ec_tracer.filter.predsettings.predmodule config -foreground black 2645 $ec_tracer.filter.predsettings.predmodule config -background white 2646 $ec_tracer.filter.predsettings.predmodule2combo configure -state normal 2647 $ec_tracer.filter.predsettings.predmodule2combo configure -editable 0 2648 $ec_tracer.filter.predsettings.predmodule2combo config -foreground black 2649 $ec_tracer.filter.predsettings.predmodule2combo config -background white 2650 $ec_tracer.filter.predsettings.predcondition configure -state normal 2651 $ec_tracer.filter.predsettings.predcondition config -foreground black 2652 $ec_tracer.filter.predsettings.predcondition config -background white 2653 2654 set tkecl(filter_port,fail) 0 2655 $ec_tracer.filter.settings.port_fail configure -state disabled 2656 set tkecl(filter_port,leave) 0 2657 $ec_tracer.filter.settings.port_leave configure -state disabled 2658 2659} 2660 2661 2662proc tkecl:observe_goal {invoc} { 2663 2664 tkinspect:inspect_command invoc($invoc) [list record_observed invoc($invoc) [list 1] Invocation:$invoc] {S[S*]S} 2665} 2666 2667 2668#--------------------------------------------------------------- 2669# Directory selection 2670#--------------------------------------------------------------- 2671proc tkecl:get_newcwd {} { 2672 tkecl:newcwd [tkecl:getDirectory [pwd] "Set Current Working Directory"] 2673} 2674 2675# change eclipse's cwd and set $tkecl(cwd) to its eclipse name 2676proc tkecl:newcwd {newdir} { 2677 global tkecl 2678 2679 if {![string match "" $newdir]} { 2680 set tkecl(cwd) [lindex [ec_rpcq [list os_file_name _ $newdir] {(_S)}] 1] 2681 ;# cd now done in ECLiPSe to ensure that it is the ECLiPSe side's 2682 ;# cwd that is changed 2683 switch [ec_rpcq [list cd $tkecl(cwd)] {(S)}] { 2684 fail - 2685 throw { 2686 tk_messageBox -icon warning -type ok -message "Unable to set current directory to $newdir" 2687 } 2688 } 2689 2690 } 2691} 2692 2693proc tkecl:paths_menu {p name} { 2694 set menu [menu $p.m -tearoff 0 -postcommand [list tkecl:build_path_menu $p.m $p $name]] 2695} 2696 2697proc tkecl:build_path_menu {menu p name} { 2698 global tkecl 2699 2700 $menu delete 0 end ;# get rid of old entries 2701 $menu add command -label "Add a new directory" -command \ 2702 [list tkecl:add_new_path $name] 2703 $menu add separator 2704 2705 set i 0 2706 foreach {item} $tkecl($name) { 2707 ;# probably treat all spaces as breaks in name! 2708 $menu add command -label $item -command [list tkecl:change_one_path $name $p $item $i] 2709 incr i 2710 } 2711} 2712 2713proc tkecl:add_new_path {name} { 2714 global tkecl 2715 2716 tkecl:gui_edit_one_path Insert $name [pwd] 0 2717 2718 if {[llength $tkecl($name)] != 0} { 2719 ec_rpcq [list set_flag $name $tkecl($name)] {(()[S*])} 2720 } 2721 2722} 2723 2724proc tkecl:getDirectory {initdir title} { 2725 return [tkecl:get_path_popup $initdir directory \ 2726 [list tk_chooseDirectory -initialdir $initdir -title $title]] 2727} 2728 2729proc tkecl:getEcFile {initdir title} { 2730 global tkecl 2731 2732 # we used to have -initialfile $tkecl(last_source_file), but that 2733 # overrides -initialdir, and is not available on Aqua Tk (b418) 2734 set tkecl(last_source_file) \ 2735 [tkecl:get_path_popup $initdir "file" [list tk_getOpenFile \ 2736 -defaultextension $tkecl(pref,defaultextension) \ 2737 -filetypes $tkecl(filetypes) -title $title \ 2738 -initialdir $initdir \ 2739 ] \ 2740 ] 2741 return $tkecl(last_source_file) 2742} 2743 2744# like tkecl:getEcFile but allows non-existing files to be selected 2745# note that underlying widget has `Save' for the select button, and also 2746# a warning about overwritting the file if the file already exists. 2747# *No* file is saved, only the filename is returned. Should try and see 2748# if we can disable this `feature' 2749proc tkecl:getNewEcFile {initdir title} { 2750 global tkecl 2751 2752 set tkecl(last_source_file) \ 2753 [tkecl:get_path_popup $initdir "file" [list tk_getSaveFile \ 2754 -defaultextension $tkecl(pref,defaultextension) \ 2755 -filetypes $tkecl(filetypes) -title $title -initialdir $initdir \ 2756 ] \ 2757 ] 2758 return $tkecl(last_source_file) 2759} 2760 2761 2762# only allow a GUI path selection if embedded, or if Tcl side has same host as 2763# ECLiPSe side, as filespace may be different otherwise 2764proc tkecl:get_path_popup {initpath pathtype browsecmd} { 2765 global tkecl 2766 2767 set echostname [lindex [ec_rpcq [list get_flag hostname _] (()_)] 2] 2768 if {([ec_interface_type] == "embedded") || 2769 ([string compare [info hostname] $echostname] == 0)} { 2770 return [eval $browsecmd] 2771 2772 } else { 2773 ;# ask user to type in path name instead 2774 set tkecl(get_path_name) $initpath 2775 set gdir [toplevel .ec_tools.get_path] 2776 wm title $gdir "Get $pathtype name" 2777 pack [frame $gdir.bf] -side bottom -expand true -fill x 2778 pack [entry $gdir.e -relief sunken -width 25 -textvariable tkecl(get_dir_name)] -side right -expand true -fill x 2779 pack [label $gdir.l -text "Please type in the $pathtype name"] -side left 2780 pack [button $gdir.bf.ok -command "destroy $gdir" -text OK] -side left -expand true -fill x 2781 pack [button $gdir.bf.cancel -text Cancel -command "set tkecl(get_path_name) {}; destroy $gdir"] -side right -expand true -fill x 2782 bind $gdir.e <Return> "destroy $gdir" 2783 $gdir.e xview moveto 1.0 2784 $gdir.e icursor end 2785 focus $gdir.e 2786 tkwait window $gdir 2787 return $tkecl(get_path_name) 2788 } 2789} 2790 2791proc tkecl:change_one_path {name p item i} { 2792 global tkecl 2793 2794 set w $p.change 2795 2796 if ![winfo exists $w] { 2797 set old [focus] 2798 set tkecl(path_to_change) [lindex [ec_rpcq [list os_file_name $item _] \ 2799 (S_)] 2] 2800 toplevel $w 2801 wm title $w "Change one path for $name" 2802 tkwait visibility $w 2803 focus $w 2804 grab $w 2805 pack [entry $w.e -bg white -width 40 -textvariable tkecl(path_to_change) \ 2806 -relief sunken] -side top -expand 1 -fill both 2807 bind $w.e <Return> [list tkecl:perform_path_change Replace $name \ 2808 $tkecl(path_to_change) $i] 2809 pack [button $w.replace -command [list tkecl:gui_edit_one_path Replace $name\ 2810 $item $i] -text Replace] -side left -expand 1 -fill both 2811 pack [button $w.delete -command [list tkecl:perform_path_change Delete $name \ 2812 $item $i] -text Delete] -side left -expand 1 -fill both 2813 pack [button $w.insert -command [list tkecl:gui_edit_one_path Insert $name \ 2814 $item $i] -text Insert] -side left -expand 1 -fill both 2815 pack [button $w.cancel -text Cancel -command "destroy $w; set tkecl($name) [list $tkecl($name)]"] -side left -expand 1 -fill both 2816 } 2817 tkwait variable tkecl($name) 2818 2819 if {[llength $tkecl($name)] == 0} { 2820 ec_rpcq [list set_flag $name $tkecl($name)] {(()[])} 2821 } else { 2822 ec_rpcq [list set_flag $name $tkecl($name)] {(()[S*])} 2823 } 2824 grab release $w 2825 focus $old 2826 destroy $w 2827 2828} 2829 2830proc tkecl:gui_edit_one_path {action name path i} { 2831 global tkecl 2832 2833 set path [lindex [ec_rpcq [list os_file_name $path _] (S_) ] 2] 2834 set new [tkecl:getDirectory $path "$action a path"] 2835 if ![string match "" $new] { 2836 set new [lindex [ec_rpcq [list os_file_name _ $new] (_S) ] 1] 2837 tkecl:perform_path_change $action $name $new $i 2838 } else { 2839 set tkecl($name) $tkecl($name) ;# make sure that tkwait does get its `changes' 2840 } 2841} 2842 2843proc tkecl:perform_path_change {action name new i} { 2844 global tkecl 2845 2846 switch -exact -- $action { 2847 Replace { 2848 set tkecl($name) [lreplace $tkecl($name) $i $i $new] 2849 } 2850 Insert { 2851 set tkecl($name) [linsert $tkecl($name) $i $new] 2852 } 2853 Delete { 2854 set tkecl($name) [lreplace $tkecl($name) $i $i] 2855 } 2856 } 2857} 2858 2859#--------------------------------------------------------------- 2860# Change Output mode 2861#--------------------------------------------------------------- 2862 2863proc tkecl:Set_output_mode {popmode return} { 2864 global outputmodes 2865 2866 bind $popmode <Enter> {focus %W} 2867 foreach {f modes status descr unsetd triopts tridesc tristatus} [lindex $return 2] { 2868 set i -1 2869 foreach m $modes s $status d $descr u $unsetd { 2870 set l $m 2871 if [string match "." $m] {set m period} ;# catch special chars. here 2872 set outputmodes($popmode.l$m) $s 2873 set outputmodes($popmode.l$m,set) $d 2874 set outputmodes($popmode.l$m,unset) $u 2875 incr i 2876 grid [checkbutton $popmode.c$m -onvalue 1 -offvalue 0 -text $l\ 2877 -anchor w -variable outputmodes($popmode.l$m) -command "tkecl:Change_output_options $m $popmode.l$m"] \ 2878 -sticky news -row $i -column 0 2879 if {$s == 1} { 2880 set label $d 2881 } else { 2882 set label $u 2883 } 2884 grid [label $popmode.l$m -text $label] -sticky w -row $i -column 1 2885 bind $popmode <Key-$m> { 2886 regexp {^(.+)\.[^\.]+$} %W null parent 2887 set lw $parent.l%K 2888 if {$outputmodes($lw) == 1} { 2889 set outputmodes($lw) 0 2890 } else { 2891 set outputmodes($lw) 1 2892 } 2893 tkecl:Change_output_options %K $lw 2894 } 2895 2896# balloonhelp $popmode.c$m $d 2897 } ;# foreach m ... 2898 2899 set trinames "" 2900 foreach tri0 $triopts tdes0 $tridesc s $tristatus { 2901 incr i 2902 set f [frame $popmode.c$i] 2903 set tri [lrange $tri0 1 end] ;# drop functor 2904 set tdes [lrange $tdes0 1 end] 2905 set name "" 2906 append name [lindex $tri 0] [lindex $tri 1] 2907 lappend trinames $name 2908 set j 0 2909 set outputmodes($popmode,t$name) $s 2910 set outputmodes($popmode,t$name,s) $tri 2911 set outputmodes($popmode,t$name,d) $tdes 2912 foreach mode $tri d $tdes { 2913 grid [radiobutton $f.b$mode -variable outputmodes($popmode,t$name) \ 2914 -text $mode -value $mode -anchor w\ 2915 -command "tkecl:Change_output_trioptions $mode $name \ 2916 $popmode.l$name $popmode"] -row 0 -column $j 2917 incr j 2918 if [string match $mode $s] { 2919 grid [label $popmode.l$name -text $d] -sticky w -row $i -column 1 2920 } 2921 } 2922 grid $f -sticky news -row $i -column 0 2923 } 2924 grid [button $popmode.end -command "destroy $popmode" -text Set] \ 2925 -sticky news -row [expr $i + 1] -column 0 -columnspan 2 2926# -sticky news -row [expr ($i/3) + 1] -column 0 -columnspan 3 2927 } 2928 tkwait window $popmode 2929 set newmodes "\"" 2930 foreach m $modes { 2931 set l $m 2932 if [string match "." $m] {set m period} ;# catch special chars. here 2933 if {$outputmodes($popmode.l$m) == 1} { 2934 append newmodes $l 2935 } 2936 } 2937 foreach name $trinames { ;# add in the tristate modes 2938 if {![string match $outputmodes($popmode,t$name) off]} { 2939 append newmodes $outputmodes($popmode,t$name) 2940 } 2941 } 2942 return [append newmodes \"] 2943 2944} 2945 2946# update label for the simple output options 2947proc tkecl:Change_output_options {mode w} { 2948 global outputmodes 2949 2950 ;# called after mode has been changed to new value 2951 if {$outputmodes($w) == 1} { 2952 $w configure -text $outputmodes($w,set) 2953 } else { 2954 $w configure -text $outputmodes($w,unset) 2955 } 2956} 2957 2958# update label for the tri-state options 2959proc tkecl:Change_output_trioptions {selected name label w} { 2960 global outputmodes 2961 2962 foreach opt $outputmodes($w,t$name,s) d $outputmodes($w,t$name,d) { 2963 ;# find the one that matches selected 2964 if [string match $selected $opt] { 2965 $label configure -text $d 2966 } 2967 } 2968} 2969 2970 2971#---------------------------------------------------------------------- 2972# Compile note pad 2973#---------------------------------------------------------------------- 2974 2975proc tkecl:compile_pad {} { 2976 2977 set w .ec_tools 2978 if [winfo exists $w.cpad] { 2979 tkinspect:RaiseWindow $w.cpad 2980 return 2981 } 2982 set pad [toplevel $w.cpad] 2983 wm title $pad "Compile scratch-pad" 2984 text $pad.t -wrap none -bg white -yscrollcommand "$pad.vscroll set" -xscrollcommand "$pad.hscroll set" 2985 set bbar [frame $pad.bbar] 2986 pack $bbar -side bottom -fill x 2987 pack [button $bbar.com -text "Compile All" -command "tkecl:do_compile_all $pad.t"] -side left -expand 1 -fill x 2988 pack [button $bbar.sel -text "Compile Selection" -command "tkecl:do_compile_sel $pad.t"] -side left -expand 1 -fill x 2989 pack [button $bbar.end -text Close -command "wm withdraw $w.cpad"] -side left -expand 1 -fill x 2990 pack [scrollbar $pad.vscroll -command "$pad.t yview"] -side right -fill y 2991 pack [scrollbar $pad.hscroll -command "$pad.t xview" -orient horizontal] -side bottom -fill x 2992 pack $pad.t -expand 1 -fill both 2993 bind $pad <Alt-h> "tkecl:Get_helpfileinfo scra $pad" 2994 balloonhelp $bbar "Type in (short) ECLiPSe code for compilation. Can compile everything in window, or only selection." 2995 focus $pad.t 2996 2997} 2998 2999proc tkecl:do_compile_all {t} { 3000 ec_rpcq_check [list compile_string [$t get 1.0 end]] (S) tracer_tcl 3001} 3002 3003proc tkecl:do_compile_sel {t} { 3004 foreach {start end} [$t tag ranges sel] { 3005 ec_rpcq_check [list compile_string [$t get $start $end]] (S) tracer_tcl 3006 } 3007} 3008 3009 3010#---------------------------------------------------------------------- 3011# Statistics display 3012#---------------------------------------------------------------------- 3013proc tkecl:handle_statistics {} { 3014 global tkecl 3015 3016 tkecl:create_stat_window 3017 set data [lindex [ec_rpcq_check [list report_stats $tkecl(pref,stats_interval) _] (D_) tracer_tcl] 2] 3018 tkecl:display_stat $data 3019} 3020 3021proc tkecl:display_stat {data} { 3022 global tkecl 3023 3024 ;# colours are in pairs: dark and light versions 3025 set ec_stats .ec_tools.ec_stats 3026 if ![winfo exists $ec_stats] { 3027 return 3028 } 3029 3030 set colours [list #00d040 #00f090 #c00000 #f00000 #c0c000 #ffff00 \ 3031 #b000b0 #f000f0 #c07000 #ff9000 #50d0b0 #a0ffe0 #000090 #0000ff] 3032 set cindex 0 3033 set h 85 ;# these are for the pie charts 3034 set w 85 3035 foreach item $data { 3036 switch -exact -- [lindex $item 0] { 3037 times { 3038 set user [lindex $item 1] 3039 set real [lindex $item 2] 3040 foreach {gctime ngc gccol gcratio} [lrange [lindex $item 3] 1 end] { 3041 break 3042 } 3043 set tframe $ec_stats.times 3044 set textf $tframe.text 3045 set pie $tframe.pie 3046 if ![winfo exists $tframe] { 3047 pack [frame $tframe] -side top 3048 pack [canvas $pie -width [expr $w + 10] -height [expr $h + 10]] -side left 3049 pack [frame $textf] -side right 3050 pack [frame $textf.times -relief ridge -borderwidth 3] -side top -padx 2 -pady 2 3051 grid [label $textf.times.a -text "total time" -width 15 -anchor e] -row 1 -column 0 3052 grid [label $textf.times.b -text "gc time" -width 15 -anchor e] -row 1 -column 1 3053 grid [label $textf.times.c -text "\% user" -width 10 -anchor e] -row 1 -column 2 3054 grid [label $textf.times.user -width 15 -anchor e] -row 2 -column 0 3055 grid [label $textf.times.gc -width 15 -anchor e] -row 2 -column 1 -padx 2 -pady 2 3056 grid [label $textf.times.userf -width 10 -anchor e] -row 2 -column 2 -padx 2 -pady 2 3057 grid [label $textf.times.label -text "User CPU Time"] -row 0 -column 0 -columnspan 2 -sticky news 3058 pack [frame $textf.gc -relief ridge -borderwidth 3] -side bottom 3059 grid [label $textf.gc.a -text "total collected" -width 16 -anchor e] -row 1 -column 0 3060 grid [label $textf.gc.b -text "\# gc" -width 9 -anchor e] -row 1 -column 1 3061 grid [label $textf.gc.c -text "% recovered" -width 15 -anchor e] -row 1 -column 2 3062 grid [label $textf.gc.col -width 16 -anchor e] -row 2 -column 0 3063 grid [label $textf.gc.ngc -width 9 -anchor e] -row 2 -column 1 3064 grid [label $textf.gc.ratio -width 15 -anchor e] -row 2 -column 2 3065 grid [label $textf.gc.label -text "Garbage Collection"] -row 0 -column 0 -columnspan 3 -sticky news 3066 set tkecl(stat,times,user) 0 3067 set tkecl(stat,times,real) 0 3068 balloonhelp $pie "Portion of total time spent on garbage collection with respect to total user CPU time" 3069 balloonhelp $textf.gc "Garbage collection statistics" 3070 balloonhelp $textf.times "Timing statistics" 3071 } 3072 3073 $textf.times.user configure -text "$user" 3074 $textf.times.gc configure -text "[expr round($gctime*100)/100.0]" 3075 $textf.times.userf configure -text \ 3076 "[expr round( ($user - $tkecl(stat,times,user)) / \ 3077 ($real - $tkecl(stat,times,real)) * 10000) / 100.0]" 3078 set tkecl(stat,times,user) $user 3079 set tkecl(stat,times,real) $real 3080 3081 $textf.gc.ngc configure -text "$ngc" 3082 $textf.gc.ratio configure -text "[expr round($gcratio*100)/100.0]" 3083 $textf.gc.col configure -text "$gccol" 3084 $pie create oval 10 10 $h $w -fill white 3085 if {$ngc != 0} { 3086 set extent [expr -360*$gctime/$user] 3087 $pie create arc 10 10 $h $w -start 90 -extent $extent -style pieslice -fill blue 3088 } 3089 } 3090 3091 memory { 3092 set total [lindex $item 2] 3093 set mname [lindex $item 1] 3094 set ref [lindex $item 3] 3095 set mframe $ec_stats.$mname 3096 set pie $mframe.pie 3097 set textf $mframe.text 3098 if ![winfo exists $mframe] { 3099 pack [frame $mframe -relief sunken -borderwidth 2] -side top 3100 pack [canvas $pie -width [expr $w + 20] -height [expr $h + 10]] -side left 3101 pack [frame $textf] -side right 3102 pack [frame $textf.headings] -side top -expand 1 -fill x 3103 grid [label $textf.headings.main -text [string toupper $mname 0 0] -anchor w] -row 0 -column 0 -columnspan 4 -sticky news 3104 grid [label $textf.headings.a -text {} -width 8 -anchor e] -row 1 -column 0 -sticky news 3105 grid [label $textf.headings.b -text used -width 11 -anchor e] -row 1 -column 1 -sticky news 3106 grid [label $textf.headings.c -text alloc -width 11 -anchor e] -row 1 -column 2 -sticky news 3107 grid [label $textf.headings.d -text peak -width 11 -anchor e] -row 1 -column 3 -sticky news 3108 3109 balloonhelp $textf "Memory statistics (in bytes) for the $mname memory area" 3110 balloonhelp $pie "Proportion of memory used/allocated in the $mname area with respect to $ref" 3111 3112 } 3113 $pie create oval 10 10 $h $w -fill white 3114 3115 set direction -1.0 3116 foreach component [lrange $item 4 end] { 3117 switch -exact -- [lindex $component 0] { 3118 stack { 3119 foreach {cname alloc used peak} [lrange $component 1 end] { 3120 break 3121 } 3122 # without round() here we get funny effects with the pie charts on Windows 3123 set startused 90 3124 set extentused [expr round($direction*$used/$total*360)] 3125 set startfree [expr $startused + $extentused] 3126 set extentfree [expr round($direction*($alloc-$used)/$total*360)] 3127 set dcol [lindex $colours $cindex] 3128 incr cindex 1 3129 set lcol [lindex $colours $cindex] 3130 incr cindex 1 3131 3132 set cframe $textf.$cname 3133 if ![winfo exists $cframe] { 3134 pack [frame $cframe] -side bottom -expand 1 -fill x 3135 grid [label $cframe.name -text $cname -width 8 -anchor e] -row 0 -column 0 -sticky news 3136 grid [label $cframe.used -foreground $dcol -width 11 -anchor e] -row 0 -column 1 -sticky news 3137 grid [label $cframe.alloc -foreground $lcol -width 11 -anchor e] -row 0 -column 2 -sticky news 3138 grid [label $cframe.peak -width 11 -anchor e] -row 0 -column 3 -sticky news 3139 } 3140 $cframe.alloc configure -text $alloc 3141 $cframe.used configure -text $used 3142 $cframe.peak configure -text $peak 3143 3144 $pie create arc 10 10 $h $w -start $startused -extent $extentused -style pieslice -fill $dcol 3145 $pie create arc 10 10 $h $w -start $startfree -extent $extentfree -style pieslice -fill $lcol 3146 } 3147 } 3148 set direction [expr -$direction] 3149 } 3150 } 3151 } 3152 } 3153} 3154 3155proc tkecl:create_stat_window {} { 3156 3157 set ec_stats .ec_tools.ec_stats 3158 if {![winfo exists $ec_stats]} { 3159 toplevel $ec_stats 3160 wm title $ec_stats "ECLiPSe statistics" 3161 wm resizable $ec_stats 0 0 3162 pack [frame $ec_stats.buttons] -side bottom -expand 1 -fill x 3163 pack [button $ec_stats.buttons.change -command "tkecl:change_stat_interval" -text "Change interval"] -side left -expand 1 -fill x 3164 pack [button $ec_stats.buttons.close -command "tkecl:kill_stat_window" -text "Close"] -side right -expand 1 -fill x 3165 bind $ec_stats <Alt-h> "tkecl:Get_helpfileinfo stat $ec_stats" 3166 3167 balloonhelp $ec_stats.buttons.change "Change the time interval with which the statistics are updated" 3168 balloonhelp $ec_stats.buttons.close "Close this window and quit monitoring statistics" 3169 } else { 3170 tkinspect:RaiseWindow $ec_stats 3171 } 3172} 3173 3174 3175proc tkecl:change_stat_interval {} { 3176 global tkecl 3177 3178 set tkecl(stats_interval1) $tkecl(pref,stats_interval) 3179 set w .ec_tools.ec_stats.interval 3180 if {![winfo exists $w]} { 3181 toplevel $w 3182 wm title $w "Statistics Reporting Interval" 3183 pack [frame $w.f] -side top 3184 pack [label $w.f.l -text "New reporting interval (sec.)"] -side left 3185 pack [entry $w.f.e -relief sunken -width 10 -textvariable tkecl(stats_interval1)] -side right -expand 1 -fill both 3186 pack [button $w.set -text "Set" -command "tkecl:set_stat_interval $w"] -side left -fill x -expand 1 3187 pack [button $w.cancel -text "Cancel" -command "destroy $w"] -side left -fill x -expand 1 3188 bind $w.f.e <Return> "tkecl:set_stat_interval $w" 3189 focus $w.f.e 3190 3191 balloonhelp $w "Change time interval at which the statistics are \ 3192 updated in the statistics window.\nType in a positive number \ 3193 and click `Set' to change, or `Cancel' to not change" 3194 } else { 3195 tkinspect:RaiseWindow $w 3196 focus $w.f.e 3197 } 3198} 3199 3200proc tkecl:set_stat_interval {w} { 3201 global tkecl 3202 3203 if [regexp {^([0-9]+[.][0-9]+)|([0-9]+)$} $tkecl(stats_interval1)] { 3204 set tkecl(pref,stats_interval) $tkecl(stats_interval1) 3205 ec_rpcq_check [list change_report_interval $tkecl(pref,stats_interval)] (D) tracer_tcl 3206 destroy $w 3207 } else { 3208 set tkecl(stats_interval1) $tkecl(pref,tats_interval) 3209 bell 3210 } 3211} 3212 3213proc tkecl:kill_stat_window {} { 3214 ec_rpcq stop_report_stats () tracer_tcl 3215 destroy .ec_tools.ec_stats 3216} 3217 3218proc tkecl:handle_stats_report {stream {length {}}} { 3219 tkecl:display_stat [ec_read_exdr [ec_streamnum_to_channel $stream]] 3220} 3221 3222#---------------------------------------------------------------------- 3223# Grace-style term matrix display 3224#---------------------------------------------------------------------- 3225proc tkecl:handle_mat_flush {stream {length {}}} { 3226 global tkecl_displayvals 3227 3228 set commandline [ec_read_exdr [ec_streamnum_to_channel $stream]] 3229 set command [lindex $commandline 0] 3230 ;#puts "line-$commandline" 3231 set name [lindex $commandline 1] ;# name is the numeric identifier for matrix 3232 3233 set ec_matdisplay .ec_tools.ec_matdisplay$name 3234 if {![winfo exists $ec_matdisplay]} { 3235 if {[string match setup $command]} { ;# initial setup 3236 foreach {ecname row col module} [lrange $commandline 2 end] { 3237 append title $ecname "@" $module 3238 set tkecl_displayvals($name,ecname) $ecname 3239 set tkecl_displayvals($name,module) $module 3240 tkecl:setup_disptable $name $title $row $col 3241 } 3242 return 3243 } else { 3244 ;# matrix display window not there, and we are not initialising 3245 ;# been kill explicitly, do not redisplay 3246 return 3247 } 3248 } 3249 3250 switch -exact -- $command { 3251 setup { 3252 tk_messageBox -type ok -message "Display matrix protocol error: trying to initialise existing matrix" 3253 } 3254 3255 disp { 3256 3257 foreach {row col new ground back} [lrange $commandline 2 end] { 3258 if {$tkecl_displayvals($name,$row,$col,stop) == 1} { 3259 append id r $row c $col 3260 set tkecl_displayvals($name,$row,$col,prev) \ 3261 [lindex [$ec_matdisplay.$id config -text] end] 3262 if {$tkecl_displayvals($name,update) == 0 && \ 3263 [string match nonground $ground]} { 3264 return 3265 } 3266 $ec_matdisplay.$id config -text $new 3267 if [string match $back back] { 3268 ;#set tkecl_displayvals($name,back) 1 3269 set tkecl_displayvals($name,back) [list $row $col] 3270 set colour pink 3271 } else { 3272 ;#set tkecl_displayvals($name,back) 0 3273 set colour beige 3274 } 3275 $ec_matdisplay.$id config -foreground black 3276 $ec_matdisplay.$id config -background $colour 3277 $ec_matdisplay.b.cont configure -state normal 3278 tkinspect:RaiseWindow $ec_matdisplay 3279 tkwait variable tkecl_displayvals($name,cont) 3280 set tkecl_displayvals($name,back) [list 0 0] 3281 if [winfo exists $ec_matdisplay] { 3282 $ec_matdisplay.$id config -background lightgray 3283 $ec_matdisplay.b.cont configure -state disabled 3284 } 3285 } elseif {(($tkecl_displayvals($name,update) == 1) || 3286 ![string match nonground $ground])} { 3287 append id r $row c $col 3288 set tkecl_displayvals($name,$row,$col,prev) \ 3289 [lindex [$ec_matdisplay.$id config -text] end] 3290 $ec_matdisplay.$id config -text $new 3291 if [string match $back back] { 3292 $ec_matdisplay.$id config -foreground red 3293 } else { 3294 $ec_matdisplay.$id config -foreground black 3295 } 3296 } 3297 } 3298 3299 } 3300 3301 interact { 3302 $ec_matdisplay.b.cont configure -state normal 3303 tkwait variable tkecl_displayvals($name,cont) 3304 if [winfo exists $ec_matdisplay] { 3305 $ec_matdisplay.b.cont configure -state disabled 3306 } 3307 } 3308 3309 kill { 3310 destroy $ec_matdisplay 3311 } 3312 3313 3314 } 3315} 3316 3317proc tkecl:setup_disptable {name title row col} { 3318 global tkecl_displayvals 3319 3320 set tkecl_displayvals($name,cont) 0 3321 ;#set tkecl_displayvals($name,back) 0 3322 set tkecl_displayvals($name,back) [list 0 0] 3323 set parent [toplevel .ec_tools.ec_matdisplay$name] 3324 wm title $parent "Term display for $title" 3325 set tkecl_displayvals($name,row) $row 3326 set tkecl_displayvals($name,col) $col 3327 set tkecl_displayvals($name,update) 1 3328 bind $parent <Button-3> "tkecl:display_popup $parent %W $name $row %X %Y" 3329 bind $parent <Control-Button-1> "tkecl:display_popup $parent %W $name $row %X %Y" 3330 3331 for {set i 1} {$i <= $row} {incr i 1} { 3332 grid [label $parent.r$i -text $i -relief groove -width 5 -fg red -bg lightblue] -row $i -column 0 -sticky news 3333 } 3334 for {set i 1} {$i <= $col} {incr i 1} { 3335 grid [label $parent.c$i -text $i -relief groove -width 15 -fg red -bg lightblue] -row 0 -column $i -sticky news 3336 } 3337 for {set i 1} {$i <= $row} {incr i 1} { 3338 for {set j 1} {$j <= $col} {incr j 1} { 3339 set id "" 3340 append id r $i c $j 3341 grid [label $parent.$id -text "-- unknown --" -relief ridge -width 15] -row $i -column $j -sticky news 3342 bind $parent.$id <Double-Button-1> "tkinspect:Inspect_term_init display($name,$i,$j)" 3343 set tkecl_displayvals($name,$i,$j,stop) 0 3344 } 3345 } 3346 grid [frame $parent.b] -row [expr $row + 1] -column 0 -columnspan [expr $col + 1] -sticky news 3347 pack [button $parent.b.cont -text "Continue" -command \ 3348 "set tkecl_displayvals($name,cont) 1"] -side left -fill x -expand 1 3349 pack [button $parent.b.kill -text "Kill display" -command "destroy $parent"] -side right -fill x 3350 pack [checkbutton $parent.b.update -text "Update on ground" -variable \ 3351 tkecl_displayvals($name,update) -onvalue 0 -offvalue 1] \ 3352 -side right -fill x 3353 pack [button $parent.b.stop -text "stop all" -command \ 3354 "tkecl:all_mat_break 1 $name $row $col"] -side right -fill x 3355 pack [button $parent.b.go -text "stop none" -command \ 3356 "tkecl:all_mat_break 0 $name $row $col"] -side right -fill x 3357 3358 bind $parent.b.kill <Destroy> "tkecl:kill_display_matrix $name" 3359 3360 for {set j 1} {$j <= $col} {incr j 1} { 3361 grid columnconfigure $parent $j -weight 1 3362 } 3363 3364 for {set j 1} {$j <= [expr $row]} {incr j 1} { 3365 grid rowconfigure $parent $j -weight 1 3366 } 3367 balloonhelp $parent "Monitor changes on terms: each matrix cell represents\ 3368 a term and show its current value.\n Right (or control-left) click on cell to get \ 3369 options. Double left click on cell to inspect\n the term in the \ 3370 cell. Current and previous (pre-update) values are shown.\n \ 3371 On break, changes due to forward execution shown in yellow,\ 3372 changes due to backtracking shown in pink." 3373 balloonhelp $parent.b.cont "Click to continue execution until next break-point.\n (if set, a break-point occurs when a cell is updated)" 3374 balloonhelp $parent.b.stop "Set break-points on all cells" 3375 balloonhelp $parent.b.go "Unset break-points on all cells" 3376 balloonhelp $parent.b.update "Control update events -- if set, only update when cell becomes ground.\n Otherwise, updates depends on make_display_matrix" 3377 balloonhelp $parent.b.kill "Click to kill this display matrix -- program will continue to run without the display matrix" 3378 bind $parent <Alt-h> "tkecl:Get_helpfileinfo disp $parent" 3379} 3380 3381 3382proc tkecl:kill_display_matrix {name} { 3383global tkecl_displayvals 3384# if needed, will go to ECLiPSe side to execute kill_display_matrix 3385 3386 3387 set tkecl_displayvals($name,cont) 1 3388 ;# make sure execute will continue 3389 ;# clean up and remove all Tcl vars associated with this display matrix 3390 foreach matvar [array names tkecl_displayvals $name,*] { 3391 unset tkecl_displayvals($matvar) 3392 } 3393} 3394 3395proc tkecl:all_mat_break {state name row col} { 3396 global tkecl_displayvals 3397 3398 for {set i 1} {$i <= $row} {incr i 1} { 3399 for {set j 1} {$j <= $col} {incr j 1} { 3400 set tkecl_displayvals($name,$i,$j,stop) $state 3401 } 3402 } 3403} 3404 3405proc tkecl:display_popup {p w name nrow x y} { 3406 global tkecl_displayvals 3407 3408 3409 if [string match disabled [lindex [$p.b.cont configure -state] end]] {return} 3410 set widgetinfo [grid info $w] 3411 foreach {option value} $widgetinfo { 3412 set widget($option) $value 3413 } 3414 if {(![info exists widget(-row)] || $widget(-row) == 0 || $widget(-column) == 0)} { 3415 return 3416 } 3417 if [winfo exists $p.popup] { 3418 destroy $p.popup 3419 } 3420 set m [menu $p.popup -tearoff 0] 3421 $m add command -label "current: [lindex [$w configure -text] end]" ;#-state disabled 3422 $m add command -label "previous: $tkecl_displayvals($name,$widget(-row),$widget(-column),prev)" -state disabled 3423 $m add check -label "Break on updates" -onvalue 1 -offvalue 0 \ 3424 -variable tkecl_displayvals($name,$widget(-row),$widget(-column),stop) 3425 ;#if {$tkecl_displayvals($name,back) == 0} 3426 foreach {brow bcol} $tkecl_displayvals($name,back) {break} 3427 if {$brow != $widget(-row) || $bcol != $widget(-column)} { 3428 $m add command -label "Inspect this term" -command \ 3429 "tkinspect:Inspect_term_init display($name,$widget(-row),$widget(-column))" 3430 } 3431 3432# $m add command -label "row: $widget(-row) col: $widget(-column)" 3433 tk_popup $m $x $y 3434} 3435 3436#---------------------------------------------------------------------- 3437# Source Display 3438#---------------------------------------------------------------------- 3439 3440proc tkecl:setup_source_debug_window {} { 3441 global tkecl 3442 3443 # setup source debug window, text display for source is not packed, as 3444 # it needs to have source text added before displaying it 3445 set ec_source .ec_tools.ec_tracer.tab.source 3446 set tkecl(source_debug,file) "" 3447 3448 .ec_tools.ec_tracer.tab add "Source Context" -window [frame $ec_source] 3449# label $ec_source.label -text "Source Context" 3450 frame $ec_source.context -relief sunken -borderwidth 1 -bg white 3451 frame $ec_source.control 3452 3453 pack $ec_source.context -side bottom -fill both -expand 1 3454# pack $ec_source.label -side top -fill x 3455 scrollbar $ec_source.context.vscroll -command "$ec_source.context.text yview" 3456 scrollbar $ec_source.context.hscroll -command "$ec_source.context.text xview" -orient horizontal 3457 text $ec_source.context.lineno -borderwidth 0 -bg white -width 5 -wrap none -yscrollcommand [list tkecl:vscroll-sync "$ec_source.context.status $ec_source.context.text"] 3458 text $ec_source.context.status -borderwidth 0 -bg white -width 1 -wrap none -yscrollcommand [list tkecl:vscroll-sync "$ec_source.context.lineno $ec_source.context.text"] 3459 text $ec_source.context.text -borderwidth 0 -bg white -xscrollcommand "$ec_source.context.hscroll set" -wrap none -yscrollcommand [list tkecl:vscroll-sync "$ec_source.context.lineno $ec_source.context.status"] 3460 pack $ec_source.context.vscroll -side left -fill y 3461 pack $ec_source.context.hscroll -side bottom -fill x 3462 pack $ec_source.context.lineno -side left -fill y 3463 pack $ec_source.context.status -side left -fill y 3464 pack $ec_source.context.text -side right -fill both -expand 1 3465 bind $ec_source.context.text <Double-Button-1> \ 3466 "tkecl:display_source_for_callport $ec_source.context.text; break" 3467 bind $ec_source.context.lineno <Any-Key> "tkecl:readonly_keypress %A" 3468 bind $ec_source.context.lineno <ButtonRelease-2> {break} 3469 3470 bind $ec_source.context.status <Any-Key> "tkecl:readonly_keypress %A" 3471 bind $ec_source.context.status <ButtonRelease-2> {break} 3472 bind $ec_source.context.status <Button-1> "tkecl:toggle_breakpoint $ec_source.context.status; break" 3473 3474 menu $ec_source.context.text.popupmenu -tearoff 0 3475 menu $ec_source.context.text.popupmenu.predmenu 3476 bind $ec_source.context.text <Any-Key> "tkecl:readonly_keypress %A" 3477 bind $ec_source.context.text <ButtonRelease-2> {break} 3478 bind $ec_source.context.text <Button-3> "tkecl:popup_sourcetext_menu $ec_source.context.text %X %Y; break" 3479 bind $ec_source.context.text <Control-Button-1> "tkecl:popup_sourcetext_menu $ec_source.context.text %X %Y; break" 3480 $ec_source.context.text tag configure call_style -foreground #7070ff \ 3481 -underline 1 -font tkeclmonobold 3482 $ec_source.context.text tag configure exit_style -foreground #00b000 \ 3483 -underline 1 -font tkeclmonobold 3484 $ec_source.context.text tag configure fail_style -foreground red \ 3485 -underline 1 -font tkeclmonobold 3486 $ec_source.context.text tag configure ancestor_style -background lightblue \ 3487 -relief raised -borderwidth 1 3488 $ec_source.context.text tag configure debug_line -background beige -relief raised -borderwidth 1 3489 $ec_source.context.text tag configure hidden_cr -elide 1 3490 $ec_source.context.text configure -cursor left_ptr 3491 3492 $ec_source.context.status tag configure on -foreground red 3493 $ec_source.context.status tag configure off -foreground lightgray 3494 $ec_source.context.status configure -cursor left_ptr 3495 $ec_source.context.lineno configure -cursor left_ptr 3496 3497 combobox $ec_source.control.select -click single -bg white -listheight 16 -editable 0 \ 3498 -postcommand [list tkecl:get_source_debug_filenames $ec_source.control.select] \ 3499 -textvariable tkecl(source_debug,file) -labeltext "File:" \ 3500 -command tkecl:load_source_debug_file 3501 3502 pack $ec_source.control.select -side left -fill x -expand 1 3503 pack $ec_source.control -side bottom -fill x -expand 1 3504 3505 .ec_tools.ec_tracer.tab activate "Source Context" 3506 3507 balloonhelp $ec_source.context.text "Source context for execution traced by the tracer 3508 3509 Display source file for debugging. Source line for 3510 most recent goal is highlighted, and the current 3511 goal is coloured in blue (call), green (success), or red (failure). 3512 3513 Source context for ancestor goals can also be shown, 3514 highlighted in blue. Hold right mouse button for a 3515 popup menu. 3516 3517 Double-click left mouse button on a port line to display 3518 the source for the predicate called." 3519 3520 balloonhelp $ec_source.context.status "Show port status for line in selected source file: a light gray '#' indicates a port line (not active)\n a red '#' indicates an active breakpoint\nClick left mouse button to toggle the setting of a nearby breakpoint." 3521 balloonhelp $ec_source.context.lineno "Show line numbers for selected source line" 3522 balloonhelp $ec_source.control.select "Select from popup list the source file to display" 3523 3524 # tkwait visibility $ec_source 3525 3526} 3527 3528# adapted from tkdiff 3529proc tkecl:vscroll-sync {windowlist y0 y1} { 3530 global tkecl 3531 3532 set ec_sourcecon .ec_tools.ec_tracer.tab.source.context 3533 $ec_sourcecon.vscroll set $y0 $y1 3534 3535 # if syncing is disabled, we're done. This prevents a nasty 3536 # set of recursive calls 3537 if {[info exists tkecl(disableSyncing)]} { 3538 return 3539 } 3540 3541 # set the flag; this makes sure we only get called once 3542 set tkecl(disableSyncing) 1 3543 3544 # scroll the other windows 3545 foreach window $windowlist { 3546 $window yview moveto $y0 3547 } 3548 3549 # we apparently automatically process idle events after this 3550 # proc is called. Once that is done we'll unset our flag 3551 after idle {catch {unset tkecl(disableSyncing)}} 3552} 3553 3554proc tkecl:popup_sourcetext_menu {t x y} { 3555 global tkecl 3556 3557 # return if no file loaded into source context window 3558 if {[string compare $tkecl(source_debug,file) ""] == 0} return 3559 3560 set m $t.popupmenu 3561 if [winfo exists $m] { 3562 $m delete 0 end 3563 } else { 3564 menu $m -tearoff 0 3565 } 3566 3567 set xypos [winfo pointerxy .ec_tools.ec_tracer] 3568 set line [tkecl:get_current_text_line $t] 3569 $m add command -label "Find..." -command "tkecl:show-find source_debug .ec_tools.ec_tracer.tab.source.context.text .ec_tools.ec_tracer" 3570 3571 $m add cascade -label "Display Predicate..." -menu $m.predmenu 3572 $m add separator 3573 $m add command -label "Refresh this file" -command \ 3574 [list tkecl:load_source_debug_file $tkecl(source_debug,file) [$t xview] [$t yview]] 3575 $m add command -label "Edit this file" -command [list tkecl:edit_file $tkecl(source_debug,file) $line] 3576 set callinfo [tkecl:get_nearest_port_call $tkecl(source_debug,file) $line] 3577 if {$callinfo != ""} { 3578 $m add separator 3579 set parent [lindex $callinfo 0] 3580 set callport [lindex $callinfo 1] 3581 set calldefmodule [lindex $callport 1] 3582 set callspec [lindex $callport 2] 3583 set callname [lindex $callspec 1] 3584 set callarity [lindex $callspec 2] 3585 $m add command -state disabled -label "Nearest tracable call\n$callname/$callarity in $parent" 3586 $m add command -label "Show predicate property for ths predicate" \ 3587 -command [list tkecl:show_pred_prop $calldefmodule $callspec] 3588 } 3589 tk_popup $m $x $y 3590} 3591 3592proc tkecl:show_pred_prop {module callspec} { 3593 global tkecl 3594 3595 set tkecl(predproppred) [lindex [ec_rpcq [list term_string $callspec _] {((()I)_)}] 2] 3596 set tkecl(predpropmodule) $module 3597 3598 tkecl:popup_pred_prop 3599 tkecl:display_predicates dummy 3600 tkecl:display_predprops .ec_tools.predprop.preds 3601} 3602 3603 3604proc tkecl:check_port_call_source {module callspec} { 3605 3606 if [winfo exists .ec_tools.ec_tracer] { 3607 set parent .ec_tools.ec_tracer 3608 } else { 3609 set parent . 3610 } 3611 3612 switch [ec_rpcq [list current_module $module] {(())}] { 3613 fail - 3614 throw { 3615 tk_messageBox -parent $parent -type ok -message "Definition module $module for call $callspec does not exist" 3616 return 0 3617 } 3618 } 3619 switch [ec_rpcatq [list is_predicate $callspec] ((()I)) $module] { 3620 fail - 3621 throw { 3622 tk_messageBox -parent $parent -type ok -message "$callspec is not a user defined predicate in module $module" 3623 return 0 3624 } 3625 } 3626 switch [ec_rpcatq [list get_flag $callspec source_file _] ((()I)()_) $module] { 3627 fail - 3628 throw { 3629 tk_messageBox -parent $parent -type ok -message "Unable to access source information for $callspec defined in module $module" 3630 return 0 3631 } 3632 } 3633 3634 return 1 3635 3636} 3637 3638proc tkecl:get_nearest_port_call {file line} { 3639 3640 set result [ec_rpcq [list find_matching_callinfo $file $line _ _] (SI__) tracer_tcl] 3641 3642 switch $result { 3643 throw - 3644 fail { 3645 return "" 3646 } 3647 default { 3648 return [lrange $result 3 4] 3649 } 3650 } 3651} 3652 3653proc tkecl:toggle_breakpoint {t} { 3654 global tkecl 3655 3656 set line [tkecl:get_current_text_line $t] 3657 set result [ec_rpcq [list toggle_source_breakpoint $tkecl(source_debug,file) $line _ _ _] (SI___) tracer_tcl] 3658 if [winfo exists .ec_tools.ec_tracer] { 3659 set parent .ec_tools.ec_tracer 3660 } else { 3661 set parent . 3662 } 3663 3664 switch $result { 3665 fail { 3666 tk_messageBox -parent $parent -type ok -message "No break ports found in file $tkecl(source_debug,file)" 3667 3668 } 3669 throw { 3670 # shouldn't happen! 3671 bell 3672 } 3673 default { 3674 set breakline [lindex $result 3] 3675 set old_style [lindex $result 4] 3676 set new_style [lindex $result 5] 3677 set ec_breakstatus .ec_tools.ec_tracer.tab.source.context.status 3678 3679 $ec_breakstatus tag remove $old_style $breakline.0 $breakline.end 3680 $ec_breakstatus tag add $new_style $breakline.0 $breakline.end 3681 3682 } 3683 } 3684} 3685 3686proc tkecl:get_source_debug_filenames {w} { 3687 3688 set source_files \ 3689 [lindex [ec_rpcq [list current_files_with_port_lines _] (_) tracer_tcl] 1] 3690 foreach file $source_files { 3691 $w add [lindex $file 0] ;# $file is an atom (1-element list) 3692 } 3693 3694} 3695 3696proc tkecl:handle_source_debug_print {stream {length {}}} { 3697 3698 set ec_sourcecon .ec_tools.ec_tracer.tab.source.context 3699# pack forget $ec_sourcecon.text ;# do not display text as it is added.... 3700 set source_stream [ec_streamnum_to_channel $stream] 3701 set part [ec_read_exdr $source_stream] 3702 if {$part != ""} { 3703 $ec_sourcecon.text insert end $part 3704 } else { 3705# pack $ec_sourcecon.text -fill both -expand 1 3706 3707 # Find and hide CR characters (for Windows) - we can't delete them 3708 # because that would break our offset-based positioning within the 3709 # file (we are getting the file in binary from ECLiPSe). 3710 set i 1.0 3711 while {1} { 3712 set i [$ec_sourcecon.text search "\r" $i] 3713 if {$i == ""} { break } 3714 $ec_sourcecon.text tag add hidden_cr $i 3715 set i "$i+1chars" 3716 } 3717 3718 # Initialise the line and breakpoint columns 3719 $ec_sourcecon.status delete 1.0 end 3720 $ec_sourcecon.lineno delete 1.0 end 3721 # find out the actual number of lines in the file. 3722 regexp {^[0-9]+} [$ec_sourcecon.text index end] lastline 3723 # check if the actual last line (lastline-1) has a newline or not. 3724 # If it does, the last char position will be 0 3725 regexp {^[0-9]+[.]([0-9]+)} [$ec_sourcecon.text index [expr $lastline-1].end] whole lastchar 3726 # actual number of lines is one less than end if there is a newline 3727 if {$lastchar == 0} { 3728 set terminating_nl 1 3729 incr lastline -1 3730 } else { 3731 set terminating_nl 0 3732 } 3733 # this only works if the source has at least 1 line! 3734 set sstuff {} 3735 set lstuff {1} 3736 for {set i 2} {$i < $lastline} {incr i} { 3737 append sstuff "\n" 3738 append lstuff "\n$i" 3739 } 3740 # only add a terminating newline if the source file has one 3741 if {$terminating_nl == 1} { 3742 append sstuff "\n" 3743 append lstuff "\n" 3744 } 3745 3746 $ec_sourcecon.status insert end $sstuff 3747 $ec_sourcecon.lineno insert end $lstuff 3748 } 3749 3750} 3751 3752proc tkecl:show_source_context {invoc greturn} { 3753 3754 set path_info [lindex $greturn 6] 3755 set from [lindex $greturn 7] 3756 set to [lindex $greturn 8] 3757 # is_current_goal/2 must be execute when source is viewed to get 3758 # the current information 3759 set rpc_result [ec_rpcq [list is_current_goal $invoc _] (I_) tracer_tcl] 3760 if {$rpc_result != "fail"} { 3761 set gstyle [lindex $rpc_result 2] 3762 } else { 3763 set gstyle ancestor_style 3764 } 3765 3766 # path_info in quotes because it may have spaces 3767 tkecl:update_source_debug $gstyle $from $to "$path_info" 3768} 3769 3770 3771 3772proc tkecl:update_source_debug {style from to fpath_info} { 3773 global tkecl 3774 3775 set ec_source .ec_tools.ec_tracer.tab.source 3776 3777 if {![winfo exists $ec_source]} { 3778 return 3779 } 3780 3781 set ec_sourcetext $ec_source.context.text 3782 if {$style != "ancestor_style"} { 3783 # reset previous trace call annotations (except debug_line) 3784 $ec_sourcetext tag remove call_style 1.0 end 3785 $ec_sourcetext tag remove exit_style 1.0 end 3786 $ec_sourcetext tag remove fail_style 1.0 end 3787 } 3788 $ec_sourcetext tag remove ancestor_style 1.0 end 3789 3790 if {$fpath_info == "no" || $from < 0} { 3791 # .ec_tools.ec_tracer.tab itemconfigure "Source Context" -state disabled 3792 return 3793 } else { 3794 # get the pathname 3795 set fpath [lindex [lindex $fpath_info 1] 0] ;# atom type (singleton list) 3796 } 3797 3798 if {$tkecl(source_debug,file) != $fpath} { 3799 if {[tkecl:load_source_debug_file $fpath] == 0} return 3800 } else { 3801 if {$style != "ancestor_style"} { 3802 $ec_sourcetext tag remove debug_line 1.0 end 3803 } 3804 } 3805 3806 # assume $from, $to -- position information on an annotated term from 3807 # ECLiPSe maps into number of characters from start of file 3808 set from_idx [$ec_sourcetext index "1.0 + $from chars"] 3809 set to_idx [$ec_sourcetext index "1.0 + $to chars"] 3810 $ec_sourcetext tag add $style $from_idx $to_idx 3811 if {$style != "ancestor_style"} { 3812 $ec_sourcetext tag add debug_line "$from_idx linestart" "$to_idx lineend" 3813 } 3814 $ec_sourcetext see $from_idx 3815 3816} 3817 3818 3819proc tkecl:get_current_text_line {t} { 3820 3821 regexp {^[0-9]+} [$t index current] line 3822 return $line 3823} 3824 3825 3826proc tkecl:load_source_debug_file {fpath {xfracs "0 1"} {yfracs "0 1"}} { 3827 global tkecl 3828 3829 set ec_source .ec_tools.ec_tracer.tab.source 3830 set ec_sourcetext $ec_source.context.text 3831 set xfrac [lindex $xfracs 0] 3832 set yfrac [lindex $yfracs 0] 3833 3834 switch [ec_rpcq [list file_is_readable $fpath] (S) tracer_tcl] { 3835 fail - 3836 throw { 3837 # source not readable, no display 3838 return 0 3839 } 3840 } 3841 3842 $ec_sourcetext delete 1.0 end 3843 ec_rpcq [list read_file_for_gui $fpath] (S) tracer_tcl 3844 set tkecl(source_debug,file) $fpath 3845 $ec_source.context.text xview moveto $xfrac 3846 $ec_source.context.text yview moveto $yfrac 3847 3848 set result [ec_rpcq [list breakpoints_for_file $fpath _ _ _] (S___) tracer_tcl] 3849 switch $result { 3850 fail - 3851 throw { 3852 return 0 3853 } 3854 default { 3855 set actives [lindex $result 2] 3856 3857 set ports [lindex $result 3] 3858 set predslist [lindex $result 4] 3859 foreach line $ports { 3860 $ec_source.context.status insert $line.0 "#" off 3861 } 3862 foreach line $actives { 3863 $ec_source.context.status tag remove off $line.0 $line.end 3864 $ec_source.context.status tag add on $line.0 $line.end 3865 } 3866 set predmenu $ec_source.context.text.popupmenu.predmenu 3867 $predmenu delete 0 end 3868 set i 0 3869 foreach pred $predslist { 3870 incr i 3871 if {[expr $i % 30] == 0} { 3872 set brk 1 3873 } else { 3874 set brk 0 3875 } 3876 $predmenu add command -label [lindex $pred 1] -command "$ec_source.context.text see [lindex $pred 2].0" -columnbreak $brk 3877 } 3878 } 3879 } 3880 3881 return 1 3882# $ec_source.control.load configure -state normal 3883} 3884 3885# the find code is adapted from tkdiff 3886# name is the `user' name of the text window being search. It is also used to 3887# distinguish the tkecl variables used by the find window. 3888# source is the path to the text widget being searched 3889# top is the path of the toplevel window for source 3890proc tkecl:show-find {name source top} { 3891 global tkecl 3892 3893 set ff $source.find.content.findFrame 3894 if {![winfo exists $source.find]} { 3895 toplevel $source.find 3896 wm group $source.find $top 3897 wm transient $source.find $top 3898 wm title $source.find "$name Find" 3899 3900 # we don't want the window to be deleted, just hidden from view 3901# following lines seems to produce a collasped window - commented out 3902# wm protocol $source.find WM_DELETE_WINDOW [list wm withdraw \ 3903 $source.find] 3904 3905# wm withdraw $source.find 3906 update idletasks 3907 3908 frame $source.find.content -bd 2 -relief groove 3909 pack $source.find.content -side top -fill both -expand y -padx 0 \ 3910 -pady 5 3911 3912 frame $source.find.buttons 3913 pack $source.find.buttons -side bottom -fill x -expand n 3914 3915 button $source.find.buttons.doit -text "Find Next" -command "tkecl:do-find $name $source $top" 3916 button $source.find.buttons.dismiss -text "Dismiss" -command \ 3917 "wm withdraw $source.find" 3918 pack $source.find.buttons.dismiss -side right -pady 5 -padx 0 3919 pack $source.find.buttons.doit -side right -pady 5 -padx 1 3920 3921 frame $ff -height 100 -bd 2 -relief flat 3922 pack $ff -side top -fill x -expand n -padx 0 -pady 5 3923 3924 label $ff.label -text "Find what:" -underline 2 3925 3926 entry $ff.entry -textvariable tkecl($name,findString) 3927 3928 checkbutton $ff.searchCase -text "Ignore Case" -offvalue 0 -onvalue 1 \ 3929 -indicatoron true -variable tkecl($name,findIgnoreCase) 3930 3931 grid $ff.label -row 0 -column 0 -sticky e 3932 grid $ff.entry -row 0 -column 1 -sticky ew 3933 grid $ff.searchCase -row 0 -column 2 -sticky w 3934 grid columnconfigure $ff 0 -weight 0 3935 grid columnconfigure $ff 1 -weight 1 3936 grid columnconfigure $ff 2 -weight 0 3937 3938 # we need this in other places... 3939 set tkecl($name,findEntry) $ff.entry 3940 3941 bind $ff.entry <Return> "tkecl:do-find $name $source $top" 3942 3943 set of $source.find.content.optionsFrame 3944 frame $of -bd 2 -relief flat 3945 pack $of -side top -fill y -expand y -padx 10 -pady 10 3946 3947 label $of.directionLabel -text "Search Direction:" -anchor e 3948 radiobutton $of.directionForward -indicatoron true -text "Down" \ 3949 -value "-forward" -variable tkecl($name,findDirection) 3950 radiobutton $of.directionBackward -text "Up" -value "-backward" \ 3951 -indicatoron true -variable tkecl($name,findDirection) 3952 3953 3954 label $of.searchLabel -text "Search Type:" -anchor e 3955 radiobutton $of.searchExact -indicatoron true -text "Exact" \ 3956 -value "-exact" -variable tkecl($name,findType) 3957 radiobutton $of.searchRegexp -text "Regexp" -value "-regexp" \ 3958 -indicatoron true -variable tkecl($name,findType) 3959 3960 grid $of.directionLabel -row 0 -column 0 -sticky w 3961 grid $of.directionForward -row 0 -column 1 -sticky w 3962 grid $of.directionBackward -row 0 -column 2 -sticky w 3963 3964 grid $of.searchLabel -row 1 -column 0 -sticky w 3965 grid $of.searchExact -row 1 -column 1 -sticky w 3966 grid $of.searchRegexp -row 1 -column 2 -sticky w 3967 3968 grid columnconfigure $of 0 -weight 0 3969 grid columnconfigure $of 1 -weight 0 3970 3971 set tkecl($name,findDirection) "-forward" 3972 set tkecl($name,findType) "-exact" 3973 set tkecl($name,findIgnoreCase) 1 3974 set tkecl($name,lastSearch) "" 3975 } 3976 3977 wm deiconify $source.find 3978 raise $source.find 3979 after idle focus $ff.entry 3980} 3981 3982# search for the text in the find dialog 3983proc tkecl:do-find {name source top} { 3984 global tkecl 3985 3986 if {![winfo exists $source.find] || ![winfo ismapped $source.find]} { 3987 tkecl:show-find $name $source $top 3988 return 3989 } 3990 3991 if {$tkecl($name,lastSearch) != ""} { 3992 if {$tkecl($name,findDirection) == "-forward"} { 3993 set start [$source index "insert +1c"] 3994 } else { 3995 set start insert 3996 } 3997 } else { 3998 set start 1.0 3999 } 4000 4001 if {$tkecl($name,findIgnoreCase)} { 4002 set result [$source search $tkecl($name,findDirection) $tkecl($name,findType) -nocase \ 4003 -- $tkecl($name,findString) $start] 4004 } else { 4005 set result [$source search $tkecl($name,findDirection) $tkecl($name,findType) \ 4006 -- $tkecl($name,findString) $start] 4007 } 4008 if {[string length $result] > 0} { 4009 # if this is a regular expression search, get the whole line and try 4010 # to figure out exactly what matched; otherwise we know we must 4011 # have matched the whole string... 4012 if {$tkecl($name,findType) == "-regexp"} { 4013 set line [$source get $result "$result lineend"] 4014 regexp $tkecl($name,findString) $line matchVar 4015 set length [string length $matchVar] 4016 } else { 4017 set length [string length $tkecl($name,findString)] 4018 } 4019 set tkecl($name,lastSearch) $result 4020 $source mark set insert $result 4021 $source tag remove sel 1.0 end 4022 $source tag add sel $result "$result + ${length}c" 4023 $source see $result 4024 focus $source 4025 # should I somehow snap to the nearest diff? Probably not... 4026 } else { 4027 bell 4028 4029 } 4030} 4031 4032#--------------------------------------------------------------------- 4033# Balloon Help Toggle 4034#--------------------------------------------------------------------- 4035 4036trace variable tkecl(pref,balloonhelp) w tkecl:ToggleBalloonHelp 4037 4038proc tkecl:ToggleBalloonHelp {name dummy op} { 4039 global tkecl 4040 4041 if {$tkecl(pref,balloonhelp) == 1} { 4042 balloonhelp enable 4043 } else { 4044 balloonhelp disable 4045 } 4046} 4047 4048#---------------------------------------------------------------------- 4049# Help Files procedures 4050#---------------------------------------------------------------------- 4051 4052# find the right help file given key (four letter unique id) and display 4053# help file as a subwindow of parent 4054proc tkecl:Get_helpfileinfo {key parent} { 4055 global tkecl 4056 4057 set i [lsearch -glob $tkecl(helpfiles) $key] 4058 if {$i == -1} { 4059 tk_messageBox -type ok -message "Invalid topic name for help files" 4060 return [list $key "invalid"] 4061 } 4062 set topic [lindex $tkecl(helpfiles) [expr $i+1]] 4063 set filename [lindex $tkecl(helpfiles) [expr $i+2]] 4064 eval tkinspect:helpinfo [concat {$parent} [list $topic $filename $key]] 4065} 4066 4067#---------------------------------------------------------------------- 4068# Routines for handling initial user defaults 4069#---------------------------------------------------------------------- 4070 4071proc tkecl:read_defaults_file {family} { 4072 global env tkecl 4073 4074 set defaults "" 4075 set file_exists 0 4076 set filename .$family ;# filename is the family name with leading . 4077 if [file exists $filename] { 4078 set file_exists 1 4079 } else { 4080 set filename [file join $env(HOME) $filename] ;# check in homedir 4081 if [file exists $filename] { set file_exists 1 } 4082 } 4083 if {$file_exists == 1} { 4084 if {[catch {open $filename r} fid]} return $defaults ;# unable to open file 4085 4086 while {[gets $fid line] >= 0} { 4087 set option [lindex $line 0] 4088 if {[lsearch $tkecl(preferences) [list $option * * $family *]] != -1} { 4089 4090 ;# get the part of the line from the start of the second word 4091 ;# (first word is $option) 4092 set tkecl(prefset,$option) [string trimleft [string range \ 4093 $line [string wordend $line [string first $option \ 4094 $line]] end]] 4095 lappend defaults $option 4096 } else { 4097 ;# not a valid option 4098 tk_messageBox -icon warning -message "$option is not a valid preference for $family" 4099 } 4100 4101 } 4102 close $fid 4103 } 4104 return $defaults 4105} 4106 4107 4108proc tkecl:get_user_defaults {family} { 4109 global tcl_platform tkecl 4110 4111 ;# read in user defined defaults for family (tkeclipserc or tkeclipsetoolsrc) 4112 switch $tcl_platform(platform) { 4113 unix { 4114 return [tkecl:read_defaults_file $family] 4115 } 4116 4117 windows { 4118 package require registry 4119 set regpath $tkecl(windows_registry_path)$family 4120 registry set $regpath ;# make sure the key is there 4121 set defaults "" 4122 4123 foreach option [registry values $regpath] { 4124 if {[lsearch $tkecl(preferences) [list $option * * $family *]] != -1} { 4125 set tkecl(prefset,$option) [registry get $regpath $option] 4126 lappend defaults $option 4127 } else { 4128 ;# not a valid option 4129 tk_messageBox -icon warning -message "$option is not a valid preference for $family" 4130 } 4131 } 4132 return $defaults 4133 4134 } 4135 } 4136} 4137 4138 4139proc tkecl:set_tools_defaults {} { 4140 global tkecl 4141 4142 set userdefaults [tkecl:get_user_defaults tkeclipsetoolsrc] 4143 4144 foreach preference $tkecl(preferences) { 4145 foreach {dname default type family help} $preference { 4146 if {$family == "tkeclipsetoolsrc"} { 4147 if {[lsearch -exact $userdefaults $dname] != -1} { 4148 set value $tkecl(prefset,$dname) 4149 } else { 4150 set value $default 4151 } 4152 tkecl:set_one_tools_default $dname $value $type 4153 } 4154 } 4155 } 4156} 4157 4158 4159proc tkecl:set_one_tools_default {dname dvalue type} { 4160 global tkecl 4161 4162 if {[string trimleft $dvalue] != ""} { 4163 ;# only set if dvalue is not empty or whitespaces 4164 switch -- $type { 4165 4166 boolean { 4167 ;# 0 or 1 options 4168 if {$dvalue == 1 || $dvalue == 0} { 4169 set tkecl(pref,$dname) $dvalue 4170 } else { 4171 tk_messageBox -icon warning -message "$dvalue is an invalid value for $dname (0/1 expected)" -type ok 4172 } 4173 } 4174 4175 +integer { 4176 ;# straight positve integers, no special routines to call 4177 if [regexp {^[0-9]+$} $dvalue size] { 4178 set tkecl(pref,$dname) $dvalue 4179 } else { 4180 tk_messageBox -icon warning -message "$dvalue is an invalid value for $dname (positive integer expected" -type ok 4181 } 4182 } 4183 4184 tracer_prdepth { 4185 if [regexp {^[0-9]+$} $dvalue size] { 4186 set tkecl(pref,tracer_prdepth) $dvalue 4187 ec_rpcq [list set_tracer_print_depth $tkecl(pref,tracer_prdepth)] (I) tracer_tcl 4188 } else { 4189 tk_messageBox -icon warning -message "$dvalue is an invalid value for tracer_prdepth (positive integer expected" -type ok 4190 } 4191 } 4192 4193 stats_interval { 4194 if [regexp {^([0-9]+[.][0-9]+)$|^([0-9]+)$} $dvalue] { 4195 set tkecl(pref,$dname) $dvalue 4196 ;# interval will be set later on via rpc 4197 } else { 4198 tk_messageBox -icon warning -message "$dvalue is an invalid value for stats_interval (number expected)" 4199 } 4200 4201 } 4202 4203 string { 4204 set tkecl(pref,$dname) $dvalue 4205 } 4206 4207 colour { ;# background colour only 4208 if [catch {tk_setPalette $dvalue}] { 4209 tk_messageBox -icon error -type ok -message \ 4210 "Unable to change default background colour to $dvalue" 4211 } else { 4212 set tkecl(pref,$dname) $dvalue 4213 } 4214 } 4215 4216 fontsize { 4217 if [regexp {^[0-9]+$} $dvalue size] { 4218 if {[string compare $dname monofont_size] == 0} { 4219 font configure tkeclmono -size $dvalue 4220 font configure tkeclmonobold -size $dvalue 4221 } else { 4222 font configure tkecllabel -size $dvalue 4223 } 4224 set tkecl(pref,$dname) $dvalue 4225 } else { 4226 tk_messageBox -icon warning -message "$dvalue is an invalid valid for $dname (positive integer expected" -type ok 4227 } 4228 } 4229 4230 font { 4231 if {[string compare $dname monofont_family] == 0} { 4232 font configure tkeclmono -family $dvalue 4233 font configure tkeclmonobold -family $dvalue 4234 } else { 4235 font configure tkecllabel -family $dvalue 4236 } 4237 set tkecl(pref,$dname) $dvalue 4238 } 4239 } 4240 } 4241} 4242 4243 4244proc tkecl:popup_edit_defaults {} { 4245 global tkecl 4246 4247 set edit .ec_tools.pref_edit 4248 if {![winfo exists $edit]} { 4249 toplevel $edit 4250 wm title $edit "TkECLiPSe Preference Editor" 4251 wm resizable $edit 0 0 4252 foreach preference $tkecl(preferences) { 4253 tkecl:display_one_default $edit $preference 4254 } 4255 pack [frame $edit.bf] -expand 1 -fill x 4256 pack [button $edit.bf.apply -text "Apply Preferences" -command tkecl:apply_prefs] -expand 1 -fill x -side left 4257 pack [button $edit.bf.save -text "Save Preferences" -command tkecl:save_prefs] -expand 1 -fill x -side left 4258 pack [button $edit.bf.close -text "Close" -command "destroy $edit"] -expand 1 -fill x -side right 4259 4260 balloonhelp $edit "Change various preference settings for TkECLiPSe" 4261 balloonhelp $edit.bf.save "Save the preferences in the editor (the values will be used for the initial settings for the next session)." 4262 balloonhelp $edit.bf.close "Close the preference editor" 4263 balloonhelp $edit.bf.apply "Apply the preferences in the editor to the current session." 4264 bind $edit <Alt-h> "tkecl:Get_helpfileinfo pref $edit" 4265 } else { 4266 tkinspect:RaiseWindow $edit 4267 } 4268} 4269 4270proc tkecl:display_one_default {w preference} { 4271 global tkecl 4272 4273 foreach {option sysdefault type family help} $preference { 4274 set default $tkecl(pref,$option) 4275 set tkecl(prefset,$option) $default 4276 4277 switch -exact -- $type { 4278 boolean { 4279 pack [frame $w.$option] -fill both 4280 pack [label $w.$option.l -text $help -anchor w -width 50] -side left -expand 1 -fill both 4281 pack [radiobutton $w.$option.on -text on -value 1 \ 4282 -variable tkecl(prefset,$option) -anchor w] -side left -expand 1 -fill both 4283 pack [radiobutton $w.$option.off -text off -value 0 \ 4284 -variable tkecl(prefset,$option) -anchor w] -side left -expand 1 -fill both 4285 } 4286 4287 fontsize - 4288 tracer_prdepth - 4289 +integer { 4290 pack [ventry $w.$option -labeltext $help -labelwidth 50 \ 4291 -vcmd {regexp {^[0-9]*$} %P} -validate key -labelanchor w\ 4292 -invalidcmd bell -textvariable tkecl(prefset,$option) \ 4293 ] -fill both -expand 1 4294 } 4295 4296 stats_interval { 4297 pack [ventry $w.$option -labeltext $help -labelwidth 50 \ 4298 -vcmd {regexp {^([0-9]*[.][0-9]*)$|^([0-9]*)$} %P} \ 4299 -validate key -invalidcmd bell -labelanchor w \ 4300 -textvariable tkecl(prefset,$option)\ 4301 ] -fill both -expand 1 4302 } 4303 4304 colour - 4305 font - 4306 string { 4307 pack [ventry $w.$option -labeltext $help -labelwidth 50 \ 4308 -labelanchor w -textvariable tkecl(prefset,$option)\ 4309 ] -fill both -expand 1 4310 } 4311 4312 4313 } 4314 } 4315} 4316 4317proc tkecl:apply_prefs {} { 4318 global tkecl 4319 4320 foreach preference $tkecl(preferences) { 4321 foreach {option default type family help} $preference { 4322 break 4323 } 4324 tkecl:set_one_tools_default $option $tkecl(prefset,$option) $type 4325 } 4326} 4327 4328proc tkecl:save_prefs {} { 4329 global tcl_platform tkecl env 4330 4331 foreach preference $tkecl(preferences) { 4332 foreach {option default type family help} $preference { 4333 lappend group($family) $option 4334 } 4335 } 4336 switch $tcl_platform(platform) { 4337 unix { 4338 foreach rootname [array names group] { 4339 if [file exists .$rootname] { 4340 set filename .$rootname 4341 } else { 4342 set filename [file join $env(HOME) .$rootname] 4343 } 4344 if {[catch {open $filename w} fid]} { 4345 tk_messageBox -type ok -icon error -message "Unable to write the preference file. Permission problems?" 4346 return 4347 } 4348 foreach option $group($rootname) { 4349 if {[string trimleft $tkecl(prefset,$option)] != ""} { 4350 puts $fid "$option $tkecl(prefset,$option)" 4351 } 4352 } 4353 close $fid 4354 } 4355 } 4356 4357 windows { 4358 foreach rootname [array names group] { 4359 set regpath $tkecl(windows_registry_path)$rootname 4360 foreach option $group($rootname) { 4361 registry set $regpath $option $tkecl(prefset,$option) 4362 } 4363 } 4364 } 4365 } 4366} 4367 4368#-------------------------------------------------------------------- 4369# 4370#-------------------------------------------------------------------- 4371 4372proc tkecl:listbox_search {lbox key keycode x y} { 4373 global tkecl 4374 4375 if {$key == {}} {return -code continue} ;# return if modifier key only 4376 4377 set s $lbox.search 4378 if {![winfo exists $s]} { 4379 toplevel $s 4380 wm overrideredirect $s 1 4381 wm positionfrom $s program 4382 wm withdraw $s 4383 pack [label $s.l -highlightthickness 0 -relief raised -bd 1 \ 4384 -background lightblue -textvariable tkecl(lboxstring)] 4385 4386 ;# for some reason x position of the popup window needs to be 4387 ;# somewhat displaced from the mouse position to work 4388 set x [expr $x + 10] 4389 wm geometry $s +$x+$y 4390 wm deiconify $s 4391 raise $s 4392 } else { 4393 raise $s 4394 } 4395 4396 switch -exact -- $keycode { 4397 Delete - 4398 BackSpace { 4399 set tkecl(lboxstring) [string range "$tkecl(lboxstring)" 0 end-1] 4400 tkecl:do_listbox_search $lbox [$lbox get 0 end] \ 4401 $tkecl(lboxstring)* 0 4402 } 4403 Escape { 4404 tkecl:listbox_search_exit $lbox 4405 } 4406 Return { 4407 ;# disabled because selection does not activate <<ListboxSelect>> 4408 ;# $lbox selection set active 4409 } 4410 Control_S { 4411 ;# search from active element 4412 set start [expr [$lbox index active] + 1] 4413 tkecl:do_listbox_search $lbox [$lbox get $start end] \ 4414 $tkecl(lboxstring)* $start 4415 } 4416 default { 4417 ;# printable character 4418 append tkecl(lboxstring) $key 4419 tkecl:do_listbox_search $lbox [$lbox get 0 end] \ 4420 $tkecl(lboxstring)* 0 4421 } 4422 } 4423 return -code continue 4424} 4425 4426# search for string, list may be a sublist starting from start of listbox 4427proc tkecl:do_listbox_search {lbox list search_string start} { 4428 set offset [lsearch $list $search_string] 4429 if {$offset != -1} { 4430 set index [expr $offset + $start] ;# index in original list 4431 $lbox yview $index 4432 $lbox activate $index 4433 } else { 4434 bell 4435 } 4436} 4437 4438proc tkecl:listbox_search_init {lbox} { 4439 global tkecl 4440 4441 if [winfo exists $lbox.search] { 4442 destroy $lbox.search 4443 } 4444 4445 set tkecl(lboxstring) "*" 4446 focus $lbox 4447} 4448 4449proc tkecl:listbox_search_exit {lbox} { 4450 global tkecl 4451 4452 if [winfo exists $lbox.search] { 4453 destroy $lbox.search 4454 } 4455 4456 focus -lastfor $lbox 4457} 4458 4459#-------------------------------------------------------------------- 4460# handling keypresses in read-only windows 4461#-------------------------------------------------------------------- 4462 4463proc tkecl:readonly_keypress {keycode} { 4464 4465 switch -exact -- $keycode { 4466 "\x3" { ;#^C -- allow default handling for window copy operation 4467 return 0 4468 } 4469 default { 4470 return -code break 4471 } 4472 } 4473} 4474 4475#-------------------------------------------------------------------- 4476# Utility for locating the window the pointer is in 4477#-------------------------------------------------------------------- 4478 4479proc tkecl:pointer_window {} { 4480 4481 set win [winfo containing -displayof . \ 4482 [winfo pointerx .] [winfo pointery .]] 4483 if {$win != ""} { ;# pointer is in a window for the application 4484 return [winfo toplevel $win] ;# we want the toplevel path only 4485 } else { 4486 return "" ;# not in any window 4487 } 4488} 4489 4490#--------------------------------------------------------------------- 4491# Handling multitasking 4492#--------------------------------------------------------------------- 4493 4494proc tkecl:multi_start_handler {type} { 4495 4496 switch $type { 4497 tracer { 4498 # only do handling of port if the tracer window exists 4499 if [winfo exists .ec_tools.ec_tracer] { 4500 tkecl:handle_tracer_port_start 4501 set of_interest continue 4502 } else { 4503 set of_interest no ;# do nothing (no tracer window) 4504 } 4505 } 4506 default { 4507 set of_interest no 4508 # do nothing 4509 } 4510 } 4511 4512 return $of_interest 4513} 4514 4515proc tkecl:multi_interact_handler {type} { 4516 global tkecl 4517 4518 switch $type { 4519 tracer { 4520 tkecl:check_tracer_interaction 4521 if [string match tkecl(tracer_state) disabled] { 4522 return terminate 4523 } else { 4524 return continue 4525 } 4526 } 4527 default { 4528 # do nothing 4529 return continue 4530 } 4531 } 4532} 4533 4534proc tkecl:multi_end_handler {type} { 4535 global tkecl 4536 4537 if {[ec_interface_type] == "remote"} { 4538 tkecl:freeze_control 4539 } 4540} 4541 4542#--------------------------------------------------------------------- 4543# Visualisation client 4544#--------------------------------------------------------------------- 4545 4546proc tkecl:start_vc {} { 4547 switch [ec_rpcq_check {ensure_loaded {library java_vc}} ((()))] { 4548 fail - throw { return } 4549 } 4550 ec_rpcq_check {start_vc _} (_) java_vc 4551} 4552 4553#--------------------------------------------------------------------- 4554# Viztool 4555#--------------------------------------------------------------------- 4556 4557proc tkecl:start_viztool {} { 4558 switch [ec_rpcq_check {ensure_loaded {library cpviz}} ((()))] { 4559 fail - throw { return } 4560 } 4561 ec_rpcq_check viztool () cpviz 4562} 4563 4564#---------------------------------------------------------------------- 4565# Initalise and create menu/toolbar 4566#---------------------------------------------------------------------- 4567 4568proc ec_tools_init {w} { 4569 global tkinspectvalues tkecl 4570 4571 4572# Init the Eclipse part (must be done after ec_init !!!) 4573 ec_rpcq {ensure_loaded {library development_support}} ((())) 4574 ec_rpcq {ensure_loaded {library tracer_tcl}} ((())) 4575 ec_rpcq install_guitools () tracer_tcl 4576 ec_queue_create debug_traceline r tkecl:handle_trace_line 4577 ec_queue_create debug_output r tkecl:handle_debug_output 4578 ec_queue_create gui_source_file r tkecl:handle_source_debug_print 4579 ec_queue_create matrix_out_queue r tkecl:handle_mat_flush 4580 ec_queue_create gui_dg_info r tkecl:handle_dg_print 4581 ec_queue_create statistics_out_queue r tkecl:handle_stats_report 4582 set tkecl(toplevel_module) [lindex [ec_rpcq_check {get_flag toplevel_module _} (()_)] 2] 4583 set tkecl(predpropmodule) $tkecl(toplevel_module) 4584 4585 ec_multi:peer_register [list interact tkecl:multi_interact_handler start tkecl:multi_start_handler end tkecl:multi_end_handler] 4586 4587# Create the tools launcher menu and set up help files 4588 4589 menu $w 4590 $w add command -label "Compile Scratch-pad" -command "tkecl:compile_pad" 4591 lappend tkecl(helpfiles) scra {Compile Scratch-Pad} scratchhelp.txt 4592 $w add command -label "Source File Manager" -command tkecl:popup_file_window 4593 lappend tkecl(helpfiles) file {Source Files Tool} sourcehelp.txt 4594 $w add command -label "Predicate Browser" -command tkecl:popup_pred_prop 4595 lappend tkecl(helpfiles) pred {Predicates Property Tool} predprophelp.txt 4596 $w add separator 4597 $w add command -label "Delayed Goals" -command tkecl:popup_dg_window 4598 lappend tkecl(helpfiles) dela {Delayed Goals Viewer} delayhelp.txt 4599 $w add command -label "Tracer" -command tkecl:popup_tracer 4600 lappend tkecl(helpfiles) trac Tracer tracerhelp.txt 4601 $w add command -label "Inspector" -command "tkinspect:Inspect_term_init current" 4602 lappend tkecl(helpfiles) insp Inspector inspecthelp.txt 4603 $w add command -label "Visualisation Client" -command "tkecl:start_vc" 4604 $w add command -label "CP-Viz Viztool" -command "tkecl:start_viztool" 4605 $w add separator 4606 $w add command -label "Global Settings" -command tkecl:popup_global_state 4607 lappend tkecl(helpfiles) glob {Global Settings Tool} globalsethelp.txt 4608 $w add command -label "Statistics" -command tkecl:handle_statistics 4609 lappend tkecl(helpfiles) stat {Statistics Window} stathelp.txt 4610 $w add command -label "Simple Query" -command tkecl:rpc 4611 lappend tkecl(helpfiles) rpc {Simple Query Tool} rpchelp.txt 4612 $w add command -label "ECLiPSe Library Browser and Help" -command tkecl:library_browser 4613 lappend tkecl(helpfiles) help {Library Browser and Help Tool} helphelp.txt 4614 $w add separator 4615# $w add command -label "ECLiPSe Help" -command tkecl:popup_help_window 4616# lappend tkecl(helpfiles) help {ECLiPSe Help Tool} helphelp.txt 4617 $w add command -label "TkECLiPSe Preference Editor" -command tkecl:popup_edit_defaults 4618 lappend tkecl(helpfiles) pref {Preference Editor} prefhelp.txt 4619 $w add separator 4620 $w add check -label "Balloon Help" -variable tkecl(pref,balloonhelp) 4621# $w add command -label "Test" -command tkecl:test 4622 lappend tkecl(helpfiles) disp {Display Matrix} matdisplayhelp.txt 4623 4624 tkecl:set_tools_defaults 4625 ;# set user defined defaults for tools 4626 4627 return $w 4628} 4629 4630