<> <> <> <> DIRECTORY CD, CDCells, CDExtras, CDGenerate, CDGenerateBackdoor, CDIO, CDMenus, CDMenuSpecials, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, Commander, CommandTool, FileNames, Rope, TerminalIO, UserProfile; CDGenerateCommands: CEDAR PROGRAM IMPORTS CD, CDCells, CDGenerate, CDGenerateBackdoor, CDExtras, CDIO, CDMenus, CDMenuSpecials, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, Commander, CommandTool, FileNames, Rope, TerminalIO, UserProfile = 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 _ CDExtras.ToRope[CDProperties.GetPropFromDesign[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.WriteRope[Rope.Cat["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.AddAnObject[design, ob, comm.pos]; TerminalIO.WriteRope[CDOps.Info[ob]]; TerminalIO.WriteRope[" included\n"] } } END; SelectGenerators: PROC [comm: CDSequencer.Command] = BEGIN key: Rope.ROPE; design: CD.Design _ comm.design; tableKey: Rope.ROPE _ TableKey[design]; TerminalIO.WriteRope[Rope.Cat["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.WriteRope[Rope.Cat["now uses [", key, "]\n"]]; CDProperties.PutPropOnDesign[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.WriteRope[Rope.Cat["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 pos: CD.Position; bb: CD.Rect _ [0, 0, 0, 0]; IF CDOps.InstList[design]#NIL THEN bb _ CDExtras.BoundingBox[design]; pos.y _ bb.y1; pos.x _ bb.x2 + ABS[100 + bb.x2 - bb.x1]/10; [] _ 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; GO TO Die} ]; IF argv.argc#5 OR ~Rope.Equal[argv[3], "_"] THEN { msg _ Rope.Cat["command should be ", commandFormat]; result _ $Failure; RETURN }; 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"; result _ $Failure; RETURN }; design _ GetDesign[inFile]; IF design=NIL THEN { msg _ "design not found"; result _ $Failure; RETURN }; ob _ CDGenerate.FetchNCall[table, design, genName]; IF ob=NIL THEN { msg _ "object not created"; result _ $Failure; RETURN }; AddConveniant[design, ob]; IF ~OutDesign[design, outFile] THEN { msg _ "object not created"; result _ $Failure; RETURN }; TerminalIO.WriteRope["object generated\n"]; EXITS Die => result _ $Failure; END; <<>> Init: PROC [] = BEGIN [] _ CDMenus.CreateMenu["Generator options", $GeneratorMenu]; CDMenus.ImplementMenuCommand[$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: "CDGenerate", proc: CDGenerateCommand, doc: Rope.Cat["CD patchwork like GeneratorProc: ", commandFormat], clientData: $CDGenerate ]; CDValue.EnregisterKey[$CDUsesGeneratorName! CD.Error => CONTINUE]; CDPanel.DefineButton[name: "generator", proc: SelectGenerators]; CDPanel.DefineLabel[name: " ", cdValueKey: $GeneratorProc]; CDPanel.DefineNewLine[]; END; Init[]; END.