<> <> <> <> <> <<>> DIRECTORY Atom USING [MakeAtom], CD USING [Design, Instance], CDCells USING [IsPushedIn], CDCommandOps USING [RegisterWithMenu], CDIO, CDImports USING [HasUnloadedImports], CDDirectory USING [Name], CDSequencer USING [Command], CDOps, CDProperties USING [GetProp], CDViewer USING [CreateViewer], CDToCif USING [WriteCIF], CifToCD USING [ReadFile], CMosB USING [cmosB], Commander USING [CommandProc, Register], CommandTool USING [ArgN, CurrentWorkingDirectory, NumArgs], FileNames, FS USING [binaryStreamOptions, StreamOpen, Error], IO USING [STREAM], Rope USING [ROPE, Cat, Concat, Find], TerminalIO USING [PutRope, PutRopes, RequestRope] ; CifCDCmds: CEDAR PROGRAM IMPORTS Atom, CDCells, CDCommandOps, CDImports, CDDirectory, CDIO, CDOps, CDProperties, CDViewer, CDToCif, CifToCD, CMosB, Commander, CommandTool, FileNames, FS, 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 ~ { wDir: Rope.ROPE _ CommandTool.CurrentWorkingDirectory[]; nofArgs: INT _ 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 _ CDIO.MakeName[root, ".dale", wDir]; root _ root.Substr[0, root.Index[0, "."]]; 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; [] _ CDOps.RenameDesign[design, root]; [] _ CDIO.WriteDesign[design, cdFile]; cmd.out.PutF[" File: %g\n", IO.rope[cdFile]]; IF nofArgs=3 THEN [] _ CDViewer.CreateViewer[design, FALSE]; REPEAT Failed => {result _ $Failure} ENDLOOP } }; 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.