<> <> <> <> 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: 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; 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.