<> <> <> <> <> <<>> DIRECTORY Atom USING [MakeAtom], CD, CDBasics, CDCells, CDCommandOps USING [RegisterWithMenu], CDIO, CDImports USING [HasUnloadedImports], CDDirectory, CDSequencer USING [Command], CDOps, CDProperties, CDViewer USING [CreateViewer], CDToCif USING [WriteCIF], CifToCD USING [ReadFile], CMosB, Commander USING [CommandProc, Register], CommandTool, FileNames, FS USING [binaryStreamOptions, StreamOpen, Error], IO, Rope, TerminalIO USING [PutRope, PutRopes, RequestRope] ; CifCDCmds: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDCells, CDCommandOps, CDImports, CDDirectory, CDIO, CDOps, CDProperties, CDViewer, CDToCif, CifToCD, CMosB, Commander, CommandTool, FileNames, FS, IO, Rope, TerminalIO ~ BEGIN cifExt: Rope.ROPE _ ".cif"; regKey: ATOM _ $EcadErrorsCif; cifPerLambda: INT _ 100; commented: BOOLEAN _ TRUE; CDToCifCmd: PROC [comm: CDSequencer.Command] ~ { <> topCellName, fileName, msg: Rope.ROPE; cifFile: IO.STREAM; mainInst: CD.Instance; flattenAtomics: BOOLEAN; IF CDCells.IsPushedIn[comm.design] THEN { TerminalIO.PutRope["**Design is pushed in\n"]; GOTO Exit }; IF CDImports.HasUnloadedImports[comm.design].yes THEN { TerminalIO.PutRope["**Design has non bound imports\n"]; GOTO Exit }; mainInst _ CDOps.TheInstance[comm.design, "cif generation\n"]; IF mainInst=NIL THEN { TerminalIO.PutRope["**CIF generation needs single selected object\n"]; GOTO Exit }; topCellName _ CDDirectory.Name[mainInst.ob, comm.design]; fileName _ Rope.Cat[topCellName, cifExt]; cifFile _ FS.StreamOpen[fileName, create ! FS.Error => IF error.group#bug THEN { TerminalIO.PutRope[error.explanation]; GOTO Exit; } ]; TerminalIO.PutRopes["CIF file generated: ", fileName, "\n"]; flattenAtomics _ CDProperties.GetProp[$CDxCIFRegistrations, $CDxFlattenAtomic]=$TRUE; msg _ CDToCif.WriteCIF[comm.design, mainInst, cifFile, cifPerLambda, flattenAtomics]; TerminalIO.PutRope["CD -> CIF cmd finished\n"]; EXITS Exit => {TerminalIO.PutRope[" CD -> CIF cmd failed\n"]}; }; CifToCDCmd: PROC [comm: CDSequencer.Command] ~ { <> cifFile: IO.STREAM; msg: Rope.ROPE; fileName: Rope.ROPE _ TerminalIO.RequestRope["CIF file: "]; cifFile _ FS.StreamOpen[fileName, read ! FS.Error => IF error.group#bug THEN { TerminalIO.PutRope[error.explanation]; GOTO Exit; } ]; msg _ CifToCD.ReadFile[cifFile, comm.design, regKey, , , commented]; IF msg#NIL THEN {TerminalIO.PutRope[msg]; GOTO Exit}; TerminalIO.PutRope["CIF -> CD cmd finished\n"]; CDOps.Redraw[comm.design]; EXITS Exit => {TerminalIO.PutRope[" CIF -> CD cmd failed\n"]}}; ReadCifComm: Commander.CommandProc ~ { library: CD.Design _ CDOps.CreateDesign[CMosB.cmosB]; wDir: Rope.ROPE _ CommandTool.CurrentWorkingDirectory[]; nofArgs: INT; objs: LIST OF CD.Object; CDOps.SetMutability[library]; CommandTool.StarExpansion[cmd]; nofArgs _ CommandTool.NumArgs[cmd]; SELECT nofArgs FROM 1 => msg _ doc; 2 => msg _ Rope.Concat["Too few arguments", doc]; ENDCASE => { key: ATOM _ Atom.MakeAtom[CommandTool.ArgN[cmd, 1]]; FOR arg: INT IN [2..nofArgs) DO design: CD.Design _ CDOps.CreateDesign[CMosB.cmosB]; fileName: Rope.ROPE _ CommandTool.ArgN[cmd, arg]; root: Rope.ROPE _ FileNames.GetShortName[fileName]; cdFile: Rope.ROPE; obj: CD.Object; root _ root.Substr[0, root.Index[0, "."]]; cdFile _ CDIO.MakeName[root, ".dale", wDir]; IF Rope.Find[fileName, "."] = -1 THEN fileName _ Rope.Concat[fileName, ".cif"]; CDOps.SetMutability[design]; msg _ CifToCD.ReadFile[ FS.StreamOpen[ fileName: fileName, accessOptions: $read, streamOptions: FS.binaryStreamOptions, wDir: wDir ! FS.Error => {msg _ error.explanation; GOTO Failed} ], design, key]; IF msg#NIL THEN GOTO Failed; obj _ CDOps.InstList[design].first.ob; [] _ CDDirectory.Rename[design, obj, root]; [] _ CDOps.RenameDesign[design, root]; [] _ CDIO.WriteDesign[design, cdFile]; obj _ CDDirectory.AnotherRecursed[obj, library, design]; CDProperties.PutProp[obj, $CellName, root]; cmd.out.PutF[" File: %g\n", IO.rope[cdFile]]; IF nofArgs=3 THEN [] _ CDViewer.CreateViewer[design, FALSE] ELSE objs _ CONS[obj, objs]; REPEAT Failed => {result _ $Failure} ENDLOOP }; IF nofArgs>3 THEN { libraryName: IO.ROPE _ "CifLibrary"; sep: INT _ CMosB.cmosB.lambda*16; pos: CD.Position _ [0,0]; temp: LIST OF CD.Object; FOR objs _ objs, objs.rest WHILE objs#NIL DO temp _ CONS[objs.first, temp] ENDLOOP; WHILE temp#NIL DO off: CD.Position _ CDBasics.SubPoints[pos, CDBasics.BaseOfRect[CD.InterestRect[temp.first]]]; shift: INT _ ((CD.InterestSize[temp.first].x+sep+sep-1)/sep)*sep; name: IO.ROPE _ NARROW[CDProperties.GetProp[temp.first, $CellName]]; CDProperties.PutProp[temp.first, $CellName, NIL]; [] _ CDDirectory.Include[library, temp.first, name]; [] _ CDOps.IncludeObject[library, temp.first, [off]]; temp _ temp.rest; pos _ [pos.x + shift, pos.y] ENDLOOP; [] _ CDOps.RenameDesign[library, libraryName]; [] _ CDIO.WriteDesign[library, libraryName]; [] _ CDViewer.CreateViewer[library, FALSE]}}; doc: Rope.ROPE _ "\nRead a cif file into ChipNDale\n Usage: ReadCif . . .\n"; Commander.Register[key:"ReadCif", proc: ReadCifComm, doc: doc]; CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "CD->CIF", doc: "Writes a CIF file", key: $CDToCifSel, proc: CDToCifCmd]; CDCommandOps.RegisterWithMenu [menu: $ProgramMenu, entry: "CIF->CD", doc: "Reads a CIF file", key: $CifToCDSel, proc: CifToCDCmd]; END.