//
// Multiple name lookup procedure - P. Deutsch
// last edited April 15, 1976  11:16 PM, by CPT
//


// entry procedures
external [
	LookUpEntries
	]

// external procedures
external [
	Zero; MoveBlock
	Resets; Gets; Endofs
	]
  
manifest [

// ENTRY TYPES 
  
	FREETYPE = 0	//EMPTY ENTRY 
	NILTYPE = FREETYPE
	REALTYPE = 1	//REAL ENTRY
	LINKTYPE = 2	//LINK ENTRY
	] 
  
structure H[ type bit 6; esize bit 10 ]
manifest [ DIRPREAMBLESIZE=6; PRWDS=DIRPREAMBLESIZE ]

structure STRING[ length byte; char↑1,255 byte ]

manifest [ NOCASEMASK1=#377-#40; NOCASEMASK=not (#40*#400+#40) ]


let LookUpEntries(S, NAMEVEC, PRVEC, CNT, FILESONLY) = valof 
  
//  Look up a collection of names in a directory.
//  S is the directory (a disk stream), which get reset.
//  NAMEVEC is a vector of CNT strings.
//  PRVEC is a vector of 6*CNT words into which the directory
//    entries (minus the name) are read.
//  If FILESONLY, only looks at REALTYPE entries.

//  Returns number of names not found (hopefully 0).
//  Those names will have 0 in their PRVEC entries.
  
[LUE	let NAME = vec 128	// Scratch for name
	let PR = vec DIRPREAMBLESIZE	// Scratch for preamble
	let NOTFOUND = CNT	// Number of names not found yet
	Zero(PRVEC,  PRWDS*CNT)	// Clear FID's

Resets(S) 
until Endofs(S) do 
	[MAINLOOP
	let descript = Gets(S) 
	let typ = descript<<H.type
	if (FILESONLY? typ ne REALTYPE, typ eq FREETYPE) then 
	 [ let P = descript<<H.esize-1
	   if P gr 0 then  for i = 1 to P do Gets(S)
	   loop
	 ]
  
	PR!0 = descript
	for i = 1 to DIRPREAMBLESIZE-1 do PR!i = Gets(S)

	NAME!0 = Gets(S)	// First word of name
	let LEN = NAME>>STRING.length
	for i = 1 to LEN rshift 1 do NAME!i = Gets(S) & NOCASEMASK
	NAME!0 = NAME!0 & NOCASEMASK1
	let PRPTR = PRVEC-PRWDS
	for I = 0 to CNT-1 do	// Loop through names
	 [ PRPTR = PRPTR+PRWDS
	   if @PRPTR ne 0 then  loop	// Already found
	   let TP = NAMEVEC!I
	   let TLEN = TP>>STRING.length
	   if (LEN-TLEN) rshift 1 ne 0 then  loop
	   for J = 1 to TLEN do
	      if NAME>>STRING.char↑J ne (TP>>STRING.char↑J & NOCASEMASK1) then  goto NOTEQ
		// If LEN ne TLEN, the extra character must be
		// a final ".", so the comparison is successful
	   MoveBlock(PRPTR, PR, PRWDS)
	   NOTFOUND = NOTFOUND-1
	   if NOTFOUND eq 0 then resultis 0	// All found, quit
	   break
NOTEQ:	 ]
	]MAINLOOP

resultis NOTFOUND

]LUE