CDDebugCommands.mesa (part of ChipNDale)
Copyright © 1983, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 29, 1983 4:44 pm
Last edited by: Christian Jacobi, August 29, 1986 11:19:28 am PDT
DIRECTORY
AMBridge,
Atom,
CD,
CDAtomicObjects,
CDCommandOps,
CDDirectory,
CDEvents,
CDOps,
CDProperties,
CDSequencer,
CDViewer,
IO,
PopUpSelection USING [Request],
PrintTV,
Process USING [Detach],
Rope,
RuntimeError USING [UNCAUGHT],
TerminalIO,
UserProfile,
ViewerClasses USING [Viewer];
CDDebugCommands: CEDAR PROGRAM
IMPORTS AMBridge, Atom, CD, CDCommandOps, CDDirectory, CDEvents, CDOps, CDProperties, CDSequencer, CDViewer, IO, PopUpSelection, PrintTV, Process, Rope, RuntimeError, TerminalIO, UserProfile =
BEGIN
lastDesign: CD.Design; -- last created or debugged design; accessable from debugger
debug: SIGNAL = CODE;
BreakProc: PROC [comm: CDSequencer.Command] = {
ENABLE ABORTED => TerminalIO.WriteRope["debugger aborted\n"];
Include: PROC [x: REFNIL] RETURNS [Rope.ROPE] = {--called from debugger
RETURN [DoInclude[x, comm]]
};
design: CD.Design ← comm.design;
ob: CD.Object ← NIL;
inst: CD.Instance ← CDOps.SelectedInstance[design].first;
specificRef: REFNIL;
viewer: ViewerClasses.Viewer ← CDViewer.GetViewer[comm];
IF inst#NIL THEN {ob ← inst.ob; specificRef ← ob.specificRef};
lastDesign ← design;
TerminalIO.WriteRopes[
" Look:  ob, inst, design, comm, specificRef, viewer\n",
" Call:   Include[x]\n"];
SIGNAL debug;
TerminalIO.WriteRope["debugger disabled\n"];
};
DoInclude: PROC [x: REF, comm: CDSequencer.Command] RETURNS [r: Rope.ROPENIL] = {
--Implements Include, which is called interactively through the debugger
WITH x SELECT FROM
ob: CD.Object => {
TerminalIO.WriteRope[r ← CDOps.ObjectInfo[ob]];
TerminalIO.WriteRope[" put down from interpreter\n"];
CDOps.IncludeObjectI[comm.design, ob, comm.pos];
};
inst: CD.Instance => {
TerminalIO.WriteRope[r ← CDOps.ObjectInfo[inst.ob]];
TerminalIO.WriteRope[" put down from interpreter\n"];
CDOps.IncludeInstance[comm.design, inst];
};
rob: REF CD.Object =>   RETURN[DoInclude[rob^, comm]];
rrob: REF REF CD.Object =>  RETURN[DoInclude[rrob^^, comm]];
rinst: REF CD.Instance =>  RETURN[DoInclude[rinst^, comm]];
rrinst: REF REF CD.Instance => RETURN[DoInclude[rrinst^^, comm]];
ENDCASE => {
r ← Rope.Cat[
IF x=NIL THEN "NIL" ELSE CDCommandOps.ToRope[x, "unknown"],
"; not included"
];
};
CDOps.DoTheDelayedRedraws[comm.design]
};
DebugComm: PROC [comm: CDSequencer.Command] = {
ForkedBreak: PROC = TRUSTED {
TerminalIO.WriteRope["**open detached debugger view\n"];
Process.Detach[FORK BreakProc[comm]]
};
InLineBreak: PROC = {
TerminalIO.WriteRope["**open locked debugger view\n"];
BreakProc[comm];
TerminalIO.WriteRope["lock released\n"];
};
SELECT PopUpSelection.Request[
header: "Debug options",
choice: LIST["detached debug", "locked debug"],
headerDoc: "discard menu for not debugging",
choiceDoc: LIST["not monitored; can still issue commands", "safe, but can't issue commands"],
timeOut: 20
] FROM
1 => ForkedBreak[];
2 => InLineBreak[];
ENDCASE => TerminalIO.WriteRope["skipped\n"];
};
NewDesign: CDEvents.EventProc = {
lastDesign ← design
};
PrintObjectClass: PrintTV.TVPrintProc = TRUSTED {
c: REF READONLY CD.ObjectClassRec ← NARROW[AMBridge.TVToRef[tv]];
stream.PutRope[ClassRope[c]]
};
ClassRope: PROC [c: REF READONLY CD.ObjectClassRec] RETURNS [Rope.ROPE] = TRUSTED {
RETURN [SELECT TRUE FROM
c=NIL => "NIL class",
Rope.IsEmpty[c.description] AND c.objectType#NIL => Atom.GetPName[c.objectType],
ENDCASE => c.description]
};
PrintInstance: PrintTV.TVPrintProc = TRUSTED {
ENABLE RuntimeError.UNCAUGHT => GOTO someErr;
x: REF;
i: REF READONLY CD.InstanceRep ← NARROW[AMBridge.TVToRef[tv]];
IF i=NIL THEN RETURN [useOld←TRUE];
stream.PutRope["{ob: "];
PrintTV.Print[AMBridge.TVForReferent[i.ob], stream, 1];
IF depth>0 THEN {
stream.PutF[", at: [%g, %g]", IO.int[i.location.x], IO.int[i.location.y]];
IF i.orientation#CD.original THEN stream.PutF[", orient: %g", IO.int[i.orientation]];
IF i.selected THEN stream.PutRope[", S"];
x ← CDProperties.GetListProp[i.properties, $SignalName];
IF x#NIL THEN stream.PutF[", SignalName: %g", IO.refAny[x]];
x ← CDProperties.GetListProp[i.properties, $InstanceName];
IF x#NIL THEN stream.PutF[", InstanceName: %g", IO.refAny[x]];
};
stream.PutChar['}];
EXITS someErr => useOld←TRUE
};
IlLength: PROC [il: CD.InstanceList] RETURNS [l: INT𡤀] = {
FOR cl: CD.InstanceList ← il, cl.rest WHILE cl#NIL DO l ← l+1 ENDLOOP;
};
PrintCellPtr: PrintTV.TVPrintProc = TRUSTED {
cp: REF READONLY CD.CellRep ← NARROW[AMBridge.TVToRef[tv]];
stream.PutF["(%g elements)", IO.int[IlLength[cp.contents]]];
};
PrintObject: PrintTV.TVPrintProc = TRUSTED {
ENABLE RuntimeError.UNCAUGHT => GOTO someErr;
o: REF READONLY CD.ObjectRep ← NARROW[AMBridge.TVToRef[tv]];
IF o=NIL OR o.class=NIL THEN RETURN [useOld←TRUE];
stream.PutChar['{];
IF o.class.inDirectory THEN
stream.PutF1["name: %g, ", IO.rope[CDDirectory.Name[LOOPHOLE[o]]]];
stream.PutRope[ClassRope[o.class]];
IF depth>=1 THEN {
stream.PutF[", size: [%g, %g]", IO.int[o.size.x], IO.int[o.size.y]];
IF CD.LayerTechnology[o.layer]#NIL OR o.class.wireTyped THEN
stream.PutF[", layer: %g", IO.rope[CDOps.LayerName[o.layer]]];
IF ~o.class.wireTyped AND ~ISTYPE[o.specificRef, CDAtomicObjects.AtomicObsPtr] AND o.specificRef#NIL THEN {
stream.PutRope[", "];
PrintTV.Print[AMBridge.TVForReferent[o.specificRef], stream, depth-1];
}
};
stream.PutChar['}];
EXITS someErr => useOld←TRUE
};
TechName: PROC [t: REF READONLY CD.TechnologyRep] RETURNS [Rope.ROPE] = {
IF t=NIL THEN RETURN ["NIL"]
ELSE IF t.name#NIL THEN RETURN [t.name]
ELSE RETURN [Atom.GetPName[t.key]]
};
PrintDesign: PrintTV.TVPrintProc = TRUSTED {
d: REF READONLY CD.DesignRec ← NARROW[AMBridge.TVToRef[tv]];
IF d=NIL THEN RETURN [useOld←TRUE];
stream.PutF["{name: %g, technology: %g}",
IO.rope[IF Rope.Length[d.name]>0 THEN d.name ELSE "(no name)"],
IO.rope[TechName[d.technology]]
];
};
PrintTechnology: PrintTV.TVPrintProc = TRUSTED {
t: REF READONLY CD.TechnologyRep = NARROW[AMBridge.TVToRef[tv]];
stream.PutRope[TechName[t]] ;
};
Impl: PROC [] = {
CDSequencer.ImplementCommand[$Debug, DebugComm];
CDEvents.RegisterEventProc[$CreateNewDesign, NewDesign];
IF UserProfile.Boolean["ChipNDale.RegisterTVPrintProcs", TRUE] THEN {
PrintTV.RegisterTVPrintProc[type: CODE[CD.CellPtr], proc: PrintCellPtr];
PrintTV.RegisterTVPrintProc[type: CODE[CD.Instance], proc: PrintInstance];
PrintTV.RegisterTVPrintProc[type: CODE[CD.Object], proc: PrintObject];
PrintTV.RegisterTVPrintProc[type: CODE[CD.Design], proc: PrintDesign];
PrintTV.RegisterTVPrintProc[type: CODE[CD.Technology], proc: PrintTechnology];
}
};
Impl[];
END.