CDDebugCommands.mesa (part of ChipNDale)
Copyright © 1983, 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, June 29, 1983 4:44 pm
last edited Christian Jacobi, December 9, 1985 3:31:58 pm PST
DIRECTORY
AMBridge,
CD,
CDAtomicObjects,
CDDirectory,
CDEvents,
CDExtras,
CDOps,
CDProperties,
CDSequencer,
CDViewer,
IO,
List,
TerminalIO,
PrintTV,
Process USING [Detach],
Rope,
RuntimeError USING [UNCAUGHT],
ViewerClasses USING [Viewer];
CDDebugCommands: CEDAR PROGRAM
IMPORTS AMBridge, CD, CDDirectory, CDOps, CDProperties, CDSequencer, IO, List, CDViewer, TerminalIO, PrintTV, Process, CDEvents, CDExtras, Rope, RuntimeError =
BEGIN
lastDesign: CD.Design; -- last created or debugged design; accessable from debugger
debug: SIGNAL = CODE;
BreakProc: PROC [comm: CDSequencer.Command] =
BEGIN
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.WriteRope[" Look:  ob, inst, design, comm, specificRef, viewer\n"];
TerminalIO.WriteRope[" Call:   Include[x]\n"];
SIGNAL debug;
TerminalIO.WriteRope["debugger disabled\n"];
END;
DoInclude: PROC [x: REF, comm: CDSequencer.Command] RETURNS [r: Rope.ROPENIL] =
--Implements Include, which is called interactively through the debugger
BEGIN
WITH x SELECT FROM
ob: CD.Object => {
TerminalIO.WriteRope[r ← CDOps.Info[ob]];
TerminalIO.WriteRope[" put down from interpreter\n"];
CDOps.AddAnObject[comm.design, ob, comm.pos];
};
inst: CD.Instance => {
TerminalIO.WriteRope[r ← CDOps.Info[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 CDExtras.ToRope[x, "unknown"],
"; not included"
];
};
CDOps.DoTheDelayedRedraws[comm.design]
END;
DebugComm: PROC [comm: CDSequencer.Command] =
BEGIN
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"];
};
n: INT𡤀
n ← TerminalIO.RequestSelection[
label: "Debug options",
choice: LIST["detached debug", "locked debug"],
timeOut: 5
];
SELECT n FROM
1 => ForkedBreak[];
2 => InLineBreak[];
ENDCASE => TerminalIO.WriteRope["skipped\n"];
END;
NewDesign: CDEvents.EventProc =
BEGIN
lastDesign ← design
END;
PrintObjectClass: PrintTV.RefPrintProc =
BEGIN
c: REF READONLY CD.ObjectClass ← NARROW[ref];
IF Rope.IsEmpty[c.description] THEN stream.Put1[IO.atom[c.objectType]]
ELSE stream.Put1[IO.rope[c.description]]
END;
PrintInstance: PrintTV.RefPrintProc =
TRUSTED BEGIN
ENABLE RuntimeError.UNCAUGHT => GOTO someErr;
x: REF;
i: CD.Instance ← LOOPHOLE[ref];
stream.PutChar['{];
stream.PutF["ob: %g, ", IO.refAny[i.ob]];
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.GetProp[i, $SignalName];
IF x#NIL THEN stream.PutF[", SignalName: %g", IO.refAny[x]];
x ← CDProperties.GetProp[i, $InstanceName];
IF x#NIL THEN stream.PutF[", InstanceName: %g", IO.refAny[x]];
stream.PutChar['}];
EXITS someErr => useOld←TRUE
END;
PrintCellPtr: PrintTV.RefPrintProc =
TRUSTED BEGIN
cp: REF READONLY CD.CellRep ← NARROW[ref];
stream.PutF["(%g elements)", IO.int[List.Length[LOOPHOLE[cp.contents]]]];
END;
PrintObject: PrintTV.RefPrintProc =
TRUSTED BEGIN
ENABLE RuntimeError.UNCAUGHT => GOTO someErr;
o: CD.Object ← LOOPHOLE[ref];
IF o.class=NIL THEN RETURN [useOld←TRUE];
stream.PutChar['{];
IF o.class.inDirectory THEN stream.PutF1["name: %g, ", IO.rope[CDDirectory.Name[o]]];
stream.PutF["class: %g, ", IO.refAny[o.class]];
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] THEN
stream.PutF[", specificRef: %g", IO.refAny[o.specificRef]];
stream.PutChar['}];
EXITS someErr => useOld←TRUE
END;
PrintDesign: PrintTV.RefPrintProc =
BEGIN
d: REF READONLY CD.DesignRec ← NARROW[ref];
stream.PutF["{name: %g, technology: %g}",
IO.rope[IF Rope.Length[d.name]>0 THEN d.name ELSE "(no name)"],
IO.refAny[d.technology]
];
END;
PrintTechnology: PrintTV.RefPrintProc =
BEGIN
t: REF READONLY CD.TechnologyRep = NARROW[ref];
stream.PutF["%g",
IF t=NIL THEN IO.rope["NIL"]
ELSE IF t.name#NIL THEN IO.rope[t.name]
ELSE IO.atom[t.key]
];
END;
PrintTVAsAny: PrintTV.TVPrintProc =
TRUSTED BEGIN
IF AMBridge.IsRemote[tv] THEN RETURN [useOld←TRUE];
IO.Put1[stream, IO.refAny[AMBridge.SomeRefFromTV[tv]]];
END;
Impl: PROC [] =
BEGIN
CDSequencer.ImplementCommand[$Debug, DebugComm];
CDEvents.RegisterEventProc[$CreateNewDesign, NewDesign];
PrintTV.RegisterRefPrintProc[referentType: CODE[CD.DesignRec], proc: PrintDesign];
PrintTV.RegisterRefPrintProc[referentType: CODE[CD.TechnologyRep], proc: PrintTechnology];
PrintTV.RegisterRefPrintProc[referentType: CODE[CD.ObjectClass], proc: PrintObjectClass];
PrintTV.RegisterRefPrintProc[referentType: CODE[CD.InstanceRep], proc: PrintInstance];
PrintTV.RegisterRefPrintProc[referentType: CODE[CD.ObjectRep], proc: PrintObject];
PrintTV.RegisterRefPrintProc[referentType: CODE[CD.CellRep], proc: PrintCellPtr];
--No TVPrintProc for CD.CellRep; you really want to see it if you don't have the object
PrintTV.RegisterTVPrintProc[type: CODE[CD.InstanceRep], proc: PrintTVAsAny];
PrintTV.RegisterTVPrintProc[type: CODE[CD.ObjectRep], proc: PrintTVAsAny];
PrintTV.RegisterTVPrintProc[type: CODE[CD.ObjectClass], proc: PrintTVAsAny];
PrintTV.RegisterTVPrintProc[type: CODE[CD.DesignRec], proc: PrintTVAsAny];
PrintTV.RegisterTVPrintProc[type: CODE[CD.TechnologyRep], proc: PrintTVAsAny];
END;
Impl[];
END.