<> <> <> <> 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: REF _ NIL, msg: ROPE _ NIL]>> <> <> <> 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.