DIRECTORY Basics USING [BITAND], Convert USING [RopeFromChar], FS USING [StreamOpen], IO USING [EndOf, GetByte, STREAM], Rope USING [Cat, ROPE], ExpertPCBRead, SymTab USING [Create, Insert, Ref]; ExpertPCBReadImpl: CEDAR PROGRAM IMPORTS Basics, Convert, FS, IO, Rope, SymTab EXPORTS ExpertPCBRead ~ BEGIN ROPE: TYPE = Rope.ROPE; PCBTable: TYPE = ExpertPCBRead.PCBTable; Part: TYPE = ExpertPCBRead.Part; PartRep: TYPE = ExpertPCBRead.PartRep; bufferSize: NAT = 50; BufferRep: TYPE = RECORD[ size: NAT _ bufferSize, lastentryindex: NAT, table: ARRAY[0..bufferSize) OF BYTE ]; Buffer: TYPE = REF BufferRep; CircularBufferPut: PROC [buffer: Buffer, i: BYTE] ~ { buffer.lastentryindex _ buffer.lastentryindex + 1; IF buffer.lastentryindex = bufferSize THEN buffer.lastentryindex _ 0; buffer.table[buffer.lastentryindex] _ i; }; CircularBufferGet: PROC [buffer: Buffer, offset: INT] RETURNS [i: BYTE] ~ { index: INT; index _ buffer.lastentryindex + offset; IF index < 0 THEN index _ index + bufferSize; IF index - bufferSize >= 0 THEN index _ index - bufferSize; i _ buffer.table[index]; }; IsChar: PROC [i: BYTE] RETURNS [yes: BOOLEAN _ FALSE] ~ { IF i IN [ORD['A]..ORD['Z]] OR i IN [ORD['a]..ORD['z]] THEN yes _ TRUE; }; IsNum: PROC [i: BYTE] RETURNS [yes: BOOLEAN _ FALSE] ~ { IF i IN [ORD['0]..ORD['9]] THEN yes _ TRUE; }; TryMatch: PROC [buffer: Buffer, pCBTable: SymTab.Ref] ~ { part: Part; orient: NAT; refDesLength: NAT; refDes: ROPE; IF NOT IsChar[CircularBufferGet[buffer, -3]] THEN RETURN; IF (NOT IsNum[CircularBufferGet[buffer, -2]]) AND (NOT IsChar[CircularBufferGet[buffer, -2]]) THEN RETURN; orient _ Basics.BITAND[CircularBufferGet[buffer, -19], 07FH]; -- Mask the MSB orient _ orient * 256 + CircularBufferGet[buffer, -18]; IF orient # 0 AND orient # 90 AND orient # 180 AND orient # 270 THEN RETURN; refDesLength _ CircularBufferGet[buffer, -4]; refDes _ Convert.RopeFromChar[VAL[CircularBufferGet[buffer, -3]], FALSE]; refDes _ Rope.Cat[refDes, Convert.RopeFromChar[VAL[CircularBufferGet[buffer, -2]], FALSE]]; SELECT refDesLength FROM = 3 => { refDes _ Rope.Cat[refDes, Convert.RopeFromChar[VAL[CircularBufferGet[buffer, -1]], FALSE]]; }; = 4 => { refDes _ Rope.Cat[refDes, Convert.RopeFromChar[VAL[CircularBufferGet[buffer, -1]], FALSE]]; refDes _ Rope.Cat[refDes, Convert.RopeFromChar[VAL[CircularBufferGet[buffer, 0]], FALSE]]; }; ENDCASE; part _ NEW[PartRep]; part.x _ CircularBufferGet[buffer, -23]; part.x _ part.x * 256 + CircularBufferGet[buffer, -22]; part.y _ CircularBufferGet[buffer, -21]; part.y _ - (part.y * 256 + CircularBufferGet[buffer, -20]); part.orientation _ orient; part.libraryEntry _ CircularBufferGet[buffer, -27]; part.libraryEntry _ part.libraryEntry * 256 + CircularBufferGet[buffer, -26]; part.libraryEntry _ part.libraryEntry * 256 + CircularBufferGet[buffer, -29]; part.libraryEntry _ part.libraryEntry * 256 + CircularBufferGet[buffer, -28]; IF part.libraryEntry < 200 THEN RETURN; [] _ SymTab.Insert[pCBTable, refDes, part]; }; ReadPCBFile: PUBLIC PROC [file: ROPE] RETURNS [pCBTable: PCBTable] ~ { i: INT; buffer: Buffer _ NEW[BufferRep]; in: IO.STREAM _ FS.StreamOpen[file]; pCBTable _ SymTab.Create[]; WHILE NOT IO.EndOf[in] DO CircularBufferPut[buffer, IO.GetByte[in]]; i _ CircularBufferGet[buffer, -4]; IF i = 2 OR i = 3 OR i = 4 THEN TryMatch[buffer, pCBTable]; ENDLOOP; }; END. ΊExpertPCBReadImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Christophe Cuenod, April 2, 1989 11:45:18 pm PDT Reads an Expert .pcb file and retrieve from this file for each part: the position the orientation the number of pins the library entry number For each part in the .pcb file the entry looks like (in bytes): 4 EntryNumber of the library 2 ? 2 X 2 Y 2 Orientation (MSB used to tell if placed on the drawing) 11 ? 1 Number of pins 1 ? 1 Length of the Reference designator 2, 3 or 4 Reference designator The program first search for correct Reference designator Length (2, 3 or 4), then it verify that the first character of the Reference designator is alphabetic and the remainder alphabetic or numeric. It then verify that the Orientation is 0, 90, 180 or 270. If all those tests are OK it thinks it found a correct entry and pick the interesting fields. Private procedures Used to test only for Numerical character but was changed to accomodate RefDes with 2 alphabetic characters. (10-4-88 JCC) The orientation of a part should be 0, 90, 180 or 270. No library entry should be under 200 Public Procedures 2, 3 or 4 can be the length of a reference designator. Κ:˜code•Mark outsideHeaderšœ™Kšœ<™