CDCommandOpsImpl.mesa
Copyright © 1984, 1986, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, July 12, 1984 3:49:16 pm PDT
Last Edited by: Christian Jacobi, September 3, 1987 12:00:29 pm PDT
DIRECTORY
Atom,
CD,
CDCommandOps,
CDEnvironment,
CDLayers,
CDOps,
CDPopUpMenus,
CDPrivate,
CDProperties,
CDSequencer,
CDSequencerExtras,
CDViewer,
Commander,
IO,
PopUpMenus,
Process,
RefTab,
Rope,
TerminalIO;
CDCommandOpsImpl:
CEDAR
MONITOR
IMPORTS Atom, CD, CDEnvironment, CDLayers, CDOps, CDPopUpMenus, CDProperties, CDSequencer, CDSequencerExtras, CDViewer, IO, PopUpMenus, Process, RefTab, Rope, TerminalIO
EXPORTS CDCommandOps =
BEGIN
reCheck: CONDITION ← [timeout: Process.MsecToTicks[1000]];
EnterResource:
ENTRY
PROC [resource:
REF, wait:
BOOL, design:
REF]
RETURNS [ok:
BOOL] = {
IF design=NIL THEN design ← $NIL;
DO
ok ← RefTab.Insert[resourceTab, resource, design];
IF ok OR ~wait THEN EXIT;
WAIT reCheck;
ENDLOOP
};
LeaveResource:
ENTRY
PROC [resource:
REF] = {
[] ← RefTab.Delete[resourceTab, resource];
BROADCAST reCheck
};
DoWithResource:
PUBLIC
PROC [proc: CDSequencer.CommandProc, comm: CDSequencer.Command, resource:
REF ←
NIL, waitIfBusy:
BOOL ←
FALSE, messageIfSkipped:
BOOL ←
TRUE]
RETURNS [skipped:
BOOL←
TRUE] = {
design: CD.Design = IF comm#NIL THEN comm.design ELSE NIL;
IF skipped ← ~EnterResource[resource, waitIfBusy, design]
THEN {
IF messageIfSkipped THEN TerminalIO.PutRope[" not reentrant; skipped\n"]
}
ELSE {
Protected:
PROC [] = {
ENABLE UNWIND => LeaveResource[resource];
proc[comm];
LeaveResource[resource];
};
Protected[]
}
};
unique: INT ← 0;
RegisterWithMenu:
PUBLIC PROC [menu:
REF←
NIL, entry: Rope.
ROPE←
NIL, doc: Rope.
ROPE←
NIL, key:
ATOM←
NIL, proc: CDSequencer.CommandProc←
NIL, queue: CDSequencer.QueueMethod𡤍oQueue, tech:
CD.Technology←
NIL] = {
IF key=NIL THEN key ← Atom.MakeAtom[IO.PutFR1["a%g", IO.int[unique ← unique+1]]];
IF proc#
NIL
THEN
CDSequencerExtras.RegisterCommand[key: key, proc: proc, queue: queue, technology: tech];
IF menu#
NIL
THEN
[] ← PopUpMenus.Entry[CDPopUpMenus.GetMenu[menu], entry, NIL, key, doc];
};
currentLayerReg: CD.PropRef ← CD.InitPropRef[];
SetCurrentLayer:
PROC [comm: CDSequencer.Command] = {
x: REF ← CDProperties.GetPropProp[currentLayerReg, comm.design.technology.key, comm.key];
IF x=NIL THEN x ← CDProperties.GetPropProp[currentLayerReg, $all, comm.key];
WITH x
SELECT
FROM
lora:
LIST
OF
REF
ANY => {
lay: CD.Layer ← CD.errorLayer;
w: INT ← -1;
WITH lora.first
SELECT
FROM
l: REF CD.Layer => lay ← l^;
ENDCASE => NULL;
IF lora.rest#
NIL
THEN
WITH lora.rest.first
SELECT
FROM
i: REF INT => w ← i^
ENDCASE => NULL;
SELECT
TRUE
FROM
w>=0 => CDLayers.SetLayerWidth[comm.design, lay, w];
w=-2 => CDLayers.SetLayerWidth[comm.design, lay, CDLayers.LayerWidth[comm.design, CD.commentLayer]];
ENDCASE => NULL; --don't change current width of layer
CDLayers.SetCurrentLayer[comm.design, lay];
TerminalIO.PutRopes["set default layer: ", CDOps.LayerRope[lay], "\n"];
};
ENDCASE => TerminalIO.PutF["command %g failed\n", [atom[comm.key]]];
};
RegisterCurrentLayerCommand:
PUBLIC PROC [key:
ATOM, layer:
CD.Layer, tech:
CD.Technology, w:
CD.Number←-1] = {
tKey: ATOM ← IF tech#NIL THEN tech.key ELSE $all;
CDProperties.PutPropProp[currentLayerReg, tKey, key, LIST[NEW[CD.Layer←layer], NEW[INT←w]]];
CDSequencer.ImplementCommand[key: key, proc: SetCurrentLayer, queue: doQueue, technology: tech];
};
IncludeOb:
PUBLIC
PROC [comm: CDSequencer.Command, ob:
CD.Object, failMessage: Rope.
ROPE] = {
msg: Rope.ROPE ← failMessage;
IF ob=
NIL
THEN {
IF msg=NIL THEN failMessage ← "failed";
}
ELSE {
i: CD.Instance ← CDOps.IncludeObjectI[design: comm.design, ob: ob, location: comm.pos];
msg ← Rope.Cat["include: ", CDOps.InstRope[i]];
};
TerminalIO.PutRopes[msg, "\n"]
};
NewDesign: Commander.CommandProc = {
IF cmd#
NIL
AND cmd.procData#
NIL
THEN
WITH cmd.procData.clientData
SELECT
FROM
t:
CD.Technology => {
design: CD.Design ← CDOps.CreateDesign[t];
CDOps.SetMutability[design, editable];
[] ← CDViewer.CreateViewer[design];
cmd.out.PutRope[Rope.Cat[t.name, " design created\n"]];
RETURN
};
ENDCASE => NULL;
cmd.out.PutRope[" bad command data\n"];
};
PseudoLoadTechnology: Commander.CommandProc = {
The purpose of this procedure is to make load files look as if they did succeed;
When this procedure is registered [or called] the technology is already loaded
cmd.out.PutRope[" technology is loaded\n"];
};
RegisterCommanderNewDesign:
PUBLIC
PROC [technology:
CD.Technology] = {
CDEnvironment.RegisterCommander[
key: Rope.Cat["CDNew", technology.name],
proc: NewDesign,
doc: Rope.Cat["Creates new ", technology.name, " ChipNDale design"],
clientData: technology,
technology: technology
];
CDEnvironment.RegisterCommander[
key: Rope.Cat["CD", technology.name],
proc: PseudoLoadTechnology,
doc: Rope.Cat["Loads ", technology.name, " ChipNDale technology [but is already loaded]"],
technology: technology
];
};
resourceTab: RefTab.Ref ~ RefTab.Create[7];
END.