DIRECTORY Alloc: TYPE USING [Handle, Notifier, AddNotify, DropNotify, Top, Words], ConvertUnsafe: TYPE USING [SubString, SubStringToRope], Copier: TYPE USING [], FileParms: TYPE USING [ActualId, BindingProc, Ops, Name, nullActual, nullName], Rope: TYPE USING [Flatten, Length, ROPE], SymbolTable: TYPE USING [ Base, Handle, nullHandle, voidHandle, Acquire, Forget, Locked, Release], Symbols: TYPE USING [ Base, Name, MDRecord, MDIndex, FileIndex, nullName, CTXNull, IncludedCTXNull, OwnMdi, MDNull, nullFileIndex, mdType], SymbolOps: TYPE USING [EnterString, SubStringForName], SymbolPack: TYPE USING [mdLimit, stHandle], SymbolSegment: TYPE USING [VersionID], TimeStamp: TYPE USING [Stamp]; FilePack: PROGRAM IMPORTS Alloc, ConvertUnsafe, Rope, SymbolTable, SymbolOps, own: SymbolPack EXPORTS Copier = { OPEN Symbols; table: Alloc.Handle _ NIL; mdb: Symbols.Base; -- module directory base FilePackNotify: Alloc.Notifier = {mdb _ base[mdType]}; VersionStamp: TYPE = TimeStamp.Stamp; FileProblem: PUBLIC SIGNAL [Name] RETURNS [BOOL] = CODE; FileVersion: PUBLIC SIGNAL [Name] RETURNS [BOOL] = CODE; FileVersionMix: PUBLIC SIGNAL [Name] = CODE; AnyVersion: VersionStamp = [net:0, host:0, time:0]; EnterFile: PUBLIC PROC [formalId, typeId: Name, defaultFile: Rope.ROPE] RETURNS [mdi: MDIndex _ MDNull] = { BindItem: FileParms.BindingProc = { IF actual # FileParms.nullActual THEN mdi _ FindMdEntry[typeId, actual.version, EnterRope[actual.locator]] ELSE [] _ SIGNAL FileProblem[formalId]}; -- need better error message fd, td: FileParms.Name; fd _ ConvertUnsafe.SubStringToRope[SymbolOps.SubStringForName[formalId]]; td _ ConvertUnsafe.SubStringToRope[SymbolOps.SubStringForName[typeId]]; fileParms.Binding[fd, td, defaultFile, BindItem]; RETURN}; FindMdEntry: PUBLIC PROC [id: Name, version: VersionStamp, file: Name] RETURNS [mdi: MDIndex] = { limit: MDIndex = table.Top[mdType]; duplicate: BOOL _ FALSE; FOR mdi _ MDIndex.FIRST, mdi + MDRecord.SIZE UNTIL mdi = limit DO IF mdb[mdi].moduleId = id THEN { IF mdb[mdi].stamp = version THEN RETURN; duplicate _ TRUE}; ENDLOOP; IF duplicate THEN SIGNAL FileVersionMix[id]; mdi _ table.Words[mdType, MDRecord.SIZE]; mdb[mdi] _ MDRecord[ stamp: version, moduleId: id, fileId: file, ctx: IncludedCTXNull, shared: FALSE, exported: FALSE, defaultImport: CTXNull, file: nullFileIndex]; own.mdLimit _ own.mdLimit + MDRecord.SIZE; RETURN}; GetSymbolTable: PUBLIC PROC [mdi: MDIndex] RETURNS [base: SymbolTable.Base] = { index: FileIndex; OpenSymbols[mdi]; index _ mdb[mdi].file; IF fileTable[index].file = nullHandle.file THEN base _ NIL ELSE { base _ SymbolTable.Acquire[fileTable[index]]; IF base.stHandle.versionIdent # SymbolSegment.VersionID THEN { SymbolTable.Release[base]; base _ NIL; IF SIGNAL FileProblem[mdb[mdi].fileId] THEN GO TO flush} ELSE IF base.stHandle.version # mdb[mdi].stamp THEN { SymbolTable.Release[base]; base _ NIL; IF SIGNAL FileProblem[mdb[mdi].fileId] THEN GO TO flush}; EXITS flush => { SymbolTable.Forget[fileTable[index] ! SymbolTable.Locked => {CONTINUE}]; fileParms.Release[fileTable[index]]; fileTable[index] _ voidHandle}}; RETURN}; FreeSymbolTable: PUBLIC PROC [base: SymbolTable.Base] = {SymbolTable.Release[base]}; EnterRope: PROC[rope: Rope.ROPE] RETURNS[Symbols.Name] = INLINE { ss: ConvertUnsafe.SubString; ss.base _ LOOPHOLE[rope.Flatten[]]; ss.offset _ 0; ss.length _ rope.Length[]; RETURN[SymbolOps.EnterString[ss]]}; FileHandle: TYPE = SymbolTable.Handle; FileTable: TYPE = RECORD[SEQUENCE length: NAT OF FileHandle]; nullHandle: FileHandle = SymbolTable.nullHandle; voidHandle: FileHandle = SymbolTable.voidHandle; fileTable: REF FileTable; lastFile: INTEGER; fileParms: FileParms.Ops; FileInit: PUBLIC PROC [ self: FileParms.ActualId, ownTable: Alloc.Handle, ops: FileParms.Ops] = { table _ ownTable; table.AddNotify[FilePackNotify]; IF FindMdEntry[nullName, self.version, EnterRope[self.locator]] # Symbols.OwnMdi THEN ERROR; fileParms _ ops; fileTable _ NIL; lastFile _ -1}; CreateFileTable: PUBLIC PROC [size: CARDINAL] = { n: CARDINAL = size+1; -- allow for ownMdi fileTable _ NEW[FileTable[n]]; FOR i: FileIndex IN [0..n) DO fileTable[i] _ nullHandle ENDLOOP; lastFile _ -1}; ExpandFileTable: PROC = { newTable: REF FileTable; i: FileIndex; size: CARDINAL = fileTable.length + 2; newTable _ NEW[FileTable[size]]; FOR i IN [0..fileTable.length) DO newTable[i] _ fileTable[i] ENDLOOP; FOR i IN [fileTable.length..size) DO newTable[i] _ nullHandle ENDLOOP; fileTable _ newTable}; FileReset: PUBLIC PROC = { FOR i: INTEGER IN [0..lastFile] DO IF fileTable[i] # nullHandle THEN fileParms.Release[fileTable[i]]; fileTable[i] _ nullHandle; ENDLOOP; table.DropNotify[FilePackNotify]; table _ NIL}; MdiToFile: PROC [mdi: MDIndex] RETURNS [FileIndex] = { IF mdb[mdi].file = nullFileIndex THEN { newFile: FileIndex = lastFile + 1; UNTIL newFile < fileTable.length DO ExpandFileTable[] ENDLOOP; fileTable[newFile] _ nullHandle; lastFile _ newFile; mdb[mdi].file _ newFile}; RETURN [mdb[mdi].file]}; OpenSymbols: PROC [mdi: MDIndex] = { index: FileIndex = MdiToFile[mdi]; IF fileTable[index] = nullHandle THEN { d1, d2: FileParms.Name; d1 _ ConvertUnsafe.SubStringToRope[SymbolOps.SubStringForName[mdb[mdi].moduleId]]; d2 _ ConvertUnsafe.SubStringToRope[SymbolOps.SubStringForName[mdb[mdi].fileId]]; fileTable[index] _ fileParms.Acquire[d1, [mdb[mdi].stamp, d2]]; IF fileTable[index] = nullHandle AND (SIGNAL FileProblem[mdb[mdi].moduleId]) THEN fileTable[index] _ voidHandle}}; TableForModule: PUBLIC PROC [mdi: MDIndex] RETURNS [SymbolTable.Handle] = { RETURN[fileTable[mdb[mdi].file]]}; MapSymbols: PUBLIC PROC [id: FileParms.ActualId] RETURNS [base: SymbolTable.Base] = { IF id = FileParms.nullActual THEN base _ NIL ELSE { handle: SymbolTable.Handle = fileParms.Acquire[FileParms.nullName, id]; IF handle.file = nullHandle.file THEN base _ NIL ELSE { base _ SymbolTable.Acquire[handle]; IF base.stHandle.versionIdent # SymbolSegment.VersionID THEN { fileParms.Release[handle]; SymbolTable.Release[base]; base _ NIL}}}; RETURN}; UnmapSymbols: PUBLIC PROC [SymbolTable.Base] = FreeSymbolTable; }. Hfile FilePack.mesa last modified by Satterthwaite, February 18, 1983 10:07 am Last Edited by: Maxwell, August 2, 1983 2:40 pm Last Edited by: Paul Rovner, September 6, 1983 11:54 pm tables defining the current symbol table included module accounting low-level file manipulation file table management file setup mdi bypass ʘJšœ™Jšœ:™:J™/Jšœ7™7J˜šÏk ˜ Jšœœœ7˜HJšœœœ˜7Jšœœœ˜Jšœ œœ:˜OJšœœœœ˜)šœ œœ˜J˜H—šœ œœ˜J˜)J˜K—Jšœ œœ!˜6Jšœ œœ˜+Jšœœœ ˜&Jšœ œœ ˜J˜—šœ ˜š˜J˜4J˜—Jšœ ˜Jšœ ˜ J˜Jšœœ˜J˜—Jšœ(™(˜JšœÏc˜,J˜J˜6J˜J˜—Jšœ™˜Jšœœ˜%J˜Jš œ œœœœœ˜8Jš œ œœœœœ˜8Jšœœœ œ˜,J˜J˜3J˜J˜šÏn œœœ,œ˜GJšœ˜#J˜˜#šœ˜%JšœD˜D—Jšœœž˜EJ˜—Jšœ˜J˜IJ˜GJ˜1Jšœ˜J˜—šŸ œœœ.˜FJšœ˜J˜#Jšœ œœ˜š œœœœ ˜Ašœœ˜ Jšœœœ˜(Jšœ œ˜—Jšœ˜—Jšœ œœ˜,Jšœ#œ˜)˜J˜J˜ J˜ J˜Jšœœ œ˜J˜J˜—Jšœ%œ˜*Jšœ˜J˜J˜—šŸœœœœ˜OJ˜J˜J˜Jšœ)œ˜:šœ˜J˜-šœ6œ˜>Jšœ#œ˜'Jš œœœœœ˜8—šœœ(œ˜5Jšœ#œ˜'Jš œœœœœ˜9—š˜˜ Jšœ=œ˜HJ˜$J˜ ———Jšœ˜J˜—JšŸœœœ8˜TJ˜š Ÿ œœ œœœ˜AJ˜Jšœ œ˜#J˜J˜Jšœ˜#—J˜J˜—Jšœ™˜Jšœ œ˜&Jš œ œœœ œœ ˜=J˜J˜0J˜0J˜Jšœ œ ˜Jšœ œ˜J˜J˜Jšœ™J˜J˜J˜šŸœœœ˜J˜J˜J˜J˜3šœN˜PJšœœ˜ —Jšœœ˜2J˜—šŸœœœœ˜1Jšœœ ž˜)Jšœ œ˜Jšœœœœ˜@J˜J˜—šŸœœ˜Jšœ œ ˜J˜ Jšœœ˜&Jšœ œ˜ Jšœœœœ˜EJšœœœœ˜FJ˜J˜—šŸ œœœ˜šœœœ˜"Jšœœ!˜BJ˜Jšœ˜—Jšœ*œ˜/J˜J˜—Jšœ ™ J˜šŸ œœœ˜6šœœ˜'J˜"Jšœœœ˜>J˜ J˜J˜—Jšœ˜J˜J˜—šŸ œœ˜$J˜"šœœ˜'Jšœ˜J˜RJ˜PJ˜?šœ˜ šœœ!˜0J˜ J˜J˜————šŸœœœœ˜KJšœ˜"J˜—Jšœ ™ ˜šŸ œœœœ˜UJšœœ˜,šœ˜J˜GJšœœ˜0šœ˜J˜#šœ6œ˜>Jšœ=œ˜D———Jšœ˜J˜—JšŸ œœœ&˜?J˜J˜J˜———…—ð W