**************************************************************************
*
* The GNO Shell Project
*
* Developed by:
*   Jawaid Bazyar
*   Tim Meekins
*
* $Id: hash.asm,v 1.7 1998/12/21 23:57:06 tribby Exp $
*
**************************************************************************
*
* HASH.ASM
*   By Tim Meekins & Greg Thompson
*   Modified by Dave Tribby for GNO 2.0.6
*
* Command hashing routines
*
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
*              |     |                  |       |       |       |
*	^	^	^	^	^	^	
**************************************************************************
*
* Interfaces defined in this file:
*
* hash	jsr with params: (2:num, 4:name)
*
* dohash	subroutine (4:files)
*	return 4:table
*
* search	subroutine (4:file,4:table,4:paths)
*	return 4:full_path
*
* dispose_table subroutine (4:table)
*	 return
*
* free_files	subroutine (4:files)
*	return
* 
* dir_search	subroutine (4:dir,2:dirNum,4:files)
*	return
* 
* hashpath	jsl with no parameters
*	no returned value
*
* dispose_hash	jsr with no parameters
*	no returned value
*		                
**************************************************************************

	mcopy /obj/gno/bin/gsh/hash.mac

dummyhash	start		; ends up in .root
	end

	setcom 60

C1	gequ	11
C2	gequ	13
TAB_MULT	gequ	4

;
; Structure for filenames
;
;	struct filenode {
;		short      dirnum;
;		char       name[32];
;		filenode  *next;
;		};
fn_dirNum	gequ	0
fn_name	gequ	fn_dirNum+2
fn_next	gequ	fn_name+32
fn_size	gequ	fn_next+4

;
; Structure for hash table
;
;	struct tablenode {
;		short      dirnum;
;		char      *name[32];
;		};
tn_dirNum	gequ	0
tn_name	gequ	tn_dirNum+2
tn_size	gequ	tn_name+32

**************************************************************************
*
* Calculate hash value for a filename
*
**************************************************************************

hash	START

	using hashdata

space	equ	1
num	equ	space+2
name	equ	num+2
end	equ	name+4

	tsc
	phd
	tcd

	lda	num
	bne	hasher

	stz	h
	ldy	#0
loop	lda	[name],y
	and	#$FF
	beq	hasher
	sta	addit+1
	lda	h	;left shift 7
	xba
	and	#$FF00
	lsr	a
addit	adc	#0	;(cf=0)
	phy
	UDivide (@a,t_size),(@a,@a)
	sta	h
	ply
	iny
	bra	loop

hasher	lda	num	;num*num
	sta	tmp
	lda	#0
	ldx	#16
mulloop	asl	a
	asl	tmp
	bcc	nomul
	clc
	adc	num
nomul	dex
	bne	mulloop
		
	pha		;Acc * C2
	asl	a
	asl	a
	sec
	sbc	1,s
	asl	a
	asl	a
	adc	1,s
	sta	1,s

	lda	num	;num*C1 + (Acc*C2) + h
	asl	a
	adc	num
	asl	a
	asl	a
	adc	1,s
	adc	h
	sec
	sbc	num
	plx
	UDivide (@a,t_size),(@a,@y)

	lda	space
	sta	end-2
	pld
	tsc
	clc
	adc	#end-3
	tcs

	tya
	rts

h	ds	2
tmp	ds	2

	END

**************************************************************************
*
* dohash
*
**************************************************************************

dohash	START
	
	using hashdata

h	equ	1
temp	equ	h+2
qh	equ	temp+4
table	equ	qh+2
space	equ	table+4
files	equ	space+3
end	equ	files+4

;	 subroutine (4:files),space

	tsc
	sec
	sbc	#space-1
	tcs
	phd
	tcd

	lda	hash_numexe
	bne	mktsize

	stz	table
	stz	table+2
	jmp	done
;
; t_size = (TAB_MULT * numexe) - 1
;     [Shift since TAB_MULT is 4, change later if needed]
;
mktsize	asl	a
	asl	a
	dec	a
	sta	t_size
;
; table = (tablenode **)malloc(sizeof(tablenode *) * t_size);
;
	inc	a	;safety precaution
	asl	a
	asl	a
	pea	0
	pha
	~NEW
	sta	table
	stx	table+2
;
; for (i=0; i < t_size; ++i) table[i] = NULL;
;
	ldy	#0
	ldx	t_size
	tya
clrtbl	sta	[table],y
	iny
	iny
	sta	[table],y
	iny
	iny
	dex
	bne	clrtbl
;
; files = files->next
;
mainloop	ldy	#fn_next
	lda	[files],y
	tax
	ldy	#fn_next+2
	lda	[files],y
	sta	files+2
	stx	files
;
; while (files != NULL) {
;
	ora	files
	jeq	done
	stz	qh
;
; while (table[h = hash(files->name, qh))]) { ++qh; ++colls; }
;
hashloop	pei	(files+2)
	lda	files
	inc	a
	inc	a
	pha
	pei	(qh)
	jsr	hash
	asl	a
	asl	a
	sta	h
	tay
	lda	[table],y
	tax
	iny2
	ora	[table],y
	beq	gotit

; If it's the same name, skip the duplicate entry

	ldy	h	Calculate address
	clc		 of hash entry's
	lda	[table],y	  name field.
	adc	#tn_name
	tax
	iny2
	lda	[table],y
	adc	#0
	pha		High-order word of address.
	phx		Low-order word of address.
	pei	(files+2)
	lda	files
	inc	a
	inc	a
	pha
	jsr	cmpcstr
	beq	mainloop

	inc	qh
	bra	hashloop
;
; table[h] = (tablenode *)malloc(sizeof(tablenode))
;
gotit	ph4	#tn_size
	~NEW
	sta	temp
	stx	temp+2
	ldy	h
	sta	[table],y
	iny
	iny
	txa
	sta	[table],y
;
; table[h]->dirnum = files->dirNum
;
	lda	[files]
	sta	[temp]
;
; strcpy(table[h]->name, files->name);
;
	pei	(files+2)
	lda	files
	inc	a
	inc	a
	pha
	pei	(temp+2)
	lda	temp
	inc	a
	inc	a
	pha
	jsr	copycstr
	jmp	mainloop

done	anop
;	return 4:table

	ldx	table+2
	ldy	table

	lda	space
	sta	end-3
	lda	space+1
	sta	end-2
	pld
	tsc
	clc
	adc	#end-4
	tcs
	
	tya
	rtl

	END

**************************************************************************
*
* Search the hash table
*
**************************************************************************

search	START
	
ptr	equ	1
name_len	equ	ptr+4
full_path	equ	name_len+2
qh	equ	full_path+4
space	equ	qh+2
paths	equ	space+3
table	equ	paths+4
file	equ	table+4
end	equ	file+4

;	 subroutine (4:file,4:table,4:paths),space

	tsc
	sec
	sbc	#space-1
	tcs
	phd
	tcd

	stz	qh
	stz	full_path	Set result to NULL.
	stz	full_path+2

	lda	table	If hash table hasn't
	ora	table+2	 been allocated,
	jeq	done	  return null string.

	pei	(file+2)
	pei	(file)
	jsr	lowercstr
mainloop	pei	(file+2)	Get hash(qh,file)
	pei	(file)
	pei	(qh)
	jsr	hash
	asl	a	Multiply by 4
	asl	a
	tay		Use as index into table.
	lda	[table],y	ptr = table[hash(qh,file)]
	sta	ptr
	tax
	iny
	iny
	ora	[table],y	If == 0,
	jeq	done	 all done.

	lda	[table],y
	sta	ptr+2

	pei	(file+2)
	pei	(file)
	pha		;ptr+2
	inx		;ptr + #2
	inx
	phx
	jsr	cmpcstr	Compare filename against entry.
	beq	found
	inc	qh
	bra	mainloop

;
; Found an entry that matches the filename. Calculate full path.
;
found	lda	[ptr]
	asl	a
	asl	a
	adc	paths	;(cf=0)
	sta	ptr
	ldx	paths+2
	stx	ptr+2

	pei	(file+2)
	pei	(file)
	jsr	cstrlen	Get length of prog name.
	sta	name_len

	ldy	#2
	lda	[ptr],y
	pha
	lda	[ptr]
	pha
	jsr	cstrlen	Get length of path.
	pha
	sec
	adc	name_len	Add name length + 1 (carry bit).
	pea	0
	pha
	~NEW		Allocate memory,
	sta	full_path	 storing address at
	stx	full_path+2	  functional return value.

	ldy	#2
	lda	[ptr],y
	pha
	lda	[ptr]
	pha
	pei	(full_path+2)
	pei	(full_path)
	jsr	copycstr	Copy pathname into buffer.

	pla		;length of path
	pei	(file+2)
	pei	(file)
	pei	(full_path+2)
	clc
	adc	full_path
	pha
	jsr	copycstr	Put filename at end of pathname.

done	ldx	full_path+2	Load return value into Y- & X- regs
	ldy	full_path

; Adjust stack in preparation for return
	lda	space
	sta	end-3
	lda	space+1
	sta	end-2
	pld
	tsc
	clc
	adc	#end-4
	tcs

	tya		A- & X- regs contain ptr (or NULL)

	rtl

	END

**************************************************************************
*
* Dispose the hash table
*
**************************************************************************

dispose_table	START

	using hashdata

ptr	equ	0
count	equ	ptr+4
space	equ	count+2

	subroutine (4:table),space

	mv4	table,ptr
	mv2	t_size,count
loop	ldy	#2
	lda	[ptr],y
	pha
	lda	[ptr]
	pha
	jsl	nullfree
	add2	ptr,#4,ptr
	dec	count
	bne	loop

	pei	(table+2)
	pei	(table)
	jsl	nullfree

	return

	END

**************************************************************************
*
* Dispose the file table
*
**************************************************************************

free_files	START

space	equ	0

	subroutine (4:files),space

loop	ora2	files,files+2,@a
	beq	done
	ldy	#fn_next
	lda	[files],y
	tax
	ldy	#fn_next+2
	lda	[files],y
	pei	(files+2)
	pei	(files)
	stx	files
	sta	files+2
	jsl	nullfree
	bra	loop

done	return

	END

**************************************************************************
*
* Directory search
*
**************************************************************************

dir_search	START
	
	using	hashdata

temp2	equ	0
temp	equ	temp2+4
entry	equ	temp+4
numEntries	equ	entry+2
ptr	equ	numEntries+2
space	equ	ptr+4

	subroutine (4:dir,2:dirNum,4:files),space
;
; Open directory name passed as 1st parameter
;
	ld2	3,ORec
	pei	(dir+2)	Turn "dir" c-string into
	pei	(dir)	 a GS/OS string, allocated
	jsr	c2gsstr	  via ~NEW.
	sta	ORecPath
	stx	ORecPath+2
	phx		Put GS/OS string addr on stack
	pha		 so it can be deallocated.
	Open	ORec	Open that file.
	bcc	goodopen	If there was an error,
	jsl	nullfree	 Free the GS/OS string
	jmp	exit	  and exit.

goodopen	jsl	nullfree	Free the GS/OS string.

;
; Set up parameter block for GetDirEntry
;
	mv2	ORecRef,DRecRef	Copy the file ref num from open.
	stz	DRecBase	Zero the base and
	stz	DRecDisp	 displacement.
	GetDirEntry DRec	Make DirEntry call.

	mv2	DRecEntry,numEntries	Save number of entries.
	ld2	1,(DRecBase,DRecDisp)
	stz	entry		# processed entries = 0.
;
; Process each entry in the directory
;
loop	lda	entry	If number of processed entries
	cmp	numEntries	 equals the total number,
	jge	done	  we are all done.
;
; Get directory entry's information
;
	GetDirEntry DRec

; Check for filetype $B3: GS/OS Application (S16)
	if2	DRecFileType,eq,#$B3,goodfile

; Check for filetype $B5: GS/OS Shell Application (EXE)
	if2	@a,eq,#$B5,goodfile

; Check for filetype $B0, subtype $0006: Shell command file (EXEC)
	cmp	#$B0
	bne	nextfile
	lda	DRecAuxType
	cmp	#$06
	bne	nextfile
	lda	DRecAuxType+2
	bne	nextfile
;
; This directory entry points to an executable file.
; Included it in the file list.
;
goodfile	inc	hash_numexe	Bump the (global) # files.

	ldx	TempRBlen	Get length word from GS/OS string
	short	a
	stz	TempRBname,x	 Store terminating null byte.
	long	a

	ph4	#TempRBname
	jsr	lowercstr	Convert name to lower case.

	ph4	#TempRBname	Push src addr for copycstr.

	ldy	#fn_next	temp = files->next.
	lda	[files],y
	sta	temp
	ldy	#fn_next+2
	lda	[files],y
	sta	temp+2

	ph4	#fn_size	temp2 = new entry.
	~NEW
	sta	temp2
	stx	temp2+2

	ldy	#fn_next	files->next = temp2
	sta	[files],y
	ldy	#fn_next+2
	txa
	pha
	sta	[files],y

	lda	temp2
	clc
	adc	#fn_name
	pha
	jsr	copycstr	Copy string into entry.

	lda	dirNum	temp2->dirnum = dirNum
	sta	[temp2]

	ldy	#fn_next	temp2->next = temp
	lda	temp
	sta	[temp2],y
	ldy	#fn_next+2
	lda	temp+2
	sta	[temp2],y

nextfile	inc	entry	Bump entry number
	jmp	loop	 and stay in the loop.

;
; Done adding entries to the hash table from this directory
;
done	anop

	ld2	1,ORec	ORec.pCount = 1
	Close	ORec

exit	return


; Parameter block for GS/OS Open and Close calls
ORec	dc	i'3'	pCount (3 for Open, 1 for Close)
ORecRef	ds	2	refNum
ORecPath	ds	4	pathname (result buf)
ORecAccess	dc	i'1'	requested access = read

; Parameter block for GS/OS GetDirEntry call
DRec	dc	i'13'	pCount
DRecRef	ds	2	refNum
DRecFlag	ds	2	flags: extended/not
DRecBase	dc	i'0'	base: displacement is absolute entry #
DRecDisp	dc	i'0'	displacement: get tot # active entries
DRecName	dc	i4'TempResultBuf'	name: result buf
DRecEntry	ds	2	entryNum: entry # whose info is rtrned
DRecFileType	ds	2	fileType
DRecEOF	ds	4	eof: # bytes in data fork
DRecBlockCnt	ds	4	blockCount: # blocks in data fork
DRecCreate	ds	8	createDateTime
DRecMod	ds	8	modDateTime
DRecAccess	ds	2	access attribute
DRecAuxType	ds	4	auxType

; GS/OS result buffer for getting a directory entry's name
TempResultBuf	dc	i2'68'	Total length = 64 bytes + 4 for length
TempRBlen	ds	2	Value's length returned here
TempRBname	ds	64	Allow 64 bytes for returned name
	ds	1	Extra byte for null string termination

	END

**************************************************************************
*
* Hash the path variable
*
**************************************************************************

hashpath	START
	
	using hashdata
	using	vardata

len	equ	1
pathnum	equ	len+2
ptr	equ	pathnum+2
files	equ	ptr+4
pathptr	equ	files+4
qflag	equ	pathptr+4
qptr	equ	qflag+2
gsosbuf	equ	qptr+4
space	equ	gsosbuf+4
end	equ	space+3

;
; Allocate space on stack for direct page variables
;
	tsc
	sec
	sbc	#space-1
	tcs
	phd
	tcd

	lock	hashmutex
;
; Allocate special file node
;
	ph4	#fn_size
	~NEW
	sta	hash_files
	sta	files
	stx	hash_files+2
	stx	files+2

;
; Initialize counters and pointers
;
	lda	#0
	sta	hash_numexe
	sta	pathnum
	ldy	#fn_next
	sta	[files],y
	ldy	#fn_next+2
	sta	[files],y
	ldy	#fn_name
	sta	[files],y
	sta	[files]
;
; Get value of $PATH environment variable string
;
	ph4	#pathname
	jsl	getenv
	sta	gsosbuf	Save address of allocated buffer.
	stx	gsosbuf+2
	ora	gsosbuf+2	If null,
	bne	setptr
	ldx	#^nopatherr		print error message
	lda	#nopatherr
	jsr	errputs
	jmp	noprint		  and exit.

setptr	clc		Add 4 bytes to
	lda	gsosbuf	 direct page pointer
	adc	#4	  to get the addr of
	sta	pathptr	   beginning of text.
	lda	gsosbuf+2
	adc	#0
	sta	pathptr+2

;
; Begin parsing $PATH
;
loop	lda	[pathptr]
	and	#$FF
	jeq	pathdone
;
; parse next pathname
;
	stz	qflag	Clear quote flag for this path

	mv4	pathptr,ptr
	ldy	#0
despace	lda	[pathptr],y
	and	#$FF
	beq	gotspace0    
	if2	@a,eq,#' ',gotspace1
	if2	@a,eq,#009,gotspace1
	if2	@a,eq,#013,gotspace1
	if2	@a,eq,#'\',gotquote
	iny
	bra	despace

; Found "\"
gotquote	anop
	iny2
	ldx	qflag	If quote flag hasn't already been set,
	bne	despace
	sty	qflag	 set it to index of first "\" + 2.
	bra	despace

; Found null byte
gotspace0	tyx			Why put Y-reg in X???
	bra	gotspace3

; Found " ", tab, or creturn
gotspace1	tyx			Why put Y-reg in X???
	short a
	lda	#0
	sta	[pathptr],y
	long	a
gotspace2	iny
	lda	[pathptr],y
	and	#$FF
	if2	@a,eq,#' ',gotspace2
	if2	@a,eq,#009,gotspace2
	if2	@a,eq,#013,gotspace2

gotspace3	anop
	clc		Bump pathptr by
	tya		 the number of bytes
	adc	pathptr	  indicated in Y-reg.
	sta	pathptr
	lda	pathptr+2
	adc	#0
	sta	pathptr+2

	lda	pathnum
	cmp	#32*4
	bcc	numok
	ldx	#^toomanyerr
	lda	#toomanyerr
	jsr	errputs
	jmp	pathdone

;
; Convert c string to GS/OS string (allocating space for it)
;
numok	pei	(ptr+2)
	pei	(ptr)
	jsr	c2gsstr
	phx		Push allocated address onto
	pha		 stack for later deallocation.
	sta	EPinputPath	Save address in ExpandPath
	stx	EPinputPath+2	 parameter block.
;
; If any quoted characters were included, the "\" chars must be removed
;
	ldy	qflag	Get quote flag (index to "\" char).
	beq	xpandit	If no "\", go ahead with expansion.

	sta	qptr	Save EPinputPath pointer in
	stx	qptr+2	 direct page variable.
	lda	[qptr]	Store length + 2 (since we're indexing
	inc2	a	 from before length word) in qflag.
	sta	qflag
	tyx		X = index of 1st overwritten "\".
	short	a	Use 1-byte accumulator
;
; Copy characters toward front of string, removing "\" chars
;
chkloop2	lda	[qptr],y	Get next character.
	cmp	#'\'	If it's a quote,
	bne	storeit
	lda	[qptr]		Decrement length.
	dec	a
	sta	[qptr]
	iny			Skip over "\".
	lda	[qptr],y		Get character following.
storeit	phy		Push source index onto stack
	txy		 so destination index can be
	sta	[qptr],y	  used to store the character.
	ply		Restore the source index.
	inx		Bump destination and
	iny		 source index registers.
	cpy	qflag	If source index < length,
	bcc	chkloop2	 stay in copy loop.

	long	a	Restore long accumulator.

;
; Convert the input pathname into the corresponding full pathname with
; colons as separators. Use temp result buf this time, just to get length.
;
xpandit	anop
	ld4	TempResultBuf,EPoutputPath
	ExpandPath EPParm
;
; Allocate memory for ExpandPath GS/OS result string
;
	lda	TempRBlen	Get length of value.
	inc2	a	Add 4 bytes for result buf len words.
	inc2	a
	sta	len	Save result buf len.
	inc	a	Add 1 more for terminator.
	pea	0
	pha
	~NEW		Request the memory.
	sta	EPoutputPath	Store address in ReadVariable
	stx	EPoutputPath+2	 parameter block and
	sta	ptr	  direct page pointer.
	stx	ptr+2
	ora	ptr+2	If address == NULL,
	jeq	donext	  get next entry.

	lda	len	Store result buffer length
	sta	[ptr]	 at beginning of buf.

	ExpandPath EPParm	Call again, and get the name.
	bcc	epok

	ldx	#^eperrstr	Print error message:
	lda	#eperrstr	 "Invalid pathname syntax."
	jsr	errputs
donext	jsl	nullfree	 Free GS/OS string (pushed earlier).
	jmp	next	 Get the next one.

epok	anop
	jsl	nullfree	Free source string (addr on stack)

	ldy	#2
	lda	[ptr],y	Get length of text
	sta	len
	tay
	iny4		 and add four.
	short	a
	lda	#0	Store 0 at end of text so it
	sta	[ptr],y	 can act like a C string.
	long	a
;
; Move text in GS/OS result buffer to beginning of buffer
; (overwritting the two length words).
;
	clc		Source is result
	lda	ptr	 buffer plus
	adc	#4	  four bytes.
	tay
	lda	ptr+2
	adc	#0
	pha
	phy
	pei	(ptr+2)	Destination is first
	pei	(ptr)	 byte of buffer.
	jsr	copycstr

	lda	ptr
	ldy	pathnum
	sta	hash_paths,y	Store address of this
	lda	ptr+2	 path's address in the
	sta	hash_paths+2,y	  hash path table.

	ldy	len
	beq	bumppnum
	dey
	lda	[ptr],y	If last character
	and	#$FF	 of path name
	cmp	#':'	  isn't ":",
	beq	bumppnum
	iny
	lda	#':'		store ":\0"
	sta	[ptr],y		 at end of string.

bumppnum	anop
	add2	pathnum,#4,pathnum	 Bump path pointer.
next	jmp	loop	Stay in loop.

;
; The $PATH entries have been created. Now we need to search each of the
; directories for executable files and add them to the "files" list.
; The earliest versions of gsh added files to the list in the order that
; directories appeared in $PATH, which put the earliest directories' files
; at the end of the list. Check for existence of $OLDPATHMODE environment
; variable to see if the user wants this, or would rather have them hashed
; in the expected order.
;
pathdone	anop
	lda	varoldpmode
	beq	neworder

;
; Search directories and add executables to file list starting at the
; beginning of $PATH and working to the end.
;
	stz	pathnum	Start at beginning of path table.

nextpath1	ldy	pathnum	Get offset into hash table.
	cpy	#32*4
	bcs	filesdone
	lda	hash_paths,y	If address of this path
	ora	hash_paths+2,y	 has not been set,
	beq	filesdone	  all done.
	lda	hash_paths,y	Get address of this
	ldx	hash_paths+2,y	 path's address in the
	phx		  hash path table.
	pha
	tya		Directory number =
	lsr2	a	 offset / 4
	pha
	pei	(files+2)	Pointer to file list.
	pei	(files)
	jsl	dir_search	Add executables from this directory.
	add2	pathnum,#4,pathnum	 Bump path offset.
	bra	nextpath1

;
; Search directories and add executables to file list starting at end
; of $PATH and working back to the beginning. (Note: Loop begins at
; "neworder", but structuring the code this ways saves an instruction.)
;
nextpath2	dey4		Decrement path offset.
	sty	pathnum
	lda	hash_paths,y	Get address of this
	ldx	hash_paths+2,y	 path's address in the
	phx		  hash path table.
	pha
	tya		Directory number =
	lsr2	a	 offset / 4
	pha
	pei	(files+2)	Pointer to file list.
	pei	(files)
	jsl	dir_search	Add executables from this directory.
neworder	ldy	pathnum	Get offset into hash table.
	bne	nextpath2	When == 0, no more to do.


;
; Executable files in $PATH have been added to the list. Print
; number of files, then build the hash table.
;
filesdone	anop
	ph4	gsosbuf	Free memory allocated for
	jsl	nullfree	 $PATH string.

	lda	hash_print	If initialization isn't complete,
	beq	noprint	 don't print the # of files.

	Int2Dec (hash_numexe,#hashnum,#3,#0)
	ldx	#^hashmsg
	lda	#hashmsg
	jsr	puts

noprint	anop

;
; Create the hash table from the file list.
;
	ph4	hash_files
	jsl	dohash
	sta	hash_table
	stx	hash_table+2

	unlock hashmutex
	
	pld
	tsc
	clc
	adc	#end-4
	tcs

	rtl

hashmutex	key		Mutual exclusion key

pathname	gsstr	'path'

hashmsg	dc	c'hashed '
hashnum	dc	c'000 files',h'0d00'

; Parameter block for GS/OS call ExpandPath
EPParm	dc	i'2'	pCount = 2
EPinputPath	ds	4	ptr to inputPath (GS/OS string)
EPoutputPath	ds	4	ptr to outputPath (Result buffer)

; GS/OS result buffer for getting the full length of expanded name
TempResultBuf	dc	i2'5'	Only five bytes total.
TempRBlen	ds	2	Value's length returned here.
	ds	1	Only 1 byte for value.

eperrstr	dc	c'rehash: Invalid pathname syntax.',h'0d00'
toomanyerr	dc	c'rehash: Too many paths specified.',h'0d00'
nopatherr	dc	c'rehash: PATH string is not set.',h'0d00'

	END

**************************************************************************
*
* Dispose of hashing tables
*
**************************************************************************

dispose_hash	START

	using hashdata

	ora2	hash_table,hash_table+2,@a
	beq	done

	ldx	#32	32 different paths, maximum
	ldy	#0	Start looking at the first entry.

loop1	phx		Save path counter
	phy		 and index.
	lda	hash_paths+2,y	Put address for this
	pha		 path table entry on
	lda	hash_paths,y	  the stack.
	pha
	lda	#0	Zero out the table entry.
	sta	hash_paths+2,y
	sta	hash_paths,y
	jsl	nullfree	Free the entry's memory.
next1	ply		Restore path index
	plx		 and counter.
	iny4		Bump pointer to next address.
	dex		If more paths to process,
	bne	loop1	 stay in the loop.

	ph4	hash_files
	jsl	free_files
	stz	hash_files
	stz	hash_files+2

	ph4	hash_table
	jsl	dispose_table
	stz	hash_table
	stz	hash_table+2

done	rts

	END

**************************************************************************
*
* Hash data
*
**************************************************************************

hashdata	DATA

t_size	ds	2	t_size = (TAB_MULT * numexe) - 1

hash_paths	dc	32i4'0'	32 paths max for now.
hash_files	dc	i4'0'
hash_table	dc	i4'0'	Pointer to table (t_size entries)
hash_numexe	dc	i2'0'	Number of hashed executables
hash_print	dc	i2'0'	Print flag; 0 until init is complete

	END
