-- file TableSymbols.mesa -- last edited by Satterthwaite, November 2, 1982 10:37 am DIRECTORY BcdDefs: TYPE, BcdOps: TYPE USING [BcdBase, MTHandle], File: TYPE USING [Capability], FileSegment: TYPE USING [Pages, nullPages], OSMiscOps: TYPE USING [FindFile], Space: TYPE USING [ Handle, nullHandle, virtualMemory, Create, LongPointer, Map, Delete], Strings: TYPE USING [String, SubStringDescriptor, AppendString], Symbols: TYPE, SymbolTable: TYPE USING [Base, Handle, Acquire, Release], Table: TYPE USING [Base], TableCommand: TYPE; TableSymbols: PROGRAM IMPORTS OSMiscOps, Space, Strings, SymbolTable EXPORTS TableCommand = { -- public interface BadInterface: PUBLIC ERROR [Strings.String] = CODE; FindInterface: PUBLIC PROC [id, file: Strings.String] RETURNS [ version: BcdDefs.VersionStamp _ BcdDefs.NullVersion, pages: FileSegment.Pages _ FileSegment.nullPages] = { headerSpace: Space.Handle _ Space.nullHandle; DeleteHeader: PROC = { IF headerSpace # Space.nullHandle THEN { Space.Delete[headerSpace]; headerSpace _ Space.nullHandle}}; bcd: BcdOps.BcdBase; mtb: BcdOps.MTHandle; sgb: Table.Base; sSeg: BcdDefs.SGIndex; s: STRING _ [40]; Strings.AppendString[s, IF file = NIL THEN id ELSE file]; FOR i: CARDINAL IN [0 .. s.length) DO IF s[i] = '. THEN EXIT; REPEAT FINISHED => Strings.AppendString[s, ".bcd"L]; ENDLOOP; BEGIN ENABLE { UNWIND => {NULL}; ANY => {GO TO badFile}}; BcdBase: PROC [p: LONG POINTER] RETURNS [BcdDefs.Base] = INLINE { RETURN [LOOPHOLE[p, BcdDefs.Base]]}; file: File.Capability; bcdPages: CARDINAL _ 8; file _ OSMiscOps.FindFile[s, read]; DO headerSpace _ Space.Create[size: bcdPages, parent: Space.virtualMemory]; headerSpace.Map[window: [file: file, base: 1]]; bcd _ headerSpace.LongPointer[]; IF bcd.versionIdent # BcdDefs.VersionID THEN GO TO badFile; IF bcdPages >= bcd.nPages THEN EXIT; bcdPages _ bcd.nPages; Space.Delete[headerSpace]; headerSpace _ Space.nullHandle ENDLOOP; IF bcd.nConfigs # 0 OR bcd.nModules # 1 THEN GO TO badFile; mtb _ BcdBase[bcd + bcd.mtOffset]; sgb _ BcdBase[bcd + bcd.sgOffset]; sSeg _ mtb.sseg; IF sSeg = BcdDefs.SGNull OR sgb[sSeg].pages = 0 OR sgb[sSeg].file # BcdDefs.FTSelf THEN GO TO badFile; version _ bcd.version; pages _ [file: file, span: [base: sgb[sSeg].base, pages: sgb[sSeg].pages]]; DeleteHeader[]; EXITS badFile => {DeleteHeader[]; ERROR BadInterface[s]}; END; IF ~CheckId[pages, id] THEN ERROR BadInterface[id]; RETURN}; CheckId: PROC [symbols: SymbolTable.Handle, id: Strings.String] RETURNS [found: BOOL] = { base: SymbolTable.Base _ SymbolTable.Acquire[symbols]; BEGIN OPEN Symbols, base; ss: Strings.SubStringDescriptor _ [base:id, offset:0, length:id.length]; sei: ISEIndex = SearchContext[FindString[@ss], stHandle.directoryCtx]; found _ sei # ISENull AND seb[sei].public; END; SymbolTable.Release[base]; RETURN}; FindItem: PUBLIC PROC [symbols: SymbolTable.Handle, item: Strings.String] RETURNS [size, entry: CARDINAL] = { base: SymbolTable.Base _ SymbolTable.Acquire[symbols]; BEGIN OPEN Symbols, base; itemSei: ISEIndex _ ISENull; ss: Strings.SubStringDescriptor _ [base:item, offset:0, length:item.length]; hti: HTIndex = FindString[@ss]; IF hti = HTNull THEN GO TO fail; size _ 0; FOR sei: ISEIndex _ FirstCtxSe[stHandle.outerCtx], NextSe[sei] UNTIL sei = ISENull DO IF LinkMode[sei] # manifest THEN { size _ size + 1; IF seb[sei].hash = hti THEN itemSei _ sei}; ENDLOOP; IF itemSei = ISENull THEN GO TO fail; entry _ seb[itemSei].idValue; EXITS fail => ERROR BadInterface[item]; END; SymbolTable.Release[base]; RETURN}; }. JLo