CDIOCommands.mesa
Copyright (C) 1984, Xerox Corporation. All rights reserved.
Last Edited by: Jacobi, February 8, 1984 9:41 am
Last Edited by: Jacobi, February 12, 1986 11:42:41 am PST
DIRECTORY
CD,
CDExtras,
CDIO,
CDOps,
CDDirectory,
CDPanel,
CDProperties,
CDSequencer,
CDValue,
CDViewer USING [CreateViewer],
Commander USING [CommandProc, Register],
CommandTool,
Rope,
TerminalIO;
CDIOCommands: CEDAR PROGRAM
IMPORTS CDDirectory, CD, CDExtras, CDIO, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, Commander, CommandTool, Rope, TerminalIO =
BEGIN
IncludeCommand: PROC [comm: CDSequencer.Command] =
BEGIN
Forward: PROC [a: ATOM] = INLINE {
CDSequencer.ExecuteCommand[comm: comm, command: a, queue: dontQueue];
};
yes: BOOL;
TerminalIO.WriteRope["include the directory of 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.ROPENIL] 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: BOOL�LSE]--
BEGIN
IF NOT CDDirectory.Remove[design: from, name: name, expectObject: ob] THEN ERROR;
[] ← CDDirectory.Include[design: design, object: ob, alternateName: SkipAt[name]];
CDProperties.PutPropOnObject[ob, $CameFrom, from.name];
CDProperties.PutPropOnObject[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 missmatch: includee is ", design.technology.name, "\n"];
END;
done: BOOLFALSE;
design: CD.Design;
ob: CD.Object;
pos: CD.Position;
TerminalIO.WriteRope["really include the directory of an input design\n"];
design ← CDIO.ReadDesign[NIL, Check];
IF design#NIL THEN {
[ob, pos] ← MergeIn[design: comm.design, from: design];
IF ob#NIL THEN {
CDOps.AddAnObject[comm.design, ob, pos];
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: REFNIL;
TerminalIO.WriteRope["write design to a file\n"];
IF comm.a=$SaveDesign THEN
to ← CDValue.Fetch[comm.design, $CDxFromFile];
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.a=$SaveDesign THEN {
comm.a ← $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.