A2osX/SHARED/X.FILEENUM.S.txt

686 lines
12 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
.LIST OFF
*--------------------------------------
X.MAX.RECURSE .EQ 8
*--------------------------------------
* Uses: (pData)
* Index .BS 1
* hDIRs .BS X.MAX.RECURSE+1
* hDIRENTs .BS X.MAX.RECURSE+1
* oDIRENTs .BS X.MAX.RECURSE*2
* STATBUF .BS S.STAT
* hSrcBasePath .BS 1
* hDstBasePath .BS 1 (optional)
* hFilter .BS 1
* hExclude .BS 1
*--------------------------------------
* Compare a ZPFileName against hFilter (e.g. '*test?.*')
* CC : match
* CS : no match
*--------------------------------------
FilterMatch >LDA.G index
dec
bne FilterMatch.CLCRTS in a subdir, match everything
clc
.HS B0 BCS
ExcludeMatch sec
php
lda #hFilter
adc #0
tay
lda (pData),y
plp
tax
beq FilterMatch.RTS No filter....exit with passed carry
>SYSCALL GetMemPtr
>STYA ZPPtr2
ldy #S.STAT.FSID
lda (ZPFileStat),y if 0, Regular ProDOS....
pha save FSID for comapring later
bne .10
>LDYA ZPPtr2 ... so CI compare
>SYSCALL StrUpr
.10 plx get back FSID
lda (ZPPtr2) Get first pattern byte
beq .8 Match always if empty
ldy #0
bra .2
.1 jsr FilterMatch.NextPtr2 get next pattern char
beq .41 end of pattern...
.2 cmp #'*'
beq .5
.3 lda (ZPFileName),y we must match ? or regular char, check if at end of string
beq .9 no char left, exit with error
lda (ZPPtr2) get back pattern char
cmp #'?'
beq .4 no need to compare, any char will match
jsr FilterMatch.CmpPtr2CharPtr1Y Regular Char, compare with string at Y
bne .9 no match, exit
.4 iny advance to next char to compare
bra .1 continue if remaining char in pattern
.41 lda (ZPFileName),y end of pattern, but end of string ?
beq .8 yes, string matched entirely
* no, remaining char in string, no match
.9 sec
rts
.5 jsr FilterMatch.NextPtr2 we have '*', last char of pattern ?
beq .8 yes, match everything, including empty string
cmp #'*' another '*' ?
beq .5 yes, '**' = '*', go next char
cmp #'?' '*?' ? we must match a least one char
beq .3
.7 lda (ZPFileName),y we need at least one remaining char in string, check if at end of string
beq .9 no chance to match ? or regular char
iny
jsr FilterMatch.CmpPtr2CharPtr1Y compare with char in string
bne .7 not equal to next non wildcard in pattern
iny
bra .1 go check remaining char in pattern...
.8
FilterMatch.CLCRTS
clc
FilterMatch.RTS
rts
*--------------------------------------
FilterMatch.CmpPtr2CharPtr1Y
phx
plx
bne .2 Foreign FS or ProDOS.FX : CS compare
lda (ZPFileName),y
cmp #'a'
bcc .1
cmp #'z'+1
bcs .1
eor #$20
.1 cmp (ZPPtr2)
rts
.2 lda (ZPPtr2)
cmp (ZPFileName),y
rts
*--------------------------------------
FilterMatch.NextPtr2
inc ZPPtr2 Make PTR2 advance to next char
bne .1
inc ZPPtr2+1
.1 lda (ZPPtr2)
rts
*--------------------------------------
InitSrcDirYA >PUSHYA
>PUSHWZ Allocate
>SYSCALL RealPath
bcs FilterMatch.RTS
>STYA ZPPtr1
txa
>STA.G hFullPath
ldy #1
lda (ZPPtr1),y
beq .5 we have '/'
>PUSHW ZPPtr1
>PUSHEA.G STATBUF
>SYSCALL Stat
bcs .1 File/DIR does not exists, go extract pattern
.DO X.ENTER.SUBDIR=1
>LDA.G STATBUF+S.STAT.MODE+1
and #$F0
cmp /S.STAT.MODE.DIR
bne .4 TYPE not a DIR, extract....
bra .5 TYPE=DIR, do not extract pattern
.ELSE
bra .4
.FIN
.1 cmp #MLI.E.INVPATH
beq .11
jmp .9
.11 jsr GetPtr1Len TYPE is not DIR, check if wc
dey
ldx #0 Init Wildcard count
.2 lda (ZPPtr1),y search backward for a /
cmp #'/'
beq .3
cmp #'?' Test if some wildcard chars....
beq .21
cmp #'*'
bne .22
.21 inx inc wildcard count
.22 dey
bne .2
.3 txa
beq .90 no wc, file not found....
.4 jsr GetPtr1Len Search end of string.....
lda #'/'
.42 dey
cmp (ZPPtr1),y Search backward /
bne .42
tya
sec +1 to skip '/'
adc ZPPtr1
sta ZPPtr2
tay
lda ZPPtr1+1
adc #0
sta ZPPtr2+1
>SYSCALL StrDup
bcs .9
txa
>STA.G hFilter
lda #0
sta (ZPPtr2) cut path at last '/' to remove wildcards
.5 >LDYAI 256
>SYSCALL GetMem Get a 256 buffer to store BasePath
bcs .9
>STYA ZPPtr2
txa
>STA.G hSrcBasePath
jsr StrcpyPtr1ptr2
dey
lda #'/'
cmp (ZPPtr2),y
beq .7
iny
sta (ZPPtr2),y
iny
lda #0
sta (ZPPtr2),y
.7 >LDYA ZPPtr2
>SYSCALL OpenDir
bcs .9
ldy #hDIRs
sta (pData),y set hDIRs[0] = Src Hdir
ldy #index
lda #1
sta (pData),y index=hDIRs[0]
jsr .9 Cleanup
clc
rts
.90 lda #MLI.E.FNOTFND
.9 pha
>LDA.G hFullPath
>SYSCALL FreeMem
pla
sec
InitSrcDirYA.RTS
rts
*--------------------------------------
ResetSrcDir jsr GethDIR
>SYSCALL CloseDir
>LDA.G hSrcBasePath
>SYSCALL GetMemPtr
>SYSCALL OpenDir
bcs .9
pha
>LDA.G index
clc
adc #hDIRs-1
tay
pla
sta (pData),y
* clc
.9 rts
*--------------------------------------
.DO X.COPY.TO.DEST=1
InitDstDirYA >PUSHYA
>PUSHWZ Allocate
>SYSCALL RealPath
bcs InitSrcDirYA.RTS
>STYA ZPPtr1
txa
>STA.G hFullPath
>PUSHW ZPPtr1
>PUSHEA.G STATBUF
>SYSCALL Stat
bcs .1 File/DIR does not exists, go extract DstFileName
>LDA.G STATBUF+S.STAT.MODE+1
and #$F0
cmp /S.STAT.MODE.DIR
beq .5 Dst is a directory...no destfilename
.1 jsr GetPtr1Len Search end of string.....
lda #'/'
.2 dey
cmp (ZPPtr1),y Search backward /
bne .2
tya
sec +1 to skip '/'
adc ZPPtr1
sta ZPPtr2
tay
lda ZPPtr1+1
adc #0
sta ZPPtr2+1
>SYSCALL StrDup
bcs .9
txa
>STA.G hDstFileName
lda #0
sta (ZPPtr2)
.5 >LDYAI 256
>SYSCALL GetMem Get a 256 buffer to store DstBasePath
bcs .9
>STYA ZPPtr2
txa
>STA.G hDstBasePath
jsr StrcpyPtr1ptr2
dey
lda #'/'
cmp (ZPPtr2),y
beq .7
iny
sta (ZPPtr2),y
iny
lda #0
sta (ZPPtr2),y
.7 jsr .9 Cleanup
clc
rts
.9 pha
>LDA.G hFullPath
>SYSCALL FreeMem
pla
sec
rts
.FIN
*--------------------------------------
GetNextEntry jsr GetEntry
bcs .9
jsr GetFilenameLen Save actual file len for setting up
pha new offset later
lda ZPFileStat
clc
adc #S.STAT
sta ZPFileName
lda ZPFileStat+1
adc /S.STAT
sta ZPFileName+1 Make nDIRENTs[i] point to next DIRENT
jsr GetFilenameLen are we at end of this buffer ?
beq .1 yes, go read next one ...
jsr SetFileStatPtr
jsr GetoDIRENT
pla Get back previous file len
sec
adc (pData),y
sta (pData),y
iny
lda #0
adc (pData),y
sta (pData),y
dey
lda #S.STAT
clc
adc (pData),y
sta (pData),y
iny
lda /S.STAT
adc (pData),y
sta (pData),y
clc
rts
.1 pla
jsr GetEntry.ReadDir
bcs .9
jsr GetFilenameLen
beq .99
jsr SetFileStatPtr
clc
.9 rts
.99 sec
rts
*--------------------------------------
GetEntry jsr GethDIRENT
bne .1 we have a buffer to scan
jsr GetEntry.ReadDir First run, get first block
bcs .9 ZPFileName = start of buffer
lda (ZPFileName) Empty !!!
bne .8
sec
rts
.1 >SYSCALL GetMemPtr
>STYA ZPFileName
jsr GetoDIRENT
lda ZPFileName
clc
adc (pData),y
sta ZPFileName
iny
lda ZPFileName+1
adc (pData),y
sta ZPFileName+1 ZPFileName=ZPFileName+oDIRENT
.8 jsr GetFilenameLen
jsr SetFileStatPtr
clc
.9 rts
*--------------------------------------
GetEntry.ReadDir
jsr GethDIRENT
beq .1
pha
lda #0
sta (pData),y reset hDIRENT
pla
>SYSCALL FreeMem discard previous hDIRENT
.1 jsr GethDIR
>SYSCALL ReadDir
bcs .9
>STYA ZPFileName
ldy #index
lda (pData),y
clc
adc #hDIRENTs-1
tay
txa get hDIRENT in A
sta (pData),y
jsr GetoDIRENT
lda #0 and reset offset for this buffer
sta (pData),y
iny
sta (pData),y
clc
.9 rts
*--------------------------------------
EnterSubDirYA >STYA ZPPtr2 save SUBDIR for StrCat
>LDA.G index
cmp #X.MAX.RECURSE
beq .9
ldy #hSrcBasePath
jsr EnterSubDirY
>LDYA ZPPtr1
>SYSCALL OpenDir
bcs .9
pha
>INC.G index
tax
* clc from BCS
adc #hDIRs-1
tay
pla
sta (pData),y
txa make sure hDIRENTs[i] is closed
adc #hDIRENTs-1
tay
lda #0
sta (pData),y
.DO X.COPY.TO.DEST=1
ldy #hDstBasePath
jsr EnterSubDirY
.FIN
clc
.9 rts
EnterSubDirY lda (pData),y
>SYSCALL GetMemPtr
>STYA ZPPtr1 save full path
jsr .1 Make sure ending with /
>PUSHW ZPPtr1
>PUSHW ZPPtr2
>SYSCALL StrCat
.1 jsr GetPtr1Len
dey
lda #'/'
cmp (ZPPtr1),y
beq .8
iny
sta (ZPPtr1),y
iny
lda #0
sta (ZPPtr1),y
.8 rts
*--------------------------------------
LeaveSubDir >LDA.G index
beq .7
jsr GethDIRENT.A
jsr LeaveSubDir.free
jsr GethDIR
beq .1
pha
lda #0
sta (pData),y
pla
>SYSCALL CloseDir
.1 >DEC.G index
bne .8
.7 >LDA.G hSrcBasePath
jsr LeaveSubDir.free
.DO X.COPY.TO.DEST=1
>LDA.G hDstBasePath
jsr LeaveSubDir.free
.FIN
sec
rts
.8 clc
rts
*--------------------------------------
LeaveSubDir.free
tax
beq .8
lda #0
sta (pData),y
txa
>SYSCALL FreeMem
.8 rts
*--------------------------------------
BasePath.. .DO X.COPY.TO.DEST=1
ldy #hDstBasePath
jsr BasePath..1
.FIN
ldy #hSrcBasePath
BasePath..1 lda (pData),y
>SYSCALL GetMemPtr
>STYA ZPPtr1 save full path
jsr GetPtr1Len get len
dey discard ending /
.2 dey
lda (ZPPtr1),y
cmp #'/'
bne .2
iny
lda #0
sta (ZPPtr1),y cut DIR2/ from /dir1/DIR2/
rts
*--------------------------------------
GetPtr1Len ldy #$ff
.1 iny
lda (ZPPtr1),y get len
bne .1
rts
*--------------------------------------
StrcpyPtr1ptr2 ldy #$ff
.1 iny
lda (ZPPtr1),y
sta (ZPPtr2),y
bne .1
rts
*--------------------------------------
GetFilenameLen ldy #$ff
.1 iny
lda (ZPFileName),y
bne .1
tya
rts
*--------------------------------------
SetFileStatPtr sec
adc ZPFileName
sta ZPFileStat
lda ZPFileName+1
adc #0
sta ZPFileStat+1
rts
*--------------------------------------
GethDIR >LDA.G index
clc
adc #hDIRs-1
tay
lda (pData),y
rts
*--------------------------------------
GethDIRENT >LDA.G index
GethDIRENT.A clc
adc #hDIRENTs-1
tay
lda (pData),y
rts
*--------------------------------------
GetoDIRENT >LDA.G index
asl
clc
adc #oDIRENTs-1
tay
rts
*--------------------------------------
MAN
SAVE usr/src/shared/x.fileenum.s
LOAD usr/src/bin/ls.s
ASM