############################################################################ # # File: scat.icn # # Subject: Program to produce call/result scatterplot # # Author: Clinton Jeffery # # Date: November 11, 1997 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # Press the left mouse button atop any plotted point to see the list of # procedures at that point. Execution (and point motion) is suspended # until the mouse button is released. # ############################################################################ # # Requires: Version 9 graphics # ############################################################################ # # Links: eemutils, vinit # ############################################################################ # # Includes: evdefs.icn # ############################################################################ $include "evdefs.icn" link emutils link evinit global at, # table of counts of procedures at a given point call, # table of call counts rslt # table of result counts record activation (p, parent, children) procedure main(av) local mask, maxmax, maxmatch, current_proc, L, max, i, k, child, e EvInit(av) | stop("*** cannot load SP") kill_output() &window := open("scat","x","geometry=150x180") | stop("can't open window") current_proc := activation(,activation(,,,,[]),[]) call := table(0) rslt := table(0) at := table(0) mask := ProcMask ++ E_MXevent maxmax := 0 maxmatch := 0 while EvGet(mask) do { case &eventcode of { E_Pcall: { move(&eventvalue, 1, 0) current_proc := activation(&eventvalue, current_proc, []) put(current_proc.parent.children, current_proc) } E_Psusp: { move(current_proc.p, 0, 1) current_proc := current_proc.parent } E_Presum: { current_proc := current_proc.children[-1] } E_Pret: { move(current_proc.p, 0, 1) pull(current_proc.parent.children) current_proc := current_proc.parent } E_Pfail: { pull(current_proc.parent.children) current_proc := current_proc.parent } E_Prem: { child := pull(current_proc.children) current_proc.children |||:= child.children } E_MXevent: { case &eventvalue of { "q" | "\033": stop("terminated") &lpress | &ldrag : { repeat { L := [] every k := key(call) do { if -3 < 2*log(call[k]+2,1.25)+2 - &x < 3 & -3 < 2*log(rslt[k]+2,1.25)+2 - &y < 3 then { put(L, procedure_name(k)) } } if max := * (L[1]) then { every max <:= *( !L ) maxmax <:= max } maxmatch <:= *L &col := WAttrib("columns") - maxmax &row := WAttrib("lines") - maxmatch - 1 EraseArea(&x,&y) if *L > 0 then { every i := 1 to *L do { GotoRC(WAttrib("lines")-*L+i,WAttrib("columns")-max) writes(&window,L[i]) } e := Event() every i := 1 to *L do { GotoRC(WAttrib("lines")-*L+i,WAttrib("columns")-max) writes(&window,L[i]) } } else e := Event() if e === &lrelease then break } } } } } } end procedure procedure_name(p) return image(p) ? { ="procedure "; tab(0) } end procedure move(who, iscall, isrslt) if (at[integer(2*log(call[who]+2,1.25)) || "," || integer(2*log(rslt[who]+2,1.25))] -:= 1) = 0 then EraseArea(2*log(call[who]+2,1.25) + 2, 2*log(rslt[who]+2,1.25) + 2, 2, 2) call[who] +:= iscall rslt[who] +:= isrslt if (at[integer(2*log(call[who]+2,1.25)) || "," || integer(2*log(rslt[who]+2,1.25))] +:= 1) = 1 then FillRectangle(2*log(call[who]+2,1.25) + 2, 2*log(rslt[who]+2,1.25) + 2, 2, 2) end