// LookupEntries: // Last modified by December 21, 1979 1:57 PM by Lyle Ramshaw, // Patched things so that a name appearing more than once in // NameVec will be handled correctly. // last edited October 4, 1977 10:49 AM by P. Deutsch // Copyright Xerox Corporation 1979 // Look up a collection of names in a directory. // S is the directory (a disk stream), which gets reset. // NameVec is a vector of Cnt strings: // zeros in NameVec are ignored. // PrVec is a vector of lDV*Cnt words into which the directory // entries (without the name) are read. // If FilesOnly, only looks at dvTypeFile entries. // Buf, if supplied, is a buffer of size BufLen // Returns number of names not found (hopefully 0). // Those names will have 0 in the first word of their PrVec entries. get "AltoFileSys.d" external [ // Defined here LookupEntries // OS Resets; Gets; Endofs Dvec MoveBlock ReadBlock StripVersion Usc Zero ] manifest [ MinBufLen = lDV+lSTRING // Minimum buffer size MaxBufLen = #77777 // Maximum buffer size to avoid Usc ] let LookupEntries(S, NameVec, PrVec, Cnt, FilesOnly, Buf, BufLen; numargs Na) = valof [LUE test (Na ls 7) % (BufLen ls MinBufLen) ifso // Allocate a local buffer [ BufLen = MinBufLen Buf = BufLen Dvec(LookupEntries, lv Buf) ] ifnot if Usc(BufLen, MaxBufLen) gr 0 then BufLen = MaxBufLen let NotFound = 0 // Number of names not found yet for i = 0 to Cnt-1 do if NameVec!i ne 0 then NotFound = NotFound+1 Zero(PrVec, lDV*Cnt) // Clear DV's Resets(S) let endp = Buf // End of valid info in buffer until Endofs(S) do [FILL endp = ReadBlock(S, endp, Buf+BufLen-endp)+endp // Fill buffer let dv = Buf [ITEM let typ = dv>>DV.type let elen = dv>>DV.length unless (FilesOnly? typ ne dvTypeFile, typ eq dvTypeFree) do [LOOK let len1 = (elen gr MinBufLen? MinBufLen, elen) // Need to look at this much of the entry if (dv+len1-endp) gr 0 then // Whole entry isn't in buffer [ MoveBlock(Buf, dv, endp-dv) endp = endp+Buf-dv // Move end pointer down break // Let FILL read some more ] let Name = dv+lDV // Fabricate pointer to name in DV let vn=StripVersion(Name) //will append a "." if needed if vn eq 0 then vn=1 let Len = Name>>STRING.length let PrPtr = PrVec-lDV for I = 0 to Cnt-1 do // Loop through names [ PrPtr = PrPtr+lDV // Loop if already found higher version if PrPtr!0 gr vn then loop let tP = NameVec!I if tP eq 0 then loop // Skip this entry let tLen = tP>>STRING.length let d=tLen-Len if (d ne 0) & (d ne -1) then loop // -1 if user didn't give "." for J = 1 to tLen do if ((Name>>STRING.char^J xor tP>>STRING.char^J) & (not #40)) ne 0 then goto NOTEQ // If Len ne tLen, the extra character must be // a final ".", so the comparison is successful if PrPtr!0 eq 0 then NotFound = NotFound-1 MoveBlock(PrPtr, dv, lDV) PrPtr!0=vn //Version we found NOTEQ: ] ]LOOK // Skip over the entry we just processed test (dv+elen-endp) ls 0 ifso dv = dv+elen // Entire entry is in the buffer ifnot [ for i = 1 to elen+dv-endp do Gets(S) // Skip rest of entry endp = Buf // Used up the whole buffer break // Read some more ] ]ITEM repeat ]FILL resultis NotFound ]LUE