CDGenerateCommands.mesa (part of ChipNDale)
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, June 5, 1985 8:02:35 pm PDT
Last Edited by: Christian Jacobi, August 6, 1986 2:07:32 pm PDT
DIRECTORY
CD,
CDCells,
CDCleanUp,
CDCommandOps,
CDCommandOpsExtras,
CDDirectory,
CDExtras,
CDGenerate,
CDGenerateBackdoor,
CDIO,
CDMenuSpecials,
CDOps,
CDPanel,
CDPanelExtras,
CDProperties,
CDSequencer,
CDValue,
CDViewer,
Commander,
CommandTool,
FileNames,
Rope,
TerminalIO,
UserProfile;
CDGenerateCommands: CEDAR PROGRAM
IMPORTS CD, CDCells, CDCleanUp, CDCommandOps, CDCommandOpsExtras, CDDirectory, CDGenerate, CDGenerateBackdoor, CDExtras, CDIO, CDMenuSpecials, CDOps, CDPanel, CDPanelExtras, 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: "DIRECTORY"]
END;
TableKey: PROC [design: CD.Design] RETURNS [r: Rope.ROPE] =
BEGIN
r ← CDCommandOps.ToRope[CDProperties.GetDesignProp[design, $GeneratorProc]];
IF Rope.IsEmpty[r] THEN
r ← CDCommandOps.ToRope[CDValue.Fetch[design, $GeneratorProc, global]];
IF Rope.IsEmpty[r] THEN
r ← ProfileKey[];
END;
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] =
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["draw object from [", tableKey, "]\n"];
key ← CDPanelExtras.FromDisplayRope[design, $CDxGeneratorObName];
IF InteractiveKey[key] THEN
key ← CDGenerate.SelectOneOf[table, "select generator"];
IF Rope.IsEmpty[key] THEN TerminalIO.WriteRope["no name given\n"]
ELSE {
ob ← CDGenerate.FetchNCall[table, comm.design, key];
IF ob=NIL THEN TerminalIO.WriteRope["failed\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 object 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, "] for generator\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;
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
};
[] ← CDCommandOpsExtras.PlaceInst[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;
doInteractive: Rope.ROPE ~ "← interactive";
Init: PROC [] =
BEGIN
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];
CDValue.Store[NIL, $GeneratorProc, ProfileKey[]];
CDValue.Store[NIL, $CDxGeneratorObName, doInteractive];
CDPanelExtras.DefineTextEntry[cdValueKey: $CDxGeneratorObName, button: "name:"];
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.