CDIOCommands.mesa
Copyright (C) 1984, 1986 Xerox Corporation. All rights reserved.
Created by: Christian Jacobi, February 8, 1984 9:41 am
Last Edited by: Christian Jacobi, August 6, 1986 11:01:08 am PDT
DIRECTORY
CD,
CDEnvironment,
CDExtras,
CDCommandOpsExtras,
CDIO,
CDOps,
CDDirectory,
CDPanel,
CDProperties,
CDSequencer,
CDValue,
CDViewer USING [CreateViewer],
Commander USING [CommandProc, Register],
CommandTool,
Rope,
TerminalIO;
CDIOCommands:
CEDAR
PROGRAM
IMPORTS CDDirectory, CD, CDCommandOpsExtras, CDEnvironment, CDExtras, CDIO, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, Commander, CommandTool, Rope, TerminalIO =
BEGIN
IncludeCommand:
PROC [comm: CDSequencer.Command] =
BEGIN
Forward:
PROC [key:
ATOM] =
INLINE {
CDSequencer.ExecuteCommand[comm: comm, key: key, queue: dontQueue];
};
yes: BOOL;
TerminalIO.WriteRope["include an input design\n"];
TerminalIO.WriteRope[" (but usually people want to import other designs)\n"];
yes ← TerminalIO.Confirm[label: "you really want to include?", choice: "yes"];
TerminalIO.WriteRope[IF yes THEN " yes\n" ELSE " no, import\n"];
Forward[IF yes THEN $ReallyIncludeADesign ELSE $Import]
END;
MergeIn:
PROC [design:
CD.Design, from:
CD.Design, name: Rope.
ROPE←
NIL]
RETURNS [ob:
CD.Object←
NIL, pos:
CD.Position] =
--DANGEROUS PROC
--"from" is transfered to an object, and is included (transitive) to "design"'s directory
--"from" then may be resetted (preserving the rule: any object is in at most one directory)
--the caller is assumed to have the locks of both designs
--if "from" is pushed in, it's merged copy will be popped out, either by flushing,
--replacing or creating new cells
--"name" replaces "from"'s design name for the new created object, but it is a hint only
--"pos": if "ob" is included at position "pos" in an empty design we would get "from" again
--the "from"'s object's may change name to avoid conflicts with "design"'s directory
--ob gets nil if "from" is empty
--technologies must be compatible
BEGIN
SkipAt:
PROC [n: Rope.
ROPE]
RETURNS [Rope.
ROPE] =
--skip everything after and inclusive first "@"
BEGIN
RETURN [Rope.Substr[base: n, len: Rope.SkipTo[s: n, skip: "@"]]]
END;
IncludeOneEntry: CDDirectory.EachEntryAction =
--[name: Rope.ROPE, ob: CD.Object] RETURNS [quit: BOOLLSE]--
BEGIN
IF NOT CDDirectory.Remove[design: from, name: name, expectObject: ob] THEN ERROR;
[] ← CDDirectory.Include[design: design, object: ob, alternateName: SkipAt[name]];
CDProperties.PutObjectProp[ob, $CameFrom, from.name];
CDProperties.PutObjectProp[ob, $OriginalName, SkipAt[name]];
END;
IF design=from THEN RETURN;
IF design.technology#from.technology
THEN
RETURN WITH ERROR CD.Error[callingError, "MergIn design has different technology"];
[ob, pos] ← CDExtras.Cellize[from, name];
IF ob#
NIL
THEN {
[] ← CDDirectory.Enumerate[design: from, action: IncludeOneEntry];
CDOps.ResetDesign[from];
}
ELSE ob ← NIL
END;
ReallyIncludeCommand:
PROC [comm: CDSequencer.Command] =
BEGIN
Check:
PROC [design:
CD.Design]
RETURNS [ok:
BOOL] =
BEGIN
ok ← design.technology=comm.design.technology;
IF
NOT ok
THEN
TerminalIO.WriteRopes["technology miss-match: includee is ", design.technology.name, "\n"];
END;
done: BOOL ← FALSE;
design: CD.Design;
ob: CD.Object;
pos: CD.Position;
TerminalIO.WriteRope["include input design\n"];
design ← CDIO.ReadDesign[NIL, Check, CDEnvironment.GetWorkingDirectory[comm.design]];
IF design#
NIL
THEN {
[ob, pos] ← MergeIn[design: comm.design, from: design];
IF ob#
NIL
THEN {
[] ← CDCommandOpsExtras.PlaceInst[comm.design, ob, comm];
done ← TRUE;
};
};
IF done THEN TerminalIO.WriteRope["include done\n"]
ELSE TerminalIO.WriteRope["include not done\n"];
END;
ReadCommand: Commander.CommandProc =
BEGIN
ENABLE {
TerminalIO.UserAbort => GOTO UserAbrt;
};
design: CD.Design;
list: LIST OF Rope.ROPE;
length: NAT;
name: Rope.ROPE;
result ← $Failure;
[list, length] ← CommandTool.ParseToList[cmd];
IF length=0 THEN name←NIL
ELSE IF length=1 THEN name ← list.first
ELSE {
msg ← "unknown arguments";
RETURN
};
IF Rope.Length[name]>1
AND Rope.Fetch[name, 0] = '-
THEN {
tech: CD.Technology ← CDExtras.GetTechnology[Rope.Substr[name, 1, Rope.Length[name]]];
IF tech=NIL THEN {msg ← "technology not loaded"; RETURN};
design ← CDOps.CreateDesign[tech];
}
ELSE design ← CDIO.ReadDesign[name];
IF design=NIL THEN msg ← "read not done"
ELSE {
[] ← CDViewer.CreateViewer[design];
result ← design;
msg ← Rope.Concat["design ", IF design.name=NIL THEN "no name" ELSE design.name];
};
TerminalIO.WriteRopes[msg, "\n"];
EXITS
UserAbrt => {result ← $Failure; msg ← "aborted"};
END;
WriteCommand:
PROC [comm: CDSequencer.Command] =
BEGIN
done: BOOL;
to: REF←NIL;
TerminalIO.WriteRope["write design to a file\n"];
IF comm.key=$SaveDesign
THEN
to ← CDValue.Fetch[comm.design, $CDxLastFile];
done ← CDIO.WriteDesign[design: comm.design, to: to];
IF done THEN TerminalIO.WriteRope["done\n"]
ELSE {
WITH to
SELECT
FROM
r: Rope.ROPE => TerminalIO.WriteRopes["write to ", r, " "];
ENDCASE => NULL;
TerminalIO.WriteRope["not done\n"];
};
IF ~done
AND to#
NIL
AND comm.key=$SaveDesign
THEN {
comm.key ← $OutputDesign;
WriteCommand[comm];
};
END;
-- Module Initialization
Commander.Register[
key: "///commands/CDRead",
proc: ReadCommand,
doc: "Read a ChipNDale design file"
];
Commander.Register[
key: "///commands/CDOpen",
proc: ReadCommand,
doc: "Open a ChipNDale design: CDOpen {file|-technology}"
];
CDSequencer.ImplementCommand[$ReallyIncludeADesign, ReallyIncludeCommand,, doQueue];
CDSequencer.ImplementCommand[$IncludeADesign, IncludeCommand,, doQueue];
CDSequencer.ImplementCommand[$OutputDesign, WriteCommand,, doQueue];
CDSequencer.ImplementCommand[$SaveDesign, WriteCommand,, doQueue];
CDPanel.DefineButton[tech: NIL, name: "save", command: $SaveDesign, topLine: TRUE];
END.