CDGenerateCommands.mesa (part of ChipNDale)
Copyright © 1985, 1987 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 5, 1985 8:02:35 pm PDT
Last edited by: Christian Jacobi, May 5, 1987 5:51:54 pm PDT
DIRECTORY
CD,
CDCells,
CDDirectory,
CDDirectoryOps,
CDEnvironment,
CDGenerate,
CDGenerateBackdoor,
CDIO,
CDMenuSpecials,
CDOps,
CDPanel,
CDProperties,
CDSequencer,
CDValue,
CDViewer,
Commander,
CommandTool,
FileNames,
Rope,
TerminalIO,
UserProfile;
CDGenerateCommands: CEDAR PROGRAM
IMPORTS CD, CDCells, --CDDirectory, CDDirectoryOps,-- CDEnvironment, CDGenerate, CDGenerateBackdoor, CDIO, CDMenuSpecials, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, CommandTool, FileNames, Rope, TerminalIO, UserProfile
SHARES CD =
BEGIN
ProfileKey: PROC [] RETURNS [r: Rope.ROPE] = {
r ← UserProfile.Token[key: "ChipNDale.GeneratorProc", default: "DIRECTORY"]
};
ContextKey: PROC [design: CD.Design] RETURNS [r: Rope.ROPE] = {
r ← CDOps.ToRope[CDProperties.GetDesignProp[design, $GeneratorProc]];
IF Rope.IsEmpty[r] THEN
r ← CDOps.ToRope[CDValue.Fetch[design, $GeneratorProc, global]];
IF Rope.IsEmpty[r] THEN
r ← ProfileKey[];
};
InteractiveKey: PROC [key: Rope.ROPE] RETURNS [BOOL] = {
IF Rope.Equal[key, doInteractive] THEN RETURN [TRUE];
IF Rope.SkipOver[key, 0, " "]=Rope.Length[key] THEN RETURN [TRUE];
RETURN [FALSE]
};
Generate: PROC [comm: CDSequencer.Command] = {
key: Rope.ROPE;
ob: CD.Object;
design: CD.Design ← comm.design;
contextKey: Rope.ROPE ← ContextKey[design];
context: CDGenerate.Context ← CDGenerate.AssertContext[contextKey];
TerminalIO.PutRopes["draw object from [", contextKey, "]\n"];
key ← CDPanel.TakeDownText[design, $CDxGeneratorObName];
IF InteractiveKey[key] THEN
key ← CDGenerate.SelectOneOf[context, "select generator"];
IF Rope.IsEmpty[key] THEN TerminalIO.PutRope["no name given\n"]
ELSE {
ob ← CDGenerate.FetchNCall[context, comm.design, key];
IF ob=NIL THEN TerminalIO.PutRope["failed\n"]
ELSE {
i: CD.Instance ← CDOps.IncludeObjectI[design, ob, comm.pos];
CleanUp[comm.design];
TerminalIO.PutRopes[CDOps.InstRope[i], " included\n"];
}
}
};
SelectGenerators: PROC [comm: CDSequencer.Command] = {
key: Rope.ROPE;
design: CD.Design ← comm.design;
contextKey: Rope.ROPE ← ContextKey[design];
TerminalIO.PutRopes["select object generator; currently uses [", contextKey, "]\n"];
key ← CDMenuSpecials.SelectOneOf[CDGenerateBackdoor.publicContexts, "select generator"];
IF Rope.IsEmpty[key] THEN TerminalIO.PutRope["not changed\n"]
ELSE {
TerminalIO.PutRopes["now uses [", key, "] for generator\n"];
CDProperties.PutDesignProp[design, $GeneratorProc, key];
CDValue.Store[design, $GeneratorProc, key];
CDPanel.PutUpAll[design];
}
};
FlushGenerators: PROC [comm: CDSequencer.Command] = {
contextKey: Rope.ROPE ← ContextKey[comm.design];
TerminalIO.PutRopes["flush generators [", contextKey, "]\n"];
CDGenerate.FlushAll[CDGenerate.AssertContext[contextKey], comm.design];
};
commandFormat: Rope.ROPE = """CDGenerate generator {outFile|*} ← {inFile|^technology}""";
CDGenerateCommand: Commander.CommandProc = {
[cmd: REF CommandObject] RETURNS [result: REFNIL, msg: ROPENIL]
CommandObject = [
in, out, err: STREAM, commandLine, command: ROPE,
propertyList: List.AList, procData: CommandProcHandle]
GetDesign: PROC [name: Rope.ROPE] RETURNS [design: CD.Design ← NIL] = {
IF Rope.Length[name]<1 THEN {msg ← "bad name"; RETURN};
IF Rope.Fetch[name, 0] = '^ THEN {
n: Rope.ROPE ← Rope.Substr[name, 1, Rope.Length[name]];
tech: CD.Technology ← CDEnvironment.LoadTechnology[NIL, n];
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.PutRope["** pushed in\n"];
}
}
};
OutDesign: PROC [design: CD.Design, name: Rope.ROPE] RETURNS [done: BOOL] = {
IF Rope.Equal[name, "*"] THEN
done ← CDViewer.CreateViewer[design]#NIL
ELSE
done ← CDIO.WriteDesign[design: design, to: name, quiet: TRUE];
};
ob: CD.Object; design: CD.Design;
genName: Rope.ROPE; inFile, outFile: Rope.ROPE;
generator: CDGenerate.GeneratorProc;
contextKey: Rope.ROPE ← ProfileKey[];
context: CDGenerate.Context ← CDGenerate.AssertContext[contextKey];
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd, FALSE, '←
! 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.PutRope["GeneratorProc called\n"];
genName ← argv[1];
outFile ← FileNames.ResolveRelativePath[argv[2]];
inFile ← FileNames.ResolveRelativePath[argv[4]];
generator ← CDGenerate.FetchRegistration[context, 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[context, design, genName];
IF ob=NIL THEN {
msg ← "object not created"; GOTO die
};
[] ← CDOps.PlaceInst[design, ob];
CleanUp[design];
IF ~OutDesign[design, outFile] THEN {
msg ← "object not created"; GOTO die
};
TerminalIO.PutRope["object generated\n"];
EXITS die => result ← $Failure;
};
doInteractive: Rope.ROPE ~ "← interactive";
Init: PROC [] = {
CDSequencer.ImplementCommand[$CallGenerator, Generate];
CDSequencer.ImplementCommand[$FlushGenerators, FlushGenerators];
CDSequencer.ImplementCommand[$SelectGenerators, SelectGenerators];
CDEnvironment.RegisterCommander[
key: "CDGenerate",
proc: CDGenerateCommand,
doc: Rope.Cat["ChipNDale object generator: ", commandFormat],
clientData: $CDGenerate
];
CDValue.RegisterKey[$CDUsesGeneratorName! CD.Error => CONTINUE];
CDPanel.Button[button: [text: "generator:"], proc: SelectGenerators];
CDPanel.Label[label: [width: 110, cdValueKey: $GeneratorProc, redisplay: TRUE]];
CDValue.Store[NIL, $GeneratorProc, ProfileKey[]];
CDValue.Store[NIL, $CDxGeneratorObName, doInteractive];
CDPanel.Text[text: [cdValueKey: $CDxGeneratorObName], button: [text: "name:", xpos: 180]];
CDPanel.Line[];
};
CleanUp: PROC [design: CD.Design] = {
--we don't for now;
--I believe nobody violates directory invariants anymore since ChipNDale2.5
n: INT ← CDDirectory.DirSize[design];
CDDirectoryOps.CleanUp[design];
IF n#CDDirectory.DirSize[design] THEN
TerminalIO.PutF["**consistency check fixed %g objects\n", [integer[CDDirectory.DirSize[design]-n]]];
};
Init[];
END.