<> <> <> <> <<>> DIRECTORY CD USING [ApplicationPtr, CellPtr, Design, DesignNumber, DesignPosition, DesignRect, Error, ErrorCode, lambda, Layer, ObPtr, Technology, InterestRect], CDCells USING [CreateEmptyCell, RepositionCell], CDDirectory USING [Include], CDImports USING [GetReference, DoImport], CDIO USING [MakeName, WriteDesign], CDRects USING [CreateRect], CDOps USING [CreateDesign], CDSil USING [cdsil, xneutral, xred, xyellow, xgreen, xcyan, xviolet, xmagenta, xwhite, xbrown, xorange, xlime, xturquise, xaqua, xultraviolet, xpink, xsmoke], CDSilConversion, CDTexts USING [CreateText, FontRec, MakeFont], CDViewer USING [CreateViewer], CDX USING [IncludeOb, IncludeMode], Commander USING [CommandProc, Register], CommandTool USING [ParseToList], Graphics USING [FontBox], FileNames USING [CurrentWorkingDirectory], FS USING [ComponentPositions, Error, ExpandName, Position, StreamOpen], IO USING [Close, EndOf, EndOfStream, GetChar, STREAM, UnsafeGetBlock], Real USING [RoundLI, Float], Rope USING [ActionType, Cat, Concat, FromChar, FromProc, Length, Map, Replace, ROPE, SkipTo, Substr], TerminalIO USING [WriteChar, WriteInt, WriteLn, WriteRope, UserAbort, UserSaysYes], UserProfile USING [Token]; CDSilConversionImpl: CEDAR PROGRAM IMPORTS CD, CDCells, CDDirectory, CDImports, CDIO, CDOps, CDRects, CDSil, CDTexts, CDViewer, CDX, Commander, CommandTool, Graphics, FileNames, FS, IO, Real, Rope, TerminalIO, UserProfile EXPORTS CDSilConversion = BEGIN OPEN CDSilConversion; debug0: BOOL ~ FALSE; -- reading file debug1: BOOL ~ FALSE; -- converting debug2: BOOL ~ FALSE; -- integration of macro files debug3: BOOL ~ FALSE; -- main Sil model debug4: BOOL ~ FALSE; -- translation of font names debugAll: BOOL ~ debug0 OR debug1 OR debug2 OR debug3 OR debug4; <> <> <> <> <> <> <> <> <> <> <> <> <<00: Neutral 08: Brown 01: Red 09: Orange 02: Yellow 10: Lime 03: Green 11: Turquise 04: Cyan 12: Aqua 05: Violet 13: UltraViolet 06: Magenta 14: Pink 07: White 15: Smoke>> <> <> <> <<00: Font 0 01: Font 0 with "boldness" opposite to default value in profile 02: Font 1 03: Font 1 with "boldness" opposite to default value in profile 04: Font 2 05: Font 2 with "boldness" opposite to default value in profile 06: Font 3 07: Font 3 with "boldness" opposite to default value in profile 08: Font 4 macro 09: Font 5 macro 10: Font 6 macro 11: Font 7 macro 12: Font 8 macro 13: Font 9 macro 14: A line with lingth and width indicated by preceeding coordinates 15: A background with area indicated by preceeding coordinates>> <> <> <> <> <> <> <> FourBits: TYPE ~ [0..17B]; TwelveBits: TYPE ~ [0..7777B]; SixteenBits: TYPE ~ [0..177777B]; OneBit: TYPE ~ [0..1]; ElevenBits: TYPE ~ [0..3777B]; bytesInSilItemBlock: NAT ~ 10; mainElementName: CHAR ~ 377C; -- this as name of silobject means it's part of main picture checkCodeByte1: CHAR ~ '9; -- check code indicating Sil format unbuiltCheckCodeByte2: CHAR ~ 'r; builtCheckCodeByte2: CHAR ~ 's; SilBlockRef: TYPE ~ REF SilBlock; SilBlock: TYPE ~ MACHINE DEPENDENT RECORD [ leftChar, rightChar: CHAR, state : FourBits, xMin : TwelveBits, yMin : SixteenBits, color : FourBits, xMax : TwelveBits, font : FourBits, italic : OneBit, yMax : ElevenBits ]; <> TrueFonts: TYPE ~ [0..3]; MainFile: TYPE ~ [4..4]; <> SilFile: TYPE ~ [4..9]; InternalFonts: TYPE ~ [0..15]; <> InternalFileMacroFonts: TYPE ~ [8..8]; InternalTrueFonts: TYPE ~ [0..7]; InternalLibraryFile: TYPE ~ [9..13]; InternalRopeFonts: TYPE ~ [0..13]; -- those fonts which do not denote boxes. See below <> InternalForegroundBoxFonts: TYPE ~ [14..14]; InternalBackgroundBoxFonts: TYPE ~ [15..15]; mainFile: MainFile ~ 4; <> <> <> Color: TYPE ~ [0..15]; colorTable: ARRAY Color OF CD.Layer ~ [CDSil.xneutral, CDSil.xred, CDSil.xyellow, CDSil.xgreen, CDSil.xcyan, CDSil.xviolet, CDSil.xmagenta, CDSil.xwhite, CDSil.xbrown, CDSil.xorange, CDSil.xlime, CDSil.xturquise, CDSil.xaqua, CDSil.xultraviolet, CDSil.xpink, CDSil.xsmoke]; <> Font: TYPE ~ RECORD [ name: Rope.ROPE, descr: REF CDTexts.FontRec _ NIL ]; cellFonts: ARRAY InternalTrueFonts OF ARRAY BOOL OF Font; <> ObjectName: TYPE ~ CHAR[' .. '~]; -- Only printing characters are used MacroName: TYPE ~ CHAR['! .. '~]; -- All but mainObject: ObjectName ~ ' ; -- object whose name is SilObject: TYPE ~ RECORD [ xMin, yMin: INTEGER, -- Upper Left boundary of box or string xMax, yMax: INTEGER, -- Lower right boundary of box, guess for lower right of string color: Color, -- Color used to display or print silobject font: InternalFonts, italic: BOOL, -- Only interesting for Ropes (fonts 0-13), TRUE for italic strings value: Rope.ROPE _ NIL ]; SilObjectList: TYPE ~ LIST OF SilObject; Macro: TYPE ~ RECORD [ xMin, yMin: INTEGER _ 32767, -- Upper Left boundary of macro definition xMax, yMax: INTEGER _ -1, -- Lower right boundary of macro definition -- note: coordinates are Alto screen absolute, hence -1 is OK. objects: SilObjectList _ NIL, cdCellPtr: CD.ObPtr _ NIL -- This field used to generate recursion if a cell includes a cell not known yet. ]; LibraryDesign: TYPE ~ RECORD [ data: CD.Design _ NIL, imported: BOOL _ FALSE, -- Chipndale wants only a single import of the same library written: BOOL _ FALSE -- libraries are written only once per run ]; MacroPtr: TYPE ~ REF Macro _ NIL; MacroFile: TYPE ~ ARRAY ObjectName OF MacroPtr; allMacros: REF MacroFile _ NIL; silDesigns: ARRAY SilFile OF LibraryDesign; -- need all because of imports silProfilePrefix: Rope.ROPE ~ "Sil.Font"; cdSilProfilePrefix: Rope.ROPE ~ "Chipndale.chipnsil.Library"; lambda: INTEGER ~ INTEGER[CD.lambda]; -- Sil uses integers throughout lambdaAltoScreenHeights: INTEGER ~ lambda * 808; <> CrackNames: PROC [genericName: Rope.ROPE] RETURNS [fullSilName: Rope.ROPE, properName: Rope.ROPE] ~ { <> namePos: FS.ComponentPositions; silExtension: Rope.ROPE ~ "sil"; dummy: Rope.ROPE; -- in Cedar 5.2 FS.ExpandName does not work as documented fullSilName _ CDIO.MakeName [base: genericName, ext: silExtension, wDir: FileNames.CurrentWorkingDirectory[]]; [fullFName: dummy, cp: namePos] _ FS.ExpandName [name: fullSilName]; properName _ Rope.Substr [base: dummy, start: namePos.base.start, len: namePos.base.length] }; -- end CrackNames <> TechnologyIsCdsil: PROC [d: CD.Design] RETURNS [b: BOOL] ~ { IF d = NIL THEN CD.Error [explanation: "Programming error in ReadSilLibrary"]; RETURN [d.technology = CDSil.cdsil] }; -- end TechnologyIsCdsil <> ReadSilModel: PUBLIC PROC [name: Rope.ROPE] RETURNS [design: CD.Design _ NIL] ~ { <> designName: Rope.ROPE; [fullSilName: name, properName: designName] _ CrackNames [name]; <> <> <> <> <<}>> <> <> FOR lib: LibraryFile IN LibraryFile DO <> silDesigns[lib].data _ NIL; silDesigns[lib].imported _ FALSE ENDLOOP; design _ CDOps.CreateDesign [technology: CDSil.cdsil]; design.name _ designName; silDesigns[mainFile].data _ design; ReadSilFile [fileName: name]; ConvertSilFile [file: mainFile]; IF TerminalIO.UserSaysYes [label: "CDSilConversion", text: Rope.Cat["Shall I write ", designName, " to disk ?\n"], default: TRUE] THEN { IF NOT CDIO.WriteDesign [design: design, to: designName] THEN { TerminalIO.WriteRope ["Warning: The design "]; TerminalIO.WriteRope [designName]; TerminalIO.WriteRope [" cannot be written. Proceeding anyway.\n"] } }; <<};>> [] _ CDViewer.CreateViewer [design: design]; <> }; -- end ReadSilModel <> ReadSilLibrary: PUBLIC PROC [library: LibraryFile] RETURNS [cells: CD.Design _ NIL] ~ { <> libraryPrefix: Rope.ROPE ~ "sil.lb"; -- Cedar Sil designPrefix: Rope.ROPE ~ "SilLib"; -- Chipnsil macroFileName, cdFileName, defaultName, designName: Rope.ROPE; key: Rope.ROPE; -- Access key for the User Profile. <> IF silDesigns[library].data # NIL THEN RETURN [silDesigns[library].data]; <> key _ Rope.Concat [cdSilProfilePrefix, Rope.FromChar['0 + library]]; defaultName _ Rope.Cat [designPrefix, Rope.FromChar['0 + library], ".dale"]; cdFileName _ UserProfile.Token [key: key, default: defaultName]; designName _ CrackNames [cdFileName].properName; <> <> <> <> <> <> <> <> <> key _ Rope.Concat [silProfilePrefix, Rope.FromChar['0 + library]]; defaultName _ Rope.Concat [libraryPrefix, Rope.FromChar['0 + library]]; macroFileName _ UserProfile.Token [key: key, default: defaultName]; <> ReadSilFile [fileName: macroFileName]; cells _ CDOps.CreateDesign[technology: CDSil.cdsil]; cells.name _ designName; silDesigns[library].data _ cells; ConvertSilFile [file: library]; <> IF TerminalIO.UserSaysYes[label: "CDSilConversion", text: Rope.Cat["Shall I write ", designName, " to disk ?\n"], default: FALSE] THEN { IF NOT silDesigns[library].written THEN { silDesigns[library].written _ CDIO.WriteDesign [design: cells, to: cdFileName]; IF NOT silDesigns[library].written THEN { TerminalIO.WriteRope ["Warning: The design "]; TerminalIO.WriteRope [designName]; TerminalIO.WriteRope [" cannot be written. Proceeding anyway.\n"] } } }; RETURN [cells] <<}>> }; -- end ReadSilLibrary SetFonts: PROC [] ~ { <> key: Rope.ROPE; -- Access key for the User Profile. TrueFontsDefaults: TYPE ~ ARRAY TrueFonts OF Rope.ROPE; trueFontsDefaults: TrueFontsDefaults ~ ["Helvetica10", "Helvetica7", "Template64", "Gates32"]; italic: BOOL ~ TRUE; FixAttibutes: PROC [coarseName: Rope.ROPE] RETURNS [notBold, italic, both: Rope.ROPE] ~ { <> properName, dummy, attributes, notBAttr: Rope.ROPE; namePos: FS.ComponentPositions; attributePos, bPos: INTEGER; alreadyItalic: BOOL; [fullFName: dummy, cp: namePos] _ FS.ExpandName [name: coarseName]; properName _ Rope.Substr [base: dummy, start: namePos.base.start, len: namePos.base.length]; attributePos _ properName.SkipTo [0, "0123456789"]; attributes _ properName.Substr [attributePos, properName.Length[]-attributePos]; <> bPos _ attributes.SkipTo [0, "bB"]; IF bPos = attributes.Length[] THEN notBAttr _ Rope.Concat [attributes, "B"] ELSE notBAttr _ Rope.Replace [base: attributes, start: bPos, len: 1]; <> alreadyItalic _ (attributes.SkipTo [0, "iI"] # attributes.Length []); IF NOT alreadyItalic THEN attributes _ Rope.Concat [attributes, "I"]; <> notBold _ Rope.Replace [base: properName, start: attributePos, len: properName.Length[]-attributePos, with: notBAttr]; italic _ Rope.Replace [base: properName, start: attributePos, len: properName.Length[]-attributePos, with: attributes]; IF alreadyItalic THEN both _ notBold ELSE { notBAttr _ Rope.Concat [notBAttr, "I"]; both _ Rope.Replace [base: properName, start: attributePos, len: properName.Length[]-attributePos, with: notBAttr] }; IF debug4 THEN { TerminalIO.WriteRope [Rope.Cat["Original font: ", coarseName, ", notBold: "]]; TerminalIO.WriteRope [Rope.Cat[notBold, ", italic: ", italic, ", both: ", both, "\n"]] } }; -- end FixAttibutes FOR i: TrueFonts IN TrueFonts DO <> key _ Rope.Concat [silProfilePrefix, Rope.FromChar ['0 + i]]; cellFonts[2*i][~italic].name _ UserProfile.Token [key: key, default: trueFontsDefaults[i]]; [cellFonts[2*i+1][~italic].name, cellFonts[2*i][italic].name, cellFonts[2*i+1][italic].name] _ FixAttibutes [cellFonts[2*i][~italic].name]; ENDLOOP }; -- end SetFonts MakeCDFont: PROC [nr: InternalTrueFonts, italic: BOOL] ~ { fullName: Rope.ROPE; fullName _ CDIO.MakeName [base: cellFonts[nr][italic].name, ext: "Strike", wDir: "/Indigo/AltoFonts/"]; cellFonts[nr][italic].descr _ CDTexts.MakeFont [name: fullName, scale: Real.Float[lambda]]; IF cellFonts[nr][italic].descr = NIL THEN { -- in case Indigo is busy or down fullName _ CDIO.MakeName [base: cellFonts[nr][italic].name, ext: "Strike", wDir: "[ivy]strikefonts>"]; cellFonts[nr][italic].descr _ CDTexts.MakeFont [name: fullName, scale: Real.Float[lambda]] }; IF cellFonts[nr][italic].descr = NIL THEN { TerminalIO.WriteRope [Rope.Cat["CDTexts.MakeFont returns not found on ", fullName, ". Fatal error.\n"]]; ERROR ABORTED } }; -- end MakeCDFont ConvertSilFile: PROC [file: SilFile] ~ { <> MacroToObject: PROC [sil: MacroPtr, name: ObjectName] RETURNS [object: CD.ObPtr _ NIL] ~ { <> size, position: CD.DesignPosition _ [0, 0]; cdObPtr: CD.ObPtr _ NIL; -- object before it is either a cell or an application cell: CD.ObPtr _ NIL; -- NIL when object is not a cell boundingBox: CD.DesignRect; -- interesting rectangle height: INTEGER _ 0; -- height of cell or main object workingOnMainObject: BOOL; impName: Rope.ROPE; -- global importee name assigned in FOR loop and used in CrackLibraryMacroSeq CrackFileMacroSeq: PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE] ~ { <> cdObPtr: CD.ObPtr; -- object before it is either a cell or an application boundingBox: CD.DesignRect; -- interesting rectangle IF allMacros[c].cdCellPtr = NIL THEN { IF debug1 THEN { TerminalIO.WriteRope [" will prepone macro "]; TerminalIO.WriteChar [c]; TerminalIO.WriteLn[] }; cdObPtr _ MacroToObject [allMacros[c], c]; } ELSE cdObPtr _ allMacros[c].cdCellPtr; [] _ CDX.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, position: position, obCSystem: interrestCoords, mode: dontPropagate]; <> boundingBox _ CD.InterestRect[cdObPtr]; position.x _ position.x + (boundingBox.x2 - boundingBox.x1) }; -- end CrackFileMacroSeq CrackLibraryMacroSeq: PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE] ~ { <> cdObPtr: CD.ObPtr; boundingBox: CD.DesignRect; -- interesting rectangle cdObPtr _ CDImports.GetReference [design: silDesigns[file].data, objectName: Rope.FromChar[c], importeeName: impName]; IF cdObPtr = NIL THEN CD.Error [ec: other, explanation: "CDImports.GetReference failed"]; [] _ CDX.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, position: position, obCSystem: interrestCoords, mode: dontPropagate]; <> boundingBox _ CD.InterestRect[cdObPtr]; position.x _ position.x + (boundingBox.x2 - boundingBox.x1) }; -- end CrackLibraryMacroSeq workingOnMainObject _ (name = ' ); height _ IF workingOnMainObject THEN lambdaAltoScreenHeights ELSE lambda * (sil.yMax - sil.yMin); boundingBox _ [lambda*sil.xMin, height - lambda*sil.yMax, lambda*sil.xMax, height - lambda*sil.yMin]; IF workingOnMainObject THEN cell _ NIL ELSE { cell _ CDCells.CreateEmptyCell []; IF cell = NIL THEN CD.Error [ec: other, explanation: "Cannot create cell"]; <> NARROW [cell.specificRef, CD.CellPtr].simplifyOn _ height / (2 * lambda); NARROW[cell.specificRef, CD.CellPtr].ir _ boundingBox; NARROW[cell.specificRef, CD.CellPtr].useDIr _ FALSE; [] _ CDDirectory.Include [design: silDesigns[file].data, object: cell, alternateName: Rope.FromChar[name]]; IF debug2 AND ((name = 'B) OR (name = 'x)) THEN { TerminalIO.WriteRope ["SetInterestRect to "]; TerminalIO.WriteInt [boundingBox.x1]; TerminalIO.WriteInt [boundingBox.y1]; TerminalIO.WriteInt [boundingBox.x2]; TerminalIO.WriteInt [boundingBox.y2]; TerminalIO.WriteLn } }; FOR silObj: SilObjectList _ sil.objects, silObj.rest WHILE silObj # NIL DO size.x _ lambda * (silObj.first.xMax - silObj.first.xMin); size.y _ lambda * (silObj.first.yMax - silObj.first.yMin); position.x _ lambda * silObj.first.xMin; position.y _ height - lambda * silObj.first.yMax; <> SELECT silObj.first.font FROM IN InternalTrueFonts => { cdFont: REF CDTexts.FontRec; xmin, ymin, xmax, ymax: REAL; -- "ascent" is ymax; "descent" is -ymin. IF (cellFonts[silObj.first.font][silObj.first.italic].descr = NIL) THEN MakeCDFont [silObj.first.font, silObj.first.italic]; cdFont _ cellFonts[silObj.first.font][silObj.first.italic].descr; cdObPtr _ CDTexts.CreateText [text: silObj.first.value, font: cdFont, layer: colorTable[silObj.first.color]]; IF cdObPtr = NIL THEN CD.Error [ec: other, explanation: "Cannot create text"]; [xmin, ymin, xmax, ymax] _ Graphics.FontBox[cdFont.font]; <> <<[xmin, ymin, xmax, ymax] _ Graphics.CharBox[cdFont.font, Rope.Fetch [base: silObj.first.value]];>> <> position.y _ height - lambda * (silObj.first.yMin + Real.RoundLI[ymax]); <> <> IF debug2 AND ((name = 'B) OR (name = 'x)) THEN { TerminalIO.WriteRope ["Value, scendent and y position: "]; TerminalIO.WriteRope [silObj.first.value]; TerminalIO.WriteInt [Real.RoundLI[ymax]]; TerminalIO.WriteInt [position.y]; TerminalIO.WriteLn [] }; [] _ CDX.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, position: position, obCSystem: interrestCoords, mode: dontPropagate] }; IN InternalFileMacroFonts => { IF debug1 THEN { TerminalIO.WriteChar [name]; TerminalIO.WriteRope [" calls a cell in the same design:\n"] }; [] _ Rope.Map [base: silObj.first.value, action: CrackFileMacroSeq] }; IN InternalLibraryFile => { <> externalFileNr: LibraryFile; -- Since the exported procedure works with the external library file numbering, we cannot use the internal Sil numbering when we call our procedures. IF debug1 THEN TerminalIO.WriteRope ["Import of a cell in another design.\n"]; externalFileNr _ silObj.first.font - mainFile; IF (silDesigns[externalFileNr].data = NIL) THEN [] _ ReadSilLibrary [externalFileNr]; IF NOT silDesigns[externalFileNr].imported THEN { silDesigns[externalFileNr].imported _ CDImports.DoImport [design: silDesigns[file].data, importee: silDesigns[externalFileNr].data]; IF NOT silDesigns[externalFileNr].imported THEN IF file IN MainFile THEN CD.Error [ec: other, explanation: "Cannot import library"] ELSE CD.Error [ec: other, explanation: "Library tried to import other library"] }; impName _ silDesigns[externalFileNr].data.name; -- assigned to a global variable, so that it can be used inside CrackLibraryMacroSeq [] _ Rope.Map [base: silObj.first.value, action: CrackLibraryMacroSeq] }; IN InternalForegroundBoxFonts => { cdObPtr _ CDRects.CreateRect [size: size, l: colorTable[silObj.first.color]]; IF cdObPtr = NIL THEN CD.Error [ec: other, explanation: "Cannot create rectangle"]; [] _ CDX.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, position: position, obCSystem: interrestCoords, mode: dontPropagate] }; IN InternalBackgroundBoxFonts => { TerminalIO.WriteRope ["Warning: Background box attribute ignored.\n"]; <> cdObPtr _ CDRects.CreateRect [size: size, l: colorTable[silObj.first.color]]; IF cdObPtr = NIL THEN CD.Error [ec: other, explanation: "Cannot create rectangle"]; [] _ CDX.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, position: position, obCSystem: interrestCoords, mode: dontPropagate] }; ENDCASE => CD.Error [explanation: "Invalid case in CDSilConversionImpl.MacroToObject"] ENDLOOP; IF NOT workingOnMainObject THEN [] _ CDCells.RepositionCell [cellOb: cell, design: silDesigns[file].data]; object _ IF workingOnMainObject THEN cdObPtr ELSE cell; sil.cdCellPtr _ object; sil.objects _ NIL; -- dispose obsolete space IF debug1 THEN { TerminalIO.WriteRope ["Converted object "]; TerminalIO.WriteChar [name]; TerminalIO.WriteLn[] }; RETURN [object] }; -- end MacroToObject <> FOR obj: MacroName IN MacroName DO IF ((allMacros[obj] # NIL) AND (allMacros[obj].cdCellPtr = NIL)) THEN <> [] _ MacroToObject [allMacros[obj], obj] ENDLOOP; IF ((allMacros[mainObject] # NIL) AND (allMacros[mainObject].cdCellPtr = NIL)) THEN <> [] _ MacroToObject [allMacros[mainObject], mainObject]; IF debugAll THEN TerminalIO.WriteRope ["Sil macro file converted to Chipndale model\n"] }; -- end ConvertSilFile ReadSilFile: PROC [fileName: Rope.ROPE] ~ { <> sBlock: SilBlockRef _ NEW [SilBlock]; AddItemBlockToMacro: PROC [itemBlock: SilObject, name: CHAR] ~ { m: MacroPtr _ allMacros[name]; IF m = NIL THEN m _ NEW [Macro]; <> m.xMin _ MIN [m.xMin, itemBlock.xMin]; m.yMin _ MIN [m.yMin, itemBlock.yMin]; m.xMax _ MAX [m.xMax, itemBlock.yMax]; m.yMax _ MAX [m.yMax, itemBlock.yMax]; <> m.objects _ CONS [itemBlock, m.objects]; allMacros[name] _ m }; -- end AddItemBlockToMacro ReadItemBlock: PROC [s: IO.STREAM] RETURNS [name: CHAR, itemBlock: SilObject] ~ { <> ENABLE IO.EndOfStream => CD.Error [ec: other, explanation: "Unexpected End Of Stream"]; <<>> ReadChar: PROC[] RETURNS [c: CHAR] ~ { <> RETURN [s.GetChar[] ]; }; -- end ReadChar <<>> <
> maxRecLen: INTEGER ~ 256; --the longest a record can be (1 byte for its length) len: INTEGER; TRUSTED { bytesGot: INT _ s.UnsafeGetBlock[ [base: LOOPHOLE[sBlock], startIndex: 0, count: bytesInSilItemBlock] ]; IF bytesGot # bytesInSilItemBlock THEN CD.Error [ec: other, explanation: "Macro file corrupted"] }; name _ IF sBlock.leftChar = mainElementName THEN ' ELSE sBlock.rightChar; <<-- name depends on whether is part of main picture ot macro.>> <<-- state of item block (normal, selected, deleted) is ignored.>> itemBlock.xMin _ sBlock.xMin; itemBlock.yMin _ sBlock.yMin; itemBlock.xMax _ sBlock.xMax; itemBlock.yMax _ sBlock.yMax; itemBlock.color _ sBlock.color; itemBlock.font _ sBlock.font; itemBlock.italic _ (sBlock.italic = 1); IF debug0 THEN { TerminalIO.WriteLn; TerminalIO.WriteChar [name]; TerminalIO.WriteInt [ORD[name]]; {OPEN itemBlock; TerminalIO.WriteRope [": xMin, yMin:"]; TerminalIO.WriteInt [xMin]; TerminalIO.WriteInt [yMin]; TerminalIO.WriteRope [". xMax, yMax:"]; TerminalIO.WriteInt [xMax]; TerminalIO.WriteInt [yMax]; TerminalIO.WriteRope [". Col:"]; TerminalIO.WriteInt [color]; TerminalIO.WriteRope [". Font:"]; TerminalIO.WriteInt [font]; IF color # 0 THEN TerminalIO.WriteRope ["***"]; IF NOT italic THEN TerminalIO.WriteRope [", not"]; TerminalIO.WriteRope [" italic "]; } }; IF itemBlock.font IN InternalRopeFonts THEN { len _ s.GetChar[] - 0C; itemBlock.value _ Rope.FromProc[len, ReadChar, maxRecLen]; IF debug0 THEN TerminalIO.WriteRope [itemBlock.value]; IF len MOD 2 = 0 THEN --Make sure to start next item block on a word boundary [] _ s.GetChar[]; --Flush the extra slot for a Char } }; -- end ReadItemBlock { header1, header2: CHAR; s: IO.STREAM _ FS.StreamOpen [fileName ! FS.Error => IF error.group#bug THEN { TerminalIO.WriteRope [Rope.Cat [fileName, " not opened: ", error.explanation]]; ERROR ABORTED } ]; name: CHAR; itemBlock: SilObject; IF debugAll THEN { TerminalIO.WriteRope [fileName]; TerminalIO.WriteLn }; header1 _ s.GetChar[]; header2 _ s.GetChar[]; IF (header1 = checkCodeByte1) AND (header2 = unbuiltCheckCodeByte2) THEN { IF debugAll THEN TerminalIO.WriteRope ["Sil file format OK.\n"] } ELSE IF (header1 = checkCodeByte1) AND (header2 = builtCheckCodeByte2) THEN TerminalIO.WriteRope ["Sil schematic file has been 'build' into a wire-list file via the Build process.\n"] ELSE TerminalIO.WriteRope ["File not in Sil format. Proceeding anyway.\n"]; allMacros _ NEW [MacroFile]; WHILE NOT s.EndOf[] DO [name, itemBlock] _ ReadItemBlock [s]; <> AddItemBlockToMacro [itemBlock, name] <> ENDLOOP; IO.Close[s] } }; -- end ReadSilFile ReadModel: Commander.CommandProc = BEGIN ENABLE { TerminalIO.UserAbort => GOTO UserAbrt; }; list: LIST OF Rope.ROPE; length: NAT; name: Rope.ROPE; [list, length] _ CommandTool.ParseToList [cmd]; IF length = 1 THEN name_list.first ELSE { result_$Failure; msg_"unknown arguments"; TerminalIO.WriteRope ["Read command failed\n"]; RETURN }; TerminalIO.WriteRope ["Warning: Strings of macros as they occour in the synoptic tables are not aligned correctly.\n"]; [] _ ReadSilModel [name]; <> <> <<[] _ CDViewer.CreateViewer [design: synopsis]; CDOps.Redraw [synopsis] -- optional>> EXITS UserAbrt => {TerminalIO.WriteRope ["Read aborted\n"]}; END; <> SetFonts[]; Commander.Register [key: "CDReadSil", proc: ReadModel, doc: "Read a SIL model into chipndale"] END. <> <> <> <> <<>>