DIRECTORY Alloc USING [AddNotify, Bounds, DropNotify, Handle, Notifier, Top, Units], MobDefs USING [FTIndex, FTNull, FTRecord, fttype, NameRecord, NullVersion, sstype, sttype], MobFileDefs USING [], MobUtilDefs USING [FreeMob, NameForHti, MobHandle, ReadMob], CinderSysOps USING [Close, Open, OpenKind], ConvertUnsafe USING [SubString, SubStringToRope], IO USING [STREAM], Rope USING [Concat, FromProc, ROPE], MobSymbols USING [HTIndex, STIndex, STRecord], MobMapper USING [BadMobContents], Table USING [Base]; MobFileLookup: PROGRAM IMPORTS Alloc, ConvertUnsafe, MobMapper, MobUtilDefs, CinderSysOps, Rope EXPORTS MobFileDefs = { FileSequence: TYPE ~ RECORD [SEQUENCE length: NAT OF MobUtilDefs.MobHandle]; fileArray: REF FileSequence; table: Alloc.Handle; ftb, stb: Table.Base; Notifier: Alloc.Notifier ~ {ftb ¬ base[MobDefs.fttype]; stb ¬ base[MobDefs.sttype]}; BuildFileTable: PUBLIC PROC[ownTable: Alloc.Handle] ~ { OPEN MobSymbols; stLimit: STIndex; table ¬ ownTable; table.AddNotify[Notifier]; stLimit ¬ table.Top[MobDefs.sttype]; FOR sti: STIndex ¬ STIndex.FIRST, sti+STRecord.SIZE UNTIL sti=stLimit DO WITH s~~stb[sti] SELECT FROM external => WITH p~~s SELECT FROM file => IF p.fti = MobDefs.FTNull THEN p.fti ¬ AddFile[s.hti]; ENDCASE; ENDCASE; ENDLOOP; fileArray ¬ NEW[FileSequence[table.Bounds[MobDefs.fttype].size/MobDefs.FTRecord.SIZE]]; FOR i: NAT IN [0..fileArray.length) DO fileArray[i] ¬ NIL ENDLOOP}; AddFile: PROC[hti: MobSymbols.HTIndex] RETURNS[fti: MobDefs.FTIndex] ~ { ftLimit: MobDefs.FTIndex ~ table.Top[MobDefs.fttype]; name: MobDefs.NameRecord ~ MobUtilDefs.NameForHti[hti]; FOR fti ¬ MobDefs.FTIndex.FIRST, (fti + MobDefs.FTRecord.SIZE) UNTIL fti = ftLimit DO IF ftb[fti].name = name THEN RETURN ENDLOOP; fti ¬ table.Units[MobDefs.fttype, MobDefs.FTRecord.SIZE]; ftb[fti] ¬ [name~name, version~MobDefs.NullVersion]; RETURN}; EraseFileTable: PUBLIC PROC ~ { FOR i: NAT IN [0..fileArray.length) DO IF fileArray[i] # NIL THEN { MobUtilDefs.FreeMob[fileArray[i]]; fileArray[i] ¬ NIL}; ENDLOOP; FREE[@fileArray]; table.DropNotify[Notifier]; table ¬ NIL}; IndexForFti: PROC[fti: MobDefs.FTIndex] RETURNS[CARD] ~ INLINE { RETURN[LOOPHOLE[fti, CARD]/MobDefs.FTRecord.SIZE]}; MobFileErr: PUBLIC ERROR[err: Rope.ROPE] ~ CODE; UnknownFile: PUBLIC ERROR[fti: MobDefs.FTIndex] ~ CODE; CapabilityForFile: PUBLIC PROC[fti: MobDefs.FTIndex] RETURNS[mobh: MobUtilDefs.MobHandle] ~ { index: CARD ~ IndexForFti[fti]; ssd: ConvertUnsafe.SubString; IF index >= fileArray.length THEN ERROR UnknownFile[fti]; IF fileArray[index] = NIL THEN { ftb: Table.Base ¬ table.Bounds[MobDefs.fttype].base; name: MobDefs.NameRecord ~ ftb[fti].name; ssb: LONG STRING ¬ table.Bounds[MobDefs.sstype].base; mobStream: IO.STREAM; ssd ¬ [base~ssb, offset~name+1, length~MIN[ssb.text[name].ORD, 100]]; mobStream ¬ CinderSysOps.Open[NormalizeFileName[in~ssd], $read].stream; IF mobStream = NIL THEN ERROR UnknownFile[fti]; fileArray[index] ¬ MobUtilDefs.ReadMob[mobStream ! MobMapper.BadMobContents => GO TO Oops]; [] ¬ CinderSysOps.Close[mobStream]; IF fileArray[index] = NIL THEN ERROR UnknownFile[fti]; EXITS Oops => ERROR MobFileErr[err: Rope.Concat["MobMapper.BadMobContents raised for ", ConvertUnsafe.SubStringToRope[ssd]]]; }; RETURN [fileArray[index]]}; NormalizeFileName: PROC[in: ConvertUnsafe.SubString] RETURNS[Rope.ROPE] = { dot: BOOL ¬ FALSE; i: CARDINAL ¬ in.offset; EachChar: SAFE PROC RETURNS[c: CHAR] ~ TRUSTED { c ¬ in.base[i]; i ¬ i + 1; SELECT c FROM '. => dot ¬ TRUE; ENDCASE; RETURN}; name: Rope.ROPE = Rope.FromProc[MIN[in.length, CARDINAL[in.base.length - in.offset]], EachChar]; RETURN[IF ~dot THEN name.Concat[".mob"] ELSE name]}; }. ΐ MobFileLookup.mesa Copyright Σ 1985, 1989, 1991 by Xerox Corporation. All rights reserved. Satterthwaite on April 18, 1986 11:55:20 am PST Maxwell, August 11, 1983 2:39 pm Paul Rovner, September 8, 1983 5:33 pm Russ Atkinson, March 7, 1985 0:17:16 am PST Andy Litman March 21, 1988 11:47:53 pm PST JKF July 22, 1989 4:18:37 pm PDT Foote, July 1, 1991 1:40 pm PDT Willie-s, September 25, 1991 8:30 pm PDT IN ['A..'Z] => c _ Ascii.Lower[c]; Κ•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ Οeœ=™HKšΟy,Πky™/Kšž ™ Kšž&™&Kšœ(Οk™+Kšž'Ÿ™*Kš œ™ K™K™(—K˜š  ˜ Kšœ œ?˜JKšœ œN˜[Kšœ  œ˜Kšœ  œ+˜Kš œ˜——Kš œ˜—Kš œ˜—Kšœ  œA œ˜WKš  œ œ œ œ œ œ˜CK˜—š‘œ œ œ˜HK˜5K˜7š  œ œ œ œ ˜UKš œ œ œ œ˜-—Kšœ3 œ˜9K˜4Kš œ˜K˜—š‘œ œ œ˜š œ œ œ ˜&š œ œ œ˜Kšœ"˜"Kšœ œ˜—Kš œ˜—Kš œ ˜Kšœ˜Kšœ œ˜ K˜—š ‘ œ œ œ œ œ˜@Kš œ œ œ œ˜3K˜—Kš ‘ œ œ œ  œ œ˜0Kš‘ œ œ œ œ˜7K˜š‘œ œ œ œ!˜]Kšœ œ˜Kšœ ˜Kš œ œ œ˜9š œ œ œ˜ K˜4K˜)Kšœ œ œ%˜5Kšœ  œ œ˜Kšœ' œ œ˜EKšœG˜GKšœ œ˜/KšœO œ œ˜\Kšœ#˜#Kš œ œ œ œ˜6š ˜Kšœ œj˜w—Kšœ˜—Kš œ˜K˜—š‘œ œ œ œ˜KKšœ œ œ˜Kšœ œ ˜K˜š ‘œ œ œ œ œ œ˜0Kšœ˜Kšœ ˜ š œ ˜ Kš œ ™"Kšœ  œ˜Kš œ˜—Kš œ˜K˜—Kšœ  œ œ  œ)˜`Kš œ œ œ œ˜4K˜—K˜K˜——…—V,