CDGenerateCommands.mesa (part of ChipNDale)
Copyright © 1985 by Xerox Corporation. All rights reserved.
by Christian Jacobi, June 5, 1985 8:02:35 pm PDT
Last Edited by Christian Jacobi, March 25, 1986 1:29:52 pm PST
DIRECTORY
CD,
CDCells,
CDCleanUp,
CDCommandOps,
CDDirectory,
CDExtras,
CDGenerate,
CDGenerateBackdoor,
CDIO,
CDMenus,
CDMenuSpecials,
CDOps,
CDPanel,
CDProperties,
CDSequencer,
CDValue,
CDViewer,
Commander,
CommandTool,
FileNames,
Rope,
TerminalIO,
UserProfile;
CDGenerateCommands: CEDAR PROGRAM
IMPORTS CD, CDCells, CDCleanUp, CDCommandOps, CDDirectory, CDGenerate, CDGenerateBackdoor, CDExtras, CDIO, CDMenus, CDMenuSpecials, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, Commander, CommandTool, FileNames, Rope, TerminalIO, UserProfile
SHARES CD =
BEGIN
ProfileKey: PROC [] RETURNS [r: Rope.ROPE] =
BEGIN
r ← UserProfile.Token[key: "ChipNDale.GeneratorProc", default: "USER"]
END;
TableKey: PROC [design: CD.Design] RETURNS [r: Rope.ROPE] =
BEGIN
r ← CDCommandOps.ToRope[CDProperties.GetDesignProp[design, $GeneratorProc]];
IF Rope.IsEmpty[r] THEN r ← ProfileKey[];
END;
Generate: PROC [comm: CDSequencer.Command] =
BEGIN
key: Rope.ROPE;
ob: CD.Object;
design: CD.Design ← comm.design;
tableKey: Rope.ROPE ← TableKey[design];
table: CDGenerate.Table ← CDGenerate.AssertTable[tableKey];
TerminalIO.WriteRopes["select programm generated object [", tableKey, "]\n"];
key ← CDGenerate.SelectOneOf[table, "select generate"];
IF Rope.IsEmpty[key] THEN TerminalIO.WriteRope["no generator selected\n"]
ELSE {
ob ← CDGenerate.FetchNCall[table, comm.design, key];
IF ob=NIL THEN TerminalIO.WriteRope["doesn't return object\n"]
ELSE {
CDOps.IncludeObjectI[design, ob, comm.pos];
CleanUp[comm.design];
TerminalIO.WriteRopes[CDOps.ObjectInfo[ob], " included\n"];
}
}
END;
SelectGenerators: PROC [comm: CDSequencer.Command] =
BEGIN
key: Rope.ROPE;
design: CD.Design ← comm.design;
tableKey: Rope.ROPE ← TableKey[design];
TerminalIO.WriteRopes["select programm generator; currently uses [", tableKey, "]\n"];
key ← CDMenuSpecials.SelectOneOf[CDGenerateBackdoor.publicTables, "select generator"];
IF Rope.IsEmpty[key] THEN TerminalIO.WriteRope["not changed\n"]
ELSE {
TerminalIO.WriteRopes["now uses [", key, "]\n"];
CDProperties.PutDesignProp[design, $GeneratorProc, key];
CDValue.Store[design, $GeneratorProc, key];
CDPanel.RedisplayLabels[design];
}
END;
FlushGenerators: PROC [comm: CDSequencer.Command] =
BEGIN
tableKey: Rope.ROPE ← TableKey[comm.design];
TerminalIO.WriteRopes["flush generators [", tableKey, "]\n"];
CDGenerate.FlushAll[CDGenerate.AssertTable[tableKey], comm.design];
END;
commandFormat: Rope.ROPE = """CDGenerate generator {out|*} ← {in|-tech}""";
CDGenerateCommand: Commander.CommandProc =
[cmd: REF CommandObject] RETURNS [result: REFNIL, msg: ROPENIL]
CommandObject = [
in, out, err: STREAM, commandLine, command: ROPE,
propertyList: List.AList, procData: CommandProcHandle]
BEGIN
GetDesign: PROC [name: Rope.ROPE]
RETURNS [design: CD.Design ← NIL] =
BEGIN
IF Rope.Length[name]<1 THEN {msg ← "bad name"; RETURN};
IF Rope.Fetch[name, 0] = '- THEN {
tech: CD.Technology ← CDExtras.GetTechnology[Rope.Substr[name, 1, Rope.Length[name]]];
IF tech=NIL THEN {result ← $Failure; msg ← "technology not loaded"; RETURN};
design ← CDOps.CreateDesign[tech];
}
ELSE {
design ← CDIO.ReadDesign[from: name];
IF design #NIL THEN {
IF CDCells.IsPushedIn[design] THEN TerminalIO.WriteRope["** pushed in\n"];
}
}
END;
OutDesign: PROC [design: CD.Design, name: Rope.ROPE] RETURNS [done: BOOL]=
BEGIN
IF Rope.Equal[name, "*"] THEN
done ← CDViewer.CreateViewer[design]#NIL
ELSE
done ← CDIO.WriteDesign[design: design, to: name, quiet: TRUE];
END;
AddConveniant: PROC [design: CD.Design, ob: CD.Object] =
BEGIN
l4: CD.Number = design.technology.lambda*4;
pos: CD.Position;
bb: CD.Rect ← [0, 0, 0, 0];
IF CDOps.InstList[design]#NIL THEN bb ← CDCommandOps.BoundingBox[design];
pos.y ← (bb.y1+l4-1)/l4*l4;
pos.x ← (bb.x2 + ABS[100 + bb.x2 - bb.x1]/10 + l4 - 1)/l4*l4;
[] ← CDCells.IncludeOb[design: design, ob: ob, position: pos, obCSystem: cdCoords];
END;
ob: CD.Object; design: CD.Design;
genName: Rope.ROPE; inFile, outFile: Rope.ROPE;
generator: CDGenerate.GeneratorProc;
tableKey: Rope.ROPE ← ProfileKey[];
table: CDGenerate.Table ← CDGenerate.AssertTable[tableKey];
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd
! CommandTool.Failed => {msg ← errorMsg; GOTO die}
];
IF argv.argc#5 OR ~Rope.Equal[argv[3], "←"] THEN {
msg ← Rope.Cat["command should be ", commandFormat]; GOTO die
};
TerminalIO.WriteRope["GeneratorProc called\n"];
genName ← argv[1];
outFile ← FileNames.ResolveRelativePath[argv[2]];
inFile ← FileNames.ResolveRelativePath[argv[4]];
generator ← CDGenerate.FetchRegistration[table, genName].generator;
IF generator=NIL THEN {
msg ← "generator not found"; GOTO die
};
design ← GetDesign[inFile];
IF design=NIL THEN {
msg ← "design not found"; GOTO die
};
ob ← CDGenerate.FetchNCall[table, design, genName];
IF ob=NIL THEN {
msg ← "object not created"; GOTO die
};
AddConveniant[design, ob];
IF ~OutDesign[design, outFile] THEN {
msg ← "object not created"; GOTO die
};
CleanUp[design];
TerminalIO.WriteRope["object generated\n"];
EXITS
die => result ← $Failure;
END;
Init: PROC [] =
BEGIN
CDMenus.ImplementCommandToCallMenu[$GeneratorMenu, $GeneratorMenu];
CDMenus.CreateEntry[$GeneratorMenu, "select generator", $SelectGenerators];
CDMenus.CreateEntry[$GeneratorMenu, "flush current generator", $FlushGenerators];
CDSequencer.ImplementCommand[$CallGenerator, Generate];
CDSequencer.ImplementCommand[$FlushGenerators, FlushGenerators];
CDSequencer.ImplementCommand[$SelectGenerators, SelectGenerators];
Commander.Register[
key: "///Commands/CDGenerate",
proc: CDGenerateCommand,
doc: Rope.Cat["ChipNDale object generator: ", commandFormat],
clientData: $CDGenerate
];
CDValue.RegisterKey[$CDUsesGeneratorName! CD.Error => CONTINUE];
CDPanel.DefineButton[name: "generator", proc: SelectGenerators];
CDPanel.DefineLabel[name: " ", cdValueKey: $GeneratorProc];
CDPanel.DefineNewLine[];
END;
CleanUp: PROC [design: CD.Design] =
BEGIN
n: INT ← CDDirectory.DirSize[design];
CDCleanUp.CleanUp[design];
IF n#CDDirectory.DirSize[design] THEN TerminalIO.WriteF["**consistency check fixed %g objects\n", [integer[CDDirectory.DirSize[design]-n]]];
END;
Init[];
END.