-- file TableSymbols.mesa -- last edited by Satterthwaite, February 4, 1980 1:11 PM DIRECTORY BcdDefs: FROM "bcddefs", SegmentDefs: FROM "segmentdefs", StringDefs: FROM "stringdefs" USING [SubStringDescriptor, AppendString], Symbols: FROM "symbols", SymbolTable: FROM "symboltable" USING [Base, Acquire, Release, TableForSegment], Table: FROM "table" USING [Base], TableCommand: FROM "tablecommand"; TableSymbols: PROGRAM IMPORTS SegmentDefs, StringDefs, SymbolTable EXPORTS TableCommand = BEGIN -- public interface BadInterface: PUBLIC ERROR [STRING] = CODE; FindInterface: PUBLIC PROCEDURE [id: STRING] RETURNS [ version: BcdDefs.VersionStamp, symbolSeg: SegmentDefs.FileSegmentHandle] = BEGIN bcdPages: CARDINAL; headerSeg: SegmentDefs.FileSegmentHandle; DeleteHeader: PROCEDURE = BEGIN OPEN SegmentDefs; IF headerSeg # NIL THEN BEGIN Unlock[headerSeg]; DeleteFileSegment[headerSeg]; headerSeg ← NIL; END; END; bcd: POINTER TO BcdDefs.BCD; mtRoot: POINTER TO BcdDefs.MTRecord; sgBase: Table.Base; sSeg: BcdDefs.SGIndex; s: STRING ← [40]; StringDefs.AppendString[s, id]; StringDefs.AppendString[s, ".bcd."]; symbolSeg ← headerSeg ← NIL; BEGIN OPEN SegmentDefs; ENABLE BEGIN UNWIND => NULL; ANY => GO TO badFile END; bcdPages ← 1; headerSeg ← NewFileSegment[NewFile[s, Read, OldFileOnly], 1, bcdPages, Read]; DO SwapIn[headerSeg]; bcd ← FileSegmentAddress[headerSeg]; IF bcdPages = bcd.nPages THEN EXIT; bcdPages ← bcd.nPages; Unlock[headerSeg]; SwapOut[headerSeg]; MoveFileSegment[headerSeg, 1, bcdPages]; ENDLOOP; IF bcd.versionIdent # BcdDefs.VersionID OR bcd.nConfigs # 0 OR bcd.nModules # 1 THEN GO TO badFile; mtRoot ← LOOPHOLE[bcd + bcd.mtOffset]; sgBase ← LOOPHOLE[bcd + bcd.sgOffset]; sSeg ← mtRoot.sseg; IF sSeg = BcdDefs.SGNull OR sgBase[sSeg].pages = 0 OR sgBase[sSeg].file # BcdDefs.FTSelf THEN GO TO badFile; version ← bcd.version; symbolSeg ← NewFileSegment[ headerSeg.file, sgBase[sSeg].base, sgBase[sSeg].pages, Read]; symbolSeg.class ← other; DeleteHeader[]; EXITS badFile => BEGIN IF headerSeg # NIL THEN DeleteHeader[]; ERROR BadInterface[id]; END; END; RETURN END; FindItem: PUBLIC PROCEDURE [ symbolSeg: SegmentDefs.FileSegmentHandle, item: STRING] RETURNS [size, entry: CARDINAL] = BEGIN base: SymbolTable.Base; base ← SymbolTable.Acquire[SymbolTable.TableForSegment[symbolSeg]]; BEGIN OPEN Symbols, base; ss: StringDefs.SubStringDescriptor; hti: HTIndex; sei, itemSei: ISEIndex; ss ← [base:item, offset:0, length:item.length]; hti ← FindString[@ss]; IF hti = HTNull THEN GO TO fail; size ← 0; itemSei ← ISENull; FOR sei ← FirstCtxSe[stHandle.outerCtx], NextSe[sei] UNTIL sei = SENull DO IF LinkMode[sei] # manifest THEN BEGIN size ← size + 1; IF seb[sei].hash = hti THEN itemSei ← sei; END; ENDLOOP; IF itemSei = ISENull THEN GO TO fail; entry ← seb[itemSei].idValue; EXITS fail => ERROR BadInterface[item]; END; SymbolTable.Release[base]; RETURN END; END.