<> <> <> <> DIRECTORY CD, CDEvents, CDExtras, CDOps, CDSequencer, IO, TerminalIO, PrintTV, Process USING [Detach], Rope; CDDebugCommands: CEDAR PROGRAM IMPORTS CDOps, CDSequencer, IO, TerminalIO, PrintTV, Process, CDEvents, CDExtras, Rope = 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: REF_NIL] 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: REF _ NIL; IF inst#NIL THEN {ob _ inst.ob; specificRef _ ob.specificRef}; lastDesign _ design; TerminalIO.WriteRope[" Look: ob, inst, design, comm, specificRef\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.ROPE_NIL] = <<--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_0; n _ TerminalIO.RequestSelection[ label: "Debug options", choice: LIST["detached debug", "locked debug"]]; SELECT n FROM 1 => ForkedBreak[]; 2 => InLineBreak[]; ENDCASE => TerminalIO.WriteRope["skipped\n"]; END; NewDesign: CDEvents.EventProc = BEGIN lastDesign _ design END; PrintDesign: PrintTV.RefPrintProc = BEGIN d: REF READONLY CD.DesignRec _ NARROW[ref]; stream.PutF["{Design: %g, technology: %g}", IO.rope[IF Rope.Length[d.name]>0 THEN d.name ELSE "(no name)"], IF d.technology=NIL THEN IO.rope["NIL"] ELSE IF d.technology.name#NIL THEN IO.rope[d.technology.name] ELSE IO.atom[d.technology.key] ]; END; <<>> PrintTechnology: PrintTV.RefPrintProc = BEGIN t: REF READONLY CD.TechnologyRep = NARROW[ref]; stream.PutF["{Technology: %g}", IF t=NIL THEN IO.rope["NIL"] ELSE IF t.name#NIL THEN IO.rope[t.name] ELSE IO.atom[t.key] ]; 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]; END; Impl[]; END.