;	*-------+---------------------------------------*
;	|Name	| FD (FinD)				|
;	|Version| 0.9	Comment:Com-piling		|
;	+-------+---------------------------------------+
;	|Lists all subdirs to current dir, or if a	|
;	|string is specified, CDs to a subdir starting	|
;	|with that string.				|
;	+-----------------------------------------------+
;	|	  Copyright (C) 1993 =MACROCOSM=	|
;	*-----------------------------------------------*
LibBits	=%00000001
MaxDirs	=501
NameSize=160
;if OpenLib/CloseLib is used, set LibBits!
;Bits 0-7=Dos,Int,Gfx,Con,Icon,MathF,MathT,MathI
;Presume that all macros destroy D0-D1/A0-A1, and preserves all other regs.
;Macros that use supplied work-registers preserve ALL registers.
;When calling a macro, A5 MUST BE INIT-ADR+32768 AND A6 MUST BE $DFF002!
;Most Macros CONTAIN GLOBAL LABELS, so use local only in-between Macro calls.
;Labels to define if relevant macros are used:
;Params (#Max longs)
;CurrHdl (current filehandle storage long)
;Buf (blk.b 81,0) for conversion & input routines
INCLUDE "CO:Symbols.S"
INCLUDE "CO:Makaron.S"
B:
	INIT
	bsr.w Caps			;Capitalize command line!
	OPENLIBS
	beq.w Quit
;	OPENF CurrHdl-R(a5),#WWName,#_OLD
	CALL DOS,DOutput		;for FIND list to file!
	move.l d0,CurrHdl-R(a5)
	beq.w Quit
	GETPARAMS Param-R(a5),#1
	move.l Params-R(a5),a0	
	cmp.b #"?",(a0)			;1st param="?" ?
	beq.w Usage
.NoSwp:	ALLOC #65*4+MaxDirs*NameSize,_Any		;FileInfo area!
	move.l d0,BufP-R(a5)
	beq.w ErrMem
	move.l d0,a1
	lea DirName-R(a5),a0
	bsr.w GetSubDirs
;...
	FREE BufP-R(a5),#65*4+MaxDirs*NameSize
Xit:;	CLOSEF CurrHdl-R(a5)
Quit:	CLOSELIBS
	EXIT
;	move.l SysRegs(PC),d0		;result from CD....?
	RTS
****************
Usage:	WRITELNA #TxtUS
	bra.w Xit
ErrMem:	WRITELN "Not enough memory, 80K needed."
	bra.w Xit
************ SUBS ************
Caps:					;CAPitalize string in a0.
	MOVEM.L D0-A6,-(SP)
	lea CapsTbl-R(a5),a1
	clr.w d0
	move.b (a0),d0
	beq.s .done
.loop:	move.b (a1,d0.w),(a0)+
	move.b (a0),d0
	bne.s .loop
.done:	MOVEM.L (SP)+,D0-A6		;a0 now points to 0, BUT RESTORED !!
	RTS
CapsTbl:
INCBIN "CO:DATA/CapsTbl"
****************
;;
CapsSearch:				;a0=CAPSed searchstring, a1=noncaps-cmp
	MOVEM.L A2-A3,-(SP)
	moveq #0,d0
	lea CapsTbl(PC),a2
.Retry:	move.l a0,a3
	move.b (a3)+,d1
.First:	move.b (a1)+,d0
	beq.s .NoMat
	cmp.b (a2,d0.w),d1
	bne.s .First
.contS:	move.b (a3)+,d1
	beq.s .Match
	move.b (a1)+,d0
	beq.s .NoMat
	cmp.b (a2,d0.w),d1
	beq.s .contS
.NoMat:	moveq #0,d0
	MOVEM.L (SP)+,A2-A3
	RTS
.Match:	move.l a1,d0
	MOVEM.L (SP)+,A2-A3		;d0=0 if correct, otherwise=a1-ptr
	RTS				;a0 is preserved!
****************
;;search from last slash forward, and show full paths of files!
GetSubDirs:				;a0=DirName,a1=DirDest
	MOVEM.L D0-A6,-(SP)
	move.l a0,a2			;copy regs out of DOS/MAKARON's reach
	move.l a1,a4
	lea 65*4(a4),a3			;a4=alloced FileInfo buffer^,a3=Dirn^
	move.l a3,d4
	add.l #(MaxDirs-1)*NameSize,d4	;d4=End-Of-Buffer minus 1 name!
	move.l a3,a2
.copy1:	move.b (a0)+,(a3)+		;COPY TOPDIR TO TOP OF DIRDEST
	bne.s .copy1
	lea NameSize(a2),a3		;a4=alloced FileInfo buffer^,a3=Dirn^
	moveq #0,d6			;#dirs searched
	moveq #0,d7			;#files searched
	move.l DOSbase-R(a5),a6		;BEWARE! SOME MAKARON RTNS WANTS A6 !!

.ScanLp:move.l a3,d5			;a3=temp. newdirdest, d5=perm scanend

.PrntLp:move.l a2,d1			;name of scan dir
	moveq #-2,d2			;type=lock-for-read(?)
	jsr DLock(a6)			;PUT LOCK ON DIR (AUTO-UNLOCK AT ERR!)
	move.l d0,FileLock-R(a5)
	beq.w GSCant
	move.l d0,d1
	move.l a4,d2
	jsr DExamine(a6)		;GET DIR INFO ("FindFirst but dir"...)
	tst.l d0
	beq.w GSCant2
.DirLp:	move.l FileLock-R(a5),d1
	move.l a4,d2
	jsr DExNext(a6)			;transfer file/dir data
	tst.l d0
	beq.w .Err			;end of files/dirs?
	btst #6,$bfe001
	bne.s .NoLMB
	btst #10,$dff016		;BOTH MBs = BREAK!
	beq.w GSBrk
.NoLMB:
	addq.l #1,d7			;inc #files
	lea 4(a4),a0			;name^-4 (inced below!)
	tst.l (a0)+			;dir or file?(A0 NOW POINTS AT NAME)
	bmi.s .File
* DIR
	move.l a3,d2			;save away a3 for Align later
	move.l a2,a1
	addq.l #1,d6			;inc #dirs
.copy2:	move.b (a1)+,(a3)+		;COPY PARENTDIR..(INCL ANY /)
	bne.s .copy2
	subq.w #1,a3			;overwrite ending zero
	tst.b (a2)
	beq.s .copy3
	move.b #"/",(a3)+		;..PLUS "/"..
.copy3:	move.b (a0)+,(a3)+		;..PLUS THIS DIR
	bne.s .copy3
	move.l a3,d3
	move.l a3,d1
	sub.l d2,d1
	cmp.w #NameSize-1,d1		;more than NameSize chars of dirname?
	bge.w GSErr2

	move.l Params-R(a5),d0		;Capsed file-parameter
	beq.s .NoSrch			;if string, search for it!
	move.l d0,a0			;capsed searchstring
	move.l d2,a1			;non-capsed file/dirname
	bsr.w CapsSearch		;found dir searchstring?
	tst.l d0
	beq.w .Cont			;eq=not found!

.NoSrch:MOVE.L D2,-(SP)			;otherwise display it!
	move.l CurrHdl-R(a5),d1		;handle
	move.b #"/",-1(a3)		;POKE a temp slash to indicate dir
	move.b #10,(a3)+		;POKE A LF
	move.l a3,d3
	sub.l d2,d3			;length (incl LF)
	jsr DWrite(a6)
	clr.b -2(a3)			;replace slash with ending zero.
	MOVE.L (SP)+,D2

.Cont:	move.l d2,a3
	lea NameSize(a3),a3		;DIRSAVE DONE!
	cmp.l a3,d4			;more than MaxDir-1 dirs?
	ble.w GSerr3
.NoDir:	bra.w .DirLp
* FILE
.File:	move.l a0,d2
	move.l Params-R(a5),d0		;Capsed file-parameter
	beq.s .FNoSrc			;if string, search for it!
	move.l d0,a0			;capsed searchstring
	move.l d2,a1			;non-capsed file/dirname
	bsr.w CapsSearch		;found dir searchstring?
	tst.l d0
	beq.w .DirLp			;eq=not found! (.FCONT !! )

.FNoSrc:				;otherwise display it!
	exg d2,a2
	move.l d2,a3
.FPlp:	tst.b (a3)+
	bne.s .FPlp
	subq.w #1,a3
	cmp.l a3,d2
	beq.s .FNoPar			;if no parent, don't display parent!
	move.b #"/",(a3)+
	move.l a3,d3
	sub.l d2,d3			;length (incl LF)
	move.l CurrHdl-R(a5),d1		;handle
	jsr DWrite(a6)
	clr.b -(a3)			;poke back a zero
.FNoPar:exg d2,a2
	move.l d2,a3
.Flp:	tst.b (a3)+
	bne.s .Flp
	move.b #10,-1(a3)		;POKE A LF
	move.l a3,d3
	sub.l d2,d3			;length (incl LF)
	move.l CurrHdl-R(a5),d1		;handle
	jsr DWrite(a6)
.FCont:	bra.w .DirLp

.Err:	jsr DIOErr(a6)			;dos error number-->d0
	cmp.l #$e8,d0
	bne.w GSErr			;REAL error!
	lea NameSize(a2),a2		;ALIGN;NEXT PARENTDIR,PLEASE!
	cmp.l a2,d5
	bgt.w .PrntLp
	cmp.l a2,a3			;no new dirs found? EXIT!
	bgt.w .ScanLp

.Done:	move.l CustBase-R(a5),a6
	lea Buf-R(a5),a2
	NUMDEC d6,a2
	WRITEA a0
	WRITE " dirs, "
	NUMDEC d7,a2
	WRITEA a0
	WRITELN " files scanned."
GSExit:	MOVEM.L (SP)+,D0-A6
	RTS
;;
GSCant2:move.l FileLock-R(a5),d1
	jsr DUnLock(a6)
GSCant:	move.l CustBase-R(a5),a6
	WRITELN "**Dir Locked or Dir Error"
	bra.w GSExit

GSBrk:	move.l FileLock-R(a5),d1
	jsr DUnLock(a6)
	move.l CustBase-R(a5),a6
	WRITELN "**Break"
	bra.w GSExit

GSErr:	move.l FileLock-R(a5),d1
	jsr DUnLock(a6)
	move.l CustBase-R(a5),a6
	WRITE "Dir Error: DOS error #$"
	lea Buf-R(a5),a2
	NUMHEX d0,a2
	WRITELNA a2
	bra.w GSExit

GSErr2:	move.l FileLock-R(a5),d1
	jsr DUnLock(a6)
	move.l CustBase-R(a5),a6
	WRITELN "Nerd Error #1: pathname > 160 chars long!"
	bra.w GSExit

GSErr3:	move.l FileLock-R(a5),d1
	jsr DUnLock(a6)
	move.l CustBase-R(a5),a6
	WRITELN "Nerd Error #2: More than 500 directories!"
	bra.w GSExit
************ VARS ************
BufP:	dc.l 0
CurrHdl:dc.l 0
FileLock:dc.l 0
Params:	blk.l 1,0
Buf:	blk.b 12,0
DirName:dc.b 0				;""=current dir!
WWName:	dc.b "*",0
FakeCLI:dc.b "map",10,0
TxtUS:
dc.b "FIND ",$a9," macrOcosm",10
dc.b "	Usage:	 Find [string]",10
dc.b "	(Lists all file and dir names that contain the search string.)",10
dc.b "	Example: Find dev",10
dc.b "	(Lists Devs/, Devs/mfm.device, Devs/IVS_SCSIPro.device etc.)",10
dc.b "	       ",$af,$af,$af,"	       ",$af,$af,$af
dc.b "			",$af,$af,$af,0
E:
