DIRECTORY Alloc USING [Handle, Notifier, AddNotify, DropNotify, Top, Units], ConvertUnsafe USING [SubString, SubStringToRope], FileParms USING [ActualId, BindingProc, Ops, Name, nullActual, nullName, SymbolSpace], MimosaCopier USING [], MimZones USING [RegisterForReset, tempZone], MobDefs USING [VersionStamp], Rope USING [Flatten, Length, ROPE], SymbolOps USING [EnterString, own, SubStringForName], Symbols USING [Base, CTXNull, FileIndex, IncludedCTXNull, MDIndex, MDFirst, MDNull, MDRecord, mdType, Name, nullFileIndex, nullName, OwnMdi], SymbolSegment USING [VersionID], SymbolTable USING [Base, Handle, AcquireSTB, ForgetSTB, LockedSTB, ReleaseSTB], SymbolTablePrivate USING [SymbolTableBaseRep]; MimFilesImpl: PROGRAM IMPORTS Alloc, ConvertUnsafe, MimZones, Rope, SymbolTable, SymbolOps EXPORTS MimosaCopier, SymbolTable = { OPEN Symbols; STB: TYPE = REF SymbolTableBaseRep; SymbolTableBaseRep: PUBLIC TYPE = SymbolTablePrivate.SymbolTableBaseRep; table: Alloc.Handle ¬ NIL; mdb: Symbols.Base; -- module directory base FilePackNotify: Alloc.Notifier = {mdb ¬ base[mdType]}; VersionStamp: TYPE = MobDefs.VersionStamp; FileProblem: PUBLIC SIGNAL [Name] RETURNS [BOOL] = CODE; FileVersion: PUBLIC SIGNAL [Name] RETURNS [BOOL] = CODE; FileVersionMix: PUBLIC SIGNAL [Name] = CODE; EnterFile: PUBLIC PROC [formalId, typeId: Name, defaultFile: Rope.ROPE] RETURNS [mdi: MDIndex ¬ MDNull] = { BindItem: FileParms.BindingProc = { IF actual # FileParms.nullActual THEN mdi ¬ FindMdEntry[formalId, typeId, actual.version, EnterRope[actual.locator]] ELSE [] ¬ SIGNAL FileProblem[formalId]; }; fd: FileParms.Name ¬ (SymbolOps.SubStringForName[ SymbolOps.own, formalId]).SubStringToRope; td: FileParms.Name ¬ (SymbolOps.SubStringForName[ SymbolOps.own, typeId]).SubStringToRope; fileParms.Binding[fd, td, defaultFile, BindItem]; }; FindMdEntry: PUBLIC PROC [formalId, typeId: Name, version: VersionStamp, file: Name] RETURNS [mdi: MDIndex] = { limit: MDIndex = table.Top[mdType]; duplicate: BOOL ¬ FALSE; FOR mdi ¬ MDFirst, mdi + MDRecord.SIZE UNTIL mdi = limit DO IF mdb[mdi].moduleId = typeId THEN { IF formalId # typeId THEN IF mdb[mdi].fileId # file THEN LOOP; IF mdb[mdi].stamp = version THEN RETURN; duplicate ¬ TRUE; }; ENDLOOP; IF duplicate THEN SIGNAL FileVersionMix[typeId]; mdi ¬ table.Units[mdType, MDRecord.SIZE]; mdb[mdi] ¬ MDRecord[ stamp: version, moduleId: typeId, fileId: file, ctx: IncludedCTXNull, shared: FALSE, exported: FALSE, defaultImport: CTXNull, file: nullFileIndex]; { stb: STB ¬ SymbolOps.own; stb.mdLimit ¬ stb.mdLimit + MDRecord.SIZE; }; }; GetSymbolTable: PUBLIC PROC [mdi: MDIndex] RETURNS [base: STB] = { index: FileIndex; OpenSymbols[mdi]; index ¬ mdb[mdi].file; IF fileTable[index].space = NIL THEN base ¬ NIL ELSE { base ¬ SymbolTable.AcquireSTB[FileHandleToSymbolHandle[fileTable[index]]]; SELECT TRUE FROM base.stHandle.versionIdent # SymbolSegment.VersionID => { SymbolTable.ReleaseSTB[base]; base ¬ NIL; IF SIGNAL FileProblem[mdb[mdi].fileId] THEN GO TO flush; }; base.stHandle.version # mdb[mdi].stamp => { SymbolTable.ReleaseSTB[base]; base ¬ NIL; IF SIGNAL FileProblem[mdb[mdi].fileId] THEN GO TO flush; }; ENDCASE; EXITS flush => { SymbolTable.ForgetSTB[FileHandleToSymbolHandle[fileTable[index]] ! SymbolTable.LockedSTB => {CONTINUE}]; fileParms.Release[fileTable[index].space]; fileTable[index] ¬ voidHandle; }; }; }; FreeSymbolTable: PUBLIC PROC [base: SymbolTable.Base] = { SymbolTable.ReleaseSTB[base]; }; EnterRope: PROC [rope: Rope.ROPE] RETURNS [Symbols.Name] = INLINE { flat: Rope.ROPE ¬ Rope.Flatten[rope]; ss: ConvertUnsafe.SubString ¬ [ base: LOOPHOLE[flat], offset: 0, length: Rope.Length[flat]]; RETURN [SymbolOps.EnterString[ss]]; }; FileHandle: TYPE = RECORD [space: FileParms.SymbolSpace, void: BOOL]; FileTable: TYPE = RECORD [SEQUENCE length: NAT OF FileHandle]; FileHandleToSymbolHandle: PROC [fh: FileHandle] RETURNS [SymbolTable.Handle] = INLINE { RETURN [[fh.space, FALSE]]; }; nullHandle: FileHandle = [NIL, FALSE]; voidHandle: FileHandle = [NIL, TRUE]; fileTable: REF FileTable ¬ NIL; lastFile: INTEGER; fileParms: FileParms.Ops ¬ [NIL, NIL, NIL, NIL]; FileInit: PUBLIC PROC [self: FileParms.ActualId, ownTable: Alloc.Handle, ops: FileParms.Ops] = { file: Symbols.Name = EnterRope[self.locator]; table ¬ ownTable; table.AddNotify[FilePackNotify]; IF FindMdEntry[nullName, nullName, self.version, file] # Symbols.OwnMdi THEN ERROR; fileParms ¬ ops; fileTable ¬ NIL; lastFile ¬ -1; }; CreateFileTable: PUBLIC PROC [size: CARDINAL] = { n: CARDINAL = size+1; -- allow for ownMdi fileTable ¬ MimZones.tempZone.NEW[FileTable[n]]; FOR i: FileIndex IN [0..n) DO fileTable[i] ¬ nullHandle ENDLOOP; lastFile ¬ -1; }; ExpandFileTable: PROC = { size: CARDINAL = fileTable.length + 2; newTable: REF FileTable ¬ MimZones.tempZone.NEW[FileTable[size]]; FOR i: FileIndex IN [0..fileTable.length) DO newTable[i] ¬ fileTable[i] ENDLOOP; FOR i: FileIndex IN [fileTable.length..size) DO newTable[i] ¬ nullHandle ENDLOOP; MimZones.tempZone.FREE[@fileTable]; fileTable ¬ newTable; }; FileReset: PUBLIC PROC = { IF fileTable # NIL THEN { FOR i: INTEGER IN [0..lastFile] DO IF fileTable[i] # nullHandle THEN fileParms.Release[fileTable[i].space]; fileTable[i] ¬ nullHandle; ENDLOOP; MimZones.tempZone.FREE[@fileTable]; }; IF table # NIL THEN {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: FileParms.Name ¬ ConvertUnsafe.SubStringToRope[ SymbolOps.SubStringForName[SymbolOps.own, mdb[mdi].moduleId]]; d2: FileParms.Name ¬ ConvertUnsafe.SubStringToRope[ SymbolOps.SubStringForName[SymbolOps.own, mdb[mdi].fileId]]; space: FileParms.SymbolSpace ¬ fileParms.Acquire[d1, [mdb[mdi].stamp, d2]]; IF space = NIL AND (SIGNAL FileProblem[mdb[mdi].moduleId]) THEN { fileTable[index] ¬ voidHandle; RETURN; }; fileTable[index] ¬ [space, FALSE]; }; }; TableForModule: PUBLIC PROC [mdi: MDIndex] RETURNS [SymbolTable.Handle] = { RETURN [FileHandleToSymbolHandle[fileTable[mdb[mdi].file]]]; }; MapSymbols: PUBLIC PROC [id: FileParms.ActualId] RETURNS [base: STB ¬ NIL] = { IF id # FileParms.nullActual THEN { space: FileParms.SymbolSpace = fileParms.Acquire[FileParms.nullName, id]; IF space # NIL THEN { handle: SymbolTable.Handle ¬ [space, FALSE]; base ¬ SymbolTable.AcquireSTB[handle]; IF base.stHandle.versionIdent # SymbolSegment.VersionID THEN { SymbolTable.ReleaseSTB[base]; fileParms.Release[space]; base ¬ NIL; }; }; }; }; UnmapSymbols: PUBLIC PROC [SymbolTable.Base] = FreeSymbolTable; MimZones.RegisterForReset[FileReset]; }. > MimFilesImpl.mesa Copyright Σ 1985, 1986, 1987, 1988, 1991 by Xerox Corporation. All rights reserved. Satterthwaite, June 10, 1986 9:58:21 am PDT Russ Atkinson (RRA) June 21, 1989 11:43:50 am PDT tables defining the current symbol table included module accounting Insist on different file names as well (a kludge, we should be storing the formalId as well). This takes care of entries like: Target: TYPE MachineParms USING [bitsPerLongWord, bitsPerWord] Don't let this be collected too soon! low-level file manipulation file table management file setup mdi bypass Κš•NewlineDelimiter –(cedarcode) style™headšœ™Icodešœ ΟeœI™TLšΟy+™+L™1—˜šΟk ˜ LšœŸœ7˜BLšœŸœ˜1Lšœ ŸœG˜VLšœ Ÿœ˜Lšœ Ÿœ˜,LšœŸœ˜LšœŸœŸœ˜#Lšœ Ÿœ&˜5LšœŸœ€˜LšœŸœ ˜ Lšœ Ÿœ>˜OLšœŸœ˜.——šΟn œŸ˜LšŸœ=˜DLšŸœ˜&LšŸœ ˜ L˜LšŸœŸœŸœ˜#LšœŸœŸœ)˜HL˜LšœŸœ˜L˜—L™(˜LšœΟc˜,L˜L˜6L˜—L™˜LšœŸœ˜*L˜Lš œ ŸœŸœŸœŸœŸœ˜8Lš œ ŸœŸœŸœŸœŸœ˜8šœŸœŸœ Ÿœ˜,L˜—š   œŸœŸœ,ŸœŸœ˜kš œ˜#šŸœ˜ LšŸœO˜SLšŸœŸœ˜'—L˜—L˜\L˜ZL˜1L˜L˜—š  œŸœŸœ=Ÿœ˜oL˜#Lšœ ŸœŸœ˜šŸœŸœŸœ Ÿ˜;šŸœŸœ˜$šŸœŸ˜šœ™LšΠorΡkor’£’™>—LšŸœŸœŸœ˜$—LšŸœŸœŸœ˜(Lšœ Ÿœ˜Lšœ˜—LšŸœ˜—LšŸœ ŸœŸœ˜0Lšœ#Ÿœ˜)˜L˜Lšœ˜L˜ L˜LšœŸœ Ÿœ˜L˜L˜—˜LšœŸœ˜Lšœ%Ÿœ˜*L˜—L˜L˜—š  œŸœŸœŸœŸœ˜BL˜L˜L˜šŸœŸ˜LšŸœŸ˜šŸœ˜LšœJ˜JšŸœŸœŸ˜šœ9˜9Lšœ˜LšœŸœ˜ Lš ŸœŸœŸœŸœŸœ˜8L˜—šœ+˜+Lšœ˜LšœŸœ˜ Lš ŸœŸœŸœŸœŸœ˜8L˜—LšŸœ˜—šŸ˜˜ šœ@˜@LšœŸœ˜'—L˜*Lšœ˜L˜——L˜——L˜L˜—š œŸœŸœ˜9Lšœ˜Lšœ˜—L˜š   œŸœ ŸœŸœŸœ˜Cšœ Ÿœ˜%L™%—˜LšœŸœ˜L˜ Lšœ˜—LšŸœ˜#L˜—L˜—L™˜Lšœ ŸœŸœ&Ÿœ˜ELš œ ŸœŸœŸœ ŸœŸœ ˜>L˜š œŸœŸœŸœ˜WLšŸœ Ÿœ˜L˜—L˜LšœŸœŸœ˜&LšœŸœŸœ˜%L˜Lšœ Ÿœ Ÿœ˜Lšœ Ÿœ˜L˜—™L˜Lš œŸœŸœŸœŸœ˜0L˜š œŸœŸœJ˜`Lšœ-˜-L˜L˜ LšŸœFŸœŸœ˜SLšœ˜Lšœ Ÿœ˜Lšœ˜L˜L˜—š œŸœŸœŸœ˜1LšœŸœ ‘˜)LšœŸœ˜0LšŸœŸœŸœŸœ˜@L˜L˜L˜—š œŸœ˜LšœŸœ˜&Lšœ ŸœŸœ˜ALšŸœŸœŸœŸœ˜PLšŸœŸœŸœŸœ˜QLšœŸœ ˜#L˜L˜L˜—š  œŸœŸœ˜šŸœ ŸœŸœ˜šŸœŸœŸœŸ˜"LšŸœŸœ'˜HL˜LšŸœ˜—LšœŸœ ˜#L˜—LšŸœ ŸœŸœ,Ÿœ˜DL˜L˜——™ L˜š  œŸœŸœ˜6šŸœŸœ˜'L˜"LšŸœŸœŸœ˜>L˜ L˜L˜L˜—LšŸœ˜L˜L˜—š  œŸœ˜$L˜"šŸœŸœ˜'Lšœr˜rLšœp˜pLšœK˜Kš Ÿœ ŸœŸœŸœ!Ÿœ˜ALšœ˜LšŸœ˜L˜—LšœŸœ˜"L˜—˜L˜——š œŸœŸœŸœ˜KLšŸœ6˜Lšœ˜L˜LšœŸœ˜ L˜—L˜—L˜—L˜L˜—š  œŸœŸœ&˜?L˜—L˜%—˜L˜——…—%ΰ