-- FastDir.mesa edited: Sandman July 15, 1980 4:18 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY AltoFileDefs USING [FP], DirectoryDefs USING [EnumerateDirectory], FastDirDefs USING [ Item, ItemHandle, HashVal, NilFileSwitches, FileSwitches, StringItem, FileType, LocalDir, Hash], String USING [AppendChar, EquivalentString], Storage USING [Node, CopyString]; FastDir: PROGRAM IMPORTS DirectoryDefs, FastDirDefs, String, Storage EXPORTS FastDirDefs = BEGIN OPEN FastDirDefs; StringHead: POINTER TO StringItem; ItemHead: ARRAY FileType OF ItemHandle; extensions: ARRAY FileType OF STRING = ["mesa", "bcd", "config", "symbols", "code", "image"]; fileSwitches: FileSwitches; NewString: PROCEDURE [s: STRING] RETURNS [STRING] = BEGIN p: POINTER TO StringItem; hash: HashVal = Hash[s]; FOR p _ StringHead, p.link UNTIL p = NIL DO IF p.hash = hash AND String.EquivalentString[s, p.s] THEN RETURN[p.s]; ENDLOOP; p _ Storage.Node[SIZE[Item]]; p.link _ StringHead; StringHead _ p; p.hash _ hash; RETURN[p.s _ Storage.CopyString[s]] END; EnterItem: PROCEDURE [s: STRING, t: FileType] RETURNS [p: ItemHandle] = INLINE BEGIN IF (p _ LookupItem[s, t]) = NIL THEN BEGIN p _ NewItem[s]; p.link _ ItemHead[t]; ItemHead[t] _ p; END; RETURN END; EnumerateList: PUBLIC PROCEDURE [ ft: FileType, proc: PROCEDURE [ItemHandle] RETURNS [BOOLEAN]] RETURNS [ih: ItemHandle] = BEGIN FOR ih _ ItemHead[ft], ih.link UNTIL ih = NIL OR proc[ih] DO ENDLOOP; END; GetExtension: PUBLIC PROCEDURE [ft: FileType] RETURNS [ext: STRING] = BEGIN RETURN[extensions[ft]] END; GetFiles: PROCEDURE [fp: POINTER TO AltoFileDefs.FP, fn: STRING] RETURNS [BOOLEAN] = BEGIN i: FileType; p: ItemHandle; ext: STRING _ [40]; StripExtension[fn, ext]; FOR i IN FileType DO IF fileSwitches[i] AND String.EquivalentString[ext, extensions[i]] THEN BEGIN p _ EnterItem[fn, i]; p.fp _ fp^; EXIT; END; ENDLOOP; RETURN[FALSE] END; Init: PROCEDURE = BEGIN i: FileType; StringHead _ NIL; fileSwitches _ NilFileSwitches; FOR i IN FileType DO ItemHead[i] _ NIL ENDLOOP; END; LookupItem: PUBLIC PROCEDURE [s: STRING, t: FileType] RETURNS [p: ItemHandle] = BEGIN hash: HashVal = Hash[s]; FOR p _ ItemHead[t], p.link UNTIL p = NIL DO IF p.hash = hash AND String.EquivalentString[s, p.name] THEN EXIT; ENDLOOP; RETURN END; NewItem: PROCEDURE [s: STRING] RETURNS [p: ItemHandle] = INLINE BEGIN p _ Storage.Node[SIZE[Item]]; p.hash _ Hash[s]; p.name _ NewString[s]; RETURN END; ScanDir: PUBLIC PROCEDURE [ files: FileSwitches, proc: PROCEDURE [ PROCEDURE [POINTER TO AltoFileDefs.FP, STRING] RETURNS [BOOLEAN]]] = BEGIN fileSwitches _ files; IF proc = LocalDir THEN DirectoryDefs.EnumerateDirectory[GetFiles] ELSE proc[GetFiles]; END; StripExtension: PUBLIC PROCEDURE [name, ext: STRING] = BEGIN i, j: CARDINAL; i _ (j _ name.length) - 1; IF name[i] = '. THEN i _ (j _ i) - 1; FOR i _ i, i - 1 UNTIL name[i] = '. DO IF name[i] = '! THEN j _ i; IF i = 0 THEN RETURN; ENDLOOP; name.length _ i; IF ext = NIL THEN RETURN; ext.length _ 0; UNTIL (i _ i + 1) = j DO String.AppendChar[ext, name[i]]; ENDLOOP; RETURN END; StripSwitches: PUBLIC PROCEDURE [name, switches: STRING] = BEGIN OPEN String; i, j: CARDINAL; FOR i _ 0, i + 1 UNTIL i = name.length DO IF name[i] = '/ THEN EXIT; REPEAT FINISHED => RETURN; ENDLOOP; IF switches = NIL THEN BEGIN name.length _ i; RETURN END; FOR j IN (i..name.length) DO AppendChar[switches, name[j]] ENDLOOP; name.length _ i; RETURN; END; Init[]; END.