DIRECTORY BcdDefs, CommandUtil USING [SetExtension], ConvertUnsafe USING [SubString], FileSegment USING [Pages, nullPages], FS USING [GetInfo, Open, OpenFile, Read], Rope USING [Flatten, ROPE, Text], RuntimeError USING [UNCAUGHT], Symbols, SymbolTable USING [Base, Handle, Acquire, Release], Table USING [Base], TableCommand, VM USING [AddressForPageNumber, Allocate, Free, Interval, nullInterval]; TableSymbols: PROGRAM IMPORTS CommandUtil, FS, Rope, RuntimeError, SymbolTable, VM EXPORTS TableCommand = { BadInterface: PUBLIC ERROR [Rope.ROPE] = CODE; FindInterface: PUBLIC PROC [id, file: Rope.ROPE] RETURNS [ version: BcdDefs.VersionStamp _ BcdDefs.NullVersion, pages: FileSegment.Pages _ FileSegment.nullPages] = { headerInterval: VM.Interval _ VM.nullInterval; DeleteHeader: PROC = { IF headerInterval # VM.nullInterval THEN { VM.Free[headerInterval]; headerInterval _ VM.nullInterval}}; bcd: BcdDefs.BcdBase; mtb: BcdDefs.MTHandle; sgb: Table.Base; sSeg: BcdDefs.SGIndex; s: Rope.ROPE _ CommandUtil.SetExtension[IF file = NIL THEN id ELSE file, "bcd"]; BEGIN ENABLE { UNWIND => {NULL}; RuntimeError.UNCAUGHT => {GO TO badFile}}; BcdBase: PROC [p: LONG POINTER] RETURNS [BcdDefs.Base] = INLINE { RETURN [LOOPHOLE[p, BcdDefs.Base]]}; file: FS.OpenFile _ FS.Open[s, $read]; bcdPages: CARDINAL _ MIN[8, CARDINAL[FS.GetInfo[file].pages]]; DO headerInterval _ VM.Allocate[bcdPages]; bcd _ VM.AddressForPageNumber[headerInterval.page]; FS.Read[file: file, from: 0, nPages: bcdPages, to: bcd]; IF bcd.versionIdent # BcdDefs.VersionID THEN GO TO badFile; IF bcdPages >= bcd.nPages THEN EXIT; bcdPages _ bcd.nPages; VM.Free[headerInterval]; headerInterval _ VM.nullInterval 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-1, 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: Rope.ROPE] RETURNS [found: BOOL] = { base: SymbolTable.Base _ SymbolTable.Acquire[symbols]; BEGIN OPEN Symbols, base; text: Rope.Text ~ id.Flatten[]; s: LONG STRING ~ LOOPHOLE[text]; ss: ConvertUnsafe.SubString _ [base: s, offset: 0, length: s.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: Rope.ROPE] RETURNS [size, entry: CARDINAL] = { base: SymbolTable.Base _ SymbolTable.Acquire[symbols]; BEGIN OPEN Symbols, base; itemSei: ISEIndex _ ISENull; text: Rope.Text ~ item.Flatten[]; s: LONG STRING ~ LOOPHOLE[text]; ss: ConvertUnsafe.SubString _ [base: s, offset: 0, length: s.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}; }.  TableSymbols.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Satterthwaite, November 2, 1982 10:37 am Maxwell, August 10, 1983 10:54 am Wyatt, March 29, 1984 6:05:39 pm PST Russ Atkinson (RRA) March 19, 1985 10:04:16 am PST public interface Κ™˜codešœ™Kšœ Οmœ1™šž˜Kšœžœ˜'Kšœžœ+˜3Kšžœ6˜8Kšžœ&žœžœžœ ˜;Kšžœžœžœ˜$K˜Kšžœ)žœ ˜:Kšžœ˜—Kš žœžœžœžœžœ ˜;K˜"K˜4šžœžœžœ ˜RKšžœžœžœ ˜—K˜K˜MK˜šž˜Kšœžœ˜3—Kšžœ˜K˜—Kšžœžœžœ˜3Kšžœ˜K˜—šŸœžœ(žœ˜:Kšžœ žœ˜˜6Kšž˜Kšžœ˜K˜Kšœžœžœžœ˜ KšœE˜EK˜EKšœžœ˜*Kšžœ˜—K˜Kšžœ˜K˜K˜—šŸœžœžœ*žœ˜DKšžœžœ˜#˜6Kšž˜Kšžœ˜K˜Kšœ!˜!Kšœžœžœžœ˜ KšœE˜EK˜Kšžœžœžœžœ˜ K˜ šžœ<žœž˜Ušžœžœ˜"Kšœžœžœ˜<—Kšžœ˜—Kšžœžœžœžœ˜%K˜šž˜Kšœžœ˜!—Kšžœ˜—K˜Kšžœ˜K˜—K˜K˜K˜———…— Tχ