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, March 20, 1987 6:55:02 pm PST
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: REF ← NIL, msg: ROPE ← NIL]
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] = {
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.