TableSymbols.mesa
Copyright © 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
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 = {
public interface
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: CARDINALMIN[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};
}.