<> <> <> <> <> DIRECTORY Basics USING [bytesPerWord], CD USING [CellPtr, Design, Error, ErrorCode, Instance, InterestRect, InterestSize, Layer, Object, Position, Rect, Technology], CDCells USING [CreateEmptyCell, IncludeMode, IncludeOb, RepositionCell, SetInterestRect], CDDirectory USING [Include], CDImports USING [Load, CreateImport], CDIO USING [MakeName, ReadDesign, WriteDesign], CDOps USING [CreateDesign], CDProperties USING [PutObjectProp, RegisterProperty], CDRects USING [CreateRect], CDSil USING [cdsil, xaqua, xbrown, xcyan, xgreen, xlime, xmagenta, xneutral, xorange, xpink, xred, xsmoke, xturquise, xultraviolet, xviolet, xwhite, xyellow], CDSilConversion, CDTexts USING [CreateText, FontRec, MakeFont], CDViewer USING [CreateViewer], Commander USING [CommandProc, Register], CommandTool USING [ParseToList], FileNames USING [CurrentWorkingDirectory], FS USING [ComponentPositions, Error, ExpandName, Position, StreamOpen], ImagerFont USING [Extents, Font, RopeBoundingBox], IO USING [Close, EndOf, EndOfStream, GetChar, STREAM, UnsafeGetBlock], Real USING [Round], Rope USING [ActionType, Cat, Concat, FromChar, FromProc, Length, Map, Replace, ROPE, SkipTo, Substr], TerminalIO USING [WriteChar, WriteInt, WriteLn, WriteRope, UserAbort, Confirm], UserProfile USING [CallWhenProfileChanges, ProfileChangedProc, Token]; CDSilConversionImpl: CEDAR PROGRAM IMPORTS CD, CDCells, CDDirectory, CDImports, CDIO, CDOps, CDProperties, CDRects, CDSil, CDTexts, CDViewer, Commander, CommandTool, FileNames, FS, ImagerFont, IO, Real, Rope, TerminalIO, UserProfile EXPORTS CDSilConversion = BEGIN OPEN CDSilConversion; <> convLibEachTime: BOOL = FALSE; -- convert all library files for each model verbose: BOOL = FALSE; -- Asks the user whether he wants to write the converted model and libraries <> 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]; SevenBits: TYPE ~ [0..177B]; TwelveBits: TYPE ~ [0..7777B]; SixteenBits: TYPE ~ [0..177777B]; OneBit: TYPE ~ [0..1]; ElevenBits: TYPE ~ [0..3777B]; 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; largeFormatFileByte2: CHAR ~ 'l; -- new password for large format files SilBlockRef: TYPE ~ REF SilBlock; LargeSilBlockRef: TYPE ~ REF LargeSilBlock; --new format for large format files SilBlock: TYPE ~ MACHINE DEPENDENT RECORD [ leftChar, rightChar: CHAR, state : FourBits, xMin : TwelveBits, yMin : SixteenBits, color : FourBits, xMax : TwelveBits, font : FourBits, italic : OneBit, yMax : ElevenBits ]; LargeSilBlock: TYPE ~ MACHINE DEPENDENT RECORD [ leftChar, rightChar: CHAR, xMin: INTEGER, yMin: INTEGER, xMax: INTEGER, yMax: INTEGER, color: FourBits, font: FourBits, italic: OneBit, pad: SevenBits _ 0 ]; <> 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]; neutralColor: Color ~ 0; <> Font: TYPE ~ RECORD [ name: Rope.ROPE, descr: REF READONLY 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 <> objects: SilObjectList _ NIL, cdCellPtr: CD.Object _ 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 background: ATOM = $SilBackground; silProfilePrefix: Rope.ROPE ~ "Sil.Font"; cdSilProfilePrefix: Rope.ROPE ~ "Chipndale.chipnsil.Library"; lambda: INTEGER = CDSil.cdsil.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; write: BOOL _ NOT verbose; [fullSilName: name, properName: designName] _ CrackNames [name]; IF convLibEachTime THEN 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 verbose THEN write _ TerminalIO.Confirm [label: "CDSilConversion", choice: Rope.Cat["Write ", designName, " to disk ?"]]; IF write THEN IF NOT CDIO.WriteDesign [design: design, to: designName] THEN TerminalIO.WriteRope [Rope.Cat["Warning: The design ", designName, " 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. write: BOOL _ NOT verbose; <> 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]; IF NOT convLibEachTime THEN BEGIN <> cells _ CDIO.ReadDesign [from: cdFileName, check: TechnologyIsCdsil]; IF cells # NIL THEN {silDesigns[library].data _ cells; RETURN [cells]} ELSE TerminalIO.WriteRope [Rope.Cat["The library file ", cdFileName, " is not available. It is being converted from ", macroFileName, "\n"]]; END; -- NOT convLibEachTime <> ReadSilFile [fileName: macroFileName]; cells _ CDOps.CreateDesign[technology: CDSil.cdsil]; cells.name _ designName; silDesigns[library].data _ cells; ConvertSilFile [file: library]; <> IF verbose THEN write _ TerminalIO.Confirm[label: "CDSilConversion", choice: Rope.Cat["Write ", designName, " to disk ?"]]; IF write THEN { IF NOT silDesigns[library].written THEN { silDesigns[library].written _ CDIO.WriteDesign [design: cells, to: cdFileName]; IF NOT silDesigns[library].written THEN TerminalIO.WriteRope [Rope.Cat["Warning: The design ", designName, " cannot be written. Proceeding anyway.\n"]] } }; -- IF write RETURN [cells] }; -- end ReadSilLibrary SetFonts: UserProfile.ProfileChangedProc ~ { <> 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]]; TerminalIO.WriteRope [Rope.Cat[", 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 _ Rope.Cat ["Xerox/TiogaFonts/", cellFonts[nr][italic].name]; cellFonts[nr][italic].descr _ CDTexts.MakeFont[name: fullName, scale: 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.Object _ NIL] ~ { <> size, position: CD.Position _ [0, 0]; topLeftPos: CD.Position _ [0, 0]; cdObPtr: CD.Object _ NIL; -- object before it is either a cell or an application cell: CD.Object _ NIL; -- NIL when object is not a cell boundingBox: CD.Rect; -- interesting rectangle height: INTEGER _ 0; -- height of cell or main object import, workingOnMainObject: BOOL; impName: Rope.ROPE; -- global importee name assigned in FOR loop and used in ExpandRope ExpandRope: PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE] ~ { <> cdObPtr: CD.Object; -- object before it is either a cell or an application sz, pos: CD.Position; IF import THEN BEGIN <> cdObPtr _ CDImports.CreateImport[into: silDesigns[file].data, objectName: Rope.FromChar[c], importeeName: impName]; IF cdObPtr = NIL THEN CD.Error [ec: other, explanation: "CDImports.CreateImport failed"]; <> END ELSE -- not import: file macro <> 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; sz _ CD.InterestSize[cdObPtr]; pos _ [topLeftPos.x, topLeftPos.y-sz.y]; topLeftPos.x _ topLeftPos.x + sz.x; [] _ CDCells.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, position: pos, obCSystem: interrestCoords, mode: dontPropagate]; }; -- end ExpandRope workingOnMainObject _ (name = ' ); height _ IF workingOnMainObject THEN lambdaAltoScreenHeights ELSE lambda * (sil.yMax - sil.yMin); boundingBox _ [x1: lambda*sil.xMin, y1: height - lambda*sil.yMax, x2: lambda*sil.xMax, y2: height - lambda*sil.yMin]; IF workingOnMainObject THEN cell _ NIL ELSE { ir: CD.Rect _ [x1: lambda*sil.xMin, y1: height - lambda*sil.yMax, x2: lambda*sil.xMax, y2: height - lambda*sil.yMin]; cell _ CDCells.CreateEmptyCell[]; CDCells.SetInterestRect[cell, ir]; 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); topLeftPos.x _ position.x _ lambda * silObj.first.xMin; position.y _ height - lambda * silObj.first.yMax; topLeftPos.y _ height - lambda * silObj.first.yMin; SELECT silObj.first.font FROM IN InternalTrueFonts => { cdFont: REF READONLY CDTexts.FontRec; er: ImagerFont.Extents; 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"]; IF debug2 AND ((name = 'B) OR (name = 'x)) THEN { TerminalIO.WriteRope [Rope.Concat ["Value, scendent and y position: ", silObj.first.value]]; TerminalIO.WriteInt [position.y]; TerminalIO.WriteLn [] }; er _ ImagerFont.RopeBoundingBox [cdFont.font, silObj.first.value]; position.y _ height - lambda * silObj.first.yMin - Real.Round[er.ascent] - cdFont.origin.y; [] _ CDCells.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, position: position, obCSystem: cdCoords, mode: dontPropagate] }; IN InternalFileMacroFonts => { IF debug1 THEN { TerminalIO.WriteChar [name]; TerminalIO.WriteRope [" calls a cell in the same design:\n"] }; import _ FALSE; [] _ Rope.Map [base: silObj.first.value, action: ExpandRope] }; 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.Load[into: silDesigns[file].data, importeeName: silDesigns[externalFileNr].data.name]; 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 ExpandRope import _ TRUE; [] _ Rope.Map [base: silObj.first.value, action: ExpandRope] }; IN InternalForegroundBoxFonts => { cdObPtr _ CDRects.CreateRect [size: size, l: colorTable[silObj.first.color]]; [] _ CDCells.IncludeOb [design: silDesigns[file].data, cell: cell, ob: cdObPtr, position: position, obCSystem: interrestCoords, mode: dontPropagate] }; IN InternalBackgroundBoxFonts => { <> cdObPtr _ CDRects.CreateRect [size: size, l: colorTable[silObj.first.color]]; CDProperties.PutObjectProp [onto: cdObPtr, prop: background, val: background]; [] _ CDCells.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 { ir: CD.Rect; NARROW [cell.specificRef, CD.CellPtr].simplifyOn _ height / (2 * lambda); [] _ CDCells.RepositionCell [cellOb: cell, design: NIL]; ir _ CD.InterestRect [cell]; ir.x2 _ ir.x1+cell.size.x; CDCells.SetInterestRect [cell, ir]; [] _ CDDirectory.Include [design: silDesigns[file].data, object: cell, alternateName: Rope.FromChar[name]]; }; 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]; largesBlock: LargeSilBlockRef _ NEW [LargeSilBlock]; largeFormat: BOOL _ FALSE; block: LONG POINTER _ NIL; -- either sBlock or largesBlock bytesInSilItemBlock: INTEGER; -- depends on above 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 BEGIN bytesGot: INT _ s.UnsafeGetBlock [ [base: block, startIndex: 0, count: bytesInSilItemBlock]]; IF bytesGot # bytesInSilItemBlock THEN CD.Error [ec: other, explanation: "Macro file corrupted"] END; IF largeFormat THEN BEGIN name _ IF largesBlock.leftChar = mainElementName THEN ' ELSE largesBlock.rightChar; <> <> itemBlock.xMin _ largesBlock.xMin; itemBlock.yMin _ largesBlock.yMin; itemBlock.xMax _ largesBlock.xMax; itemBlock.yMax _ largesBlock.yMax; itemBlock.color _ largesBlock.color; itemBlock.font _ largesBlock.font; itemBlock.italic _ (largesBlock.italic = 1) END ELSE BEGIN name _ IF sBlock.leftChar = mainElementName THEN ' ELSE sBlock.rightChar; <> <> 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) END; 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 BEGIN header1, header2: CHAR; name: CHAR; itemBlock: SilObject; s: IO.STREAM _ FS.StreamOpen [fileName ! FS.Error => IF error.group#bug THEN { TerminalIO.WriteRope [Rope.Cat [fileName, " not opened: ", error.explanation]]; ERROR ABORTED } ]; IF debugAll THEN {TerminalIO.WriteRope [fileName]; TerminalIO.WriteLn}; header1 _ s.GetChar[]; header2 _ s.GetChar[]; IF (header1 # checkCodeByte1) THEN BEGIN TerminalIO.WriteRope ["File not in Sil format.\n"]; ERROR ABORTED END; SELECT header2 FROM unbuiltCheckCodeByte2 => IF debugAll THEN TerminalIO.WriteRope ["Sil file format OK.\n"]; builtCheckCodeByte2 => TerminalIO.WriteRope ["Sil schematic file has been 'build' into a wire-list file via the Build process.\n"]; largeFormatFileByte2 => largeFormat _ TRUE; ENDCASE => BEGIN TerminalIO.WriteRope ["File not in Sil format.\n"]; ERROR ABORTED END; TRUSTED {block _ IF largeFormat THEN LOOPHOLE [largesBlock] ELSE LOOPHOLE [sBlock]}; bytesInSilItemBlock _ IF largeFormat THEN SIZE [LargeSilBlock] * Basics.bytesPerWord ELSE SIZE [SilBlock] * Basics.bytesPerWord; allMacros _ NEW [MacroFile]; WHILE NOT s.EndOf[] DO [name, itemBlock] _ ReadItemBlock [s]; <> AddItemBlockToMacro [itemBlock, name] <> ENDLOOP; IO.Close[s] END }; -- 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 }; IF convLibEachTime THEN TerminalIO.WriteRope ["All libraries will be converted as they are referenced.\n"] ELSE TerminalIO.WriteRope ["If they exist, the libraries specified in the user profile entries 'ChipNDale.ChipNSil.Library%' will be used. Delete them to force the creation of new ones.\n"]; [] _ ReadSilModel [name]; <> <> <<[] _ CDViewer.CreateViewer [design: synopsis]; CDOps.Redraw [synopsis] -- optional>> EXITS UserAbrt => {TerminalIO.WriteRope ["Read aborted\n"]}; END; <> UserProfile.CallWhenProfileChanges [SetFonts]; IF NOT CDProperties.RegisterProperty [prop: background, registrationKey: $GBB] THEN TerminalIO.WriteRope ["CDSilConversionImpl re-executed"]; -- somebody is already using it Commander.Register [key: "CDReadSil", proc: ReadModel, doc: "Read a SIL model into ChipNSil and save it"] END. <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>>