<> <> <> <> <<>> DIRECTORY CedarProcess, CD, CDCells, CDOps, CDSequencer, CDSequencerExtras, Core, CoreOps, FS, IO, Rope, Rsh, SinixOps, Sisyph, TerminalIO, SpiceOps; SpiceCDCmds: CEDAR MONITOR IMPORTS CedarProcess, CDCells, CDOps, CDSequencerExtras, CoreOps, IO, FS, Rope, Rsh, SinixOps, Sisyph, SpiceOps, TerminalIO ~ BEGIN ROPE: TYPE = Rope.ROPE; stop: BOOL _ FALSE; cmd: ROPE _ "/usr/datools/spice "; host: ROPE _ "tregonsee"; SIGTERM: CHAR = VAL[15]; -- Unix signal to terminate a process. debug: BOOLEAN _ FALSE; <> ExtractSelectedObjAndSpiceIt: PROC [comm: CDSequencer.Command] = { msg: Rope.ROPE; selected: CD.Instance; multiple: BOOL; stdStr, errStr: IO.STREAM; cellType: Core.CellType; cellName: Rope.ROPE; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelectedAndCell[selected, multiple] THEN RETURN; cellType _ NARROW [SinixOps.ExtractCDInstance[selected, comm.design, Sisyph.mode].result]; cellName _ CoreOps.GetCellTypeName[cellType]; TerminalIO.PutRopes["SpiceOps on ", cellName, " ."]; [stdStr, errStr, msg] _ Rsh.RemoteShell[host, cmd, TRUE]; IF stdStr#NIL THEN { ENABLE ABORTED => { IO.PutChar[errStr, SIGTERM]; IO.Flush[errStr]; IO.Close[errStr]; IO.Close[stdStr]; TerminalIO.PutRopes["SpiceOps Failure : ", msg, "\n"]; GOTO Failed }; convData: SpiceOps.ConvData _ SpiceOps.CreateConvData[stdStr, stdStr]; convData.rootCell _ cellType; IF msg#NIL THEN ERROR ABORTED; IF debug THEN [] _ CedarProcess.Fork[action: WatchErrors, data: stdStr] ELSE [] _ CedarProcess.Fork[ReadOutput, convData, [inheritProperties: TRUE]]; [] _ CedarProcess.Fork[action: WatchErrors, data: errStr]; SpiceOps.WriteSpiceDeck[cellType, convData]; IO.Flush[stdStr]; IO.Close[stdStr]; TerminalIO.PutRope["."]; }; EXITS Failed => {}; }; ReadOutput: PROC [data: REF] RETURNS [result: REF _ NIL] ~ { line: Rope.ROPE _ NIL; convData: SpiceOps.ConvData _ NARROW[data]; stdStr: IO.STREAM _ convData.inS; fileName: Rope.ROPE _ Rope.Cat[CoreOps.GetCellTypeName[convData.rootCell], ".spo"]; file: IO.STREAM _ FS.StreamOpen[fileName, create]; WHILE NOT IO.EndOf[stdStr] DO c: CHAR _ IO.GetChar[stdStr]; IF c = '\l THEN { IO.PutRope[file, line]; IO.PutChar[file, '\n]; line _ NIL; } ELSE line _ Rope.Concat[line, Rope.FromChar[c]]; ENDLOOP; IF line#NIL THEN IO.PutRope[file, line]; IO.Close[file]; convData.inS _ FS.StreamOpen[fileName]; TerminalIO.PutRopes[".finished, ", fileName, " created.\n"]; SpiceOps.DisplaySpiceListing[convData]; }; WatchErrors: PROC [data: REF] RETURNS [results: REF _ NIL] ~ { line: Rope.ROPE _ NIL; errStr: IO.STREAM _ NARROW[data]; WHILE NOT IO.EndOf[errStr] DO c: CHAR _ IO.GetChar[errStr ! IO.EndOfStream => { IF line#NIL THEN TerminalIO.PutRopes[line, "\n"]; GOTO CleanExit }]; IF c = '\l THEN { TerminalIO.PutRopes[line, "\n"]; line _ NIL; } ELSE line _ Rope.Concat[line, Rope.FromChar[c]]; ENDLOOP; EXITS CleanExit => NULL; }; IsSingleSelectedAndCell: PROC [selected: CD.Instance, multiple: BOOL] RETURNS [BOOL] = { IF ~IsSingleSelected[selected, multiple] THEN RETURN [FALSE]; IF ~CDCells.IsCell[selected.ob] THEN { TerminalIO.PutRope["\n** Selected instance is not a cellcan't do it.\n"]; RETURN[FALSE]; }; RETURN[TRUE]; }; IsSingleSelected: PROC [selected: CD.Instance, multiple: BOOL] RETURNS [BOOL] = { IF selected=NIL THEN { TerminalIO.PutRope["\n** No current selection--can't do it.\n"]; RETURN[FALSE]; }; IF multiple THEN { TerminalIO.PutRope["\n** Multiple instances selected--can't do it.\n"]; RETURN[FALSE]; }; RETURN[TRUE]; }; LoadModelFile: PROC [fileName: Rope.ROPE] ~ { file: IO.STREAM _ FS.StreamOpen[fileName]; SpiceOps.ReadModels[file]; }; <> CDSequencerExtras.RegisterCommand[key: $Spice, proc: ExtractSelectedObjAndSpiceIt, queue: doQueue]; LoadModelFile["MODELS.DAT"]; END.