home *** CD-ROM | disk | FTP | other *** search
- ;******************************************************
- ; TPBM.ASM 5.07
- ; String handling routines
- ; Copyright (c) TurboPower Software 1987.
- ; Portions copyright (c) Sunny Hill Software 1985, 1986
- ; and used under license to TurboPower Software
- ; All rights reserved.
- ;******************************************************
-
- INCLUDE TPCOMMON.ASM
-
- ;****************************************************** Code
-
- CODE SEGMENT BYTE PUBLIC
-
- ASSUME CS:CODE
-
- PUBLIC BMMakeTable, BMSearch, BMSearchUC
-
- EXTRN UpCasePrim : FAR
-
- Upcase MACRO ;UpCase character in AL
- PUSH BX
- CALL UpCasePrim
- POP BX
- ENDM
-
- ;****************************************************** BMMakeTable
-
- ; procedure BMMakeTable(MatchString : string; var BT : BTable);
- ; Build Boyer-Moore link table
- ; BTable is array[0..255] of byte;
-
- MString EQU DWORD PTR SS:[BX+8]
- BTable EQU DWORD PTR SS:[BX+4]
-
- BMMakeTable PROC FAR
-
- StackFrame
- MOV DX,DS ;Save DS in DX
- CLD ;Go forward
-
- LDS SI,MString ;DS:SI => MatchString
- LES DI,BTable ;ES:DI => BY
- MOV BX,DI ;Save DI in BX
- LODSB ;AL = length(MatchString)
- MOV AH,AL ;Copy it to AH
- MOV CX,128 ;Number of words in BT
- REP STOSW ;Fill BT with length(MatchString)
- CMP AL,1 ;Is length(MatchString) <= 1?
- JBE MTDONE ;Yes, we're done
-
- MOV DI,BX ;Restore base of table from BX
- MOV BH,CH ;BH = 0
- MOV CL,AL ;CX = length(MatchString)
- DEC CX ;CX = length(MatchString)-1
-
- MTnext: LODSB ;AL = MatchString[i]
- MOV BL,AL ;BL = MatchString[i]
- MOV ES:[BX+DI],CL ;BTable[char] = length(MatchString)-i
- LOOP MTnext ;Repeat for all characters in MatchString
-
- MTDone: MOV DS,DX ;Restore DS from DX
- RET 8
-
- BMMakeTable ENDP
-
- ;****************************************************** BMSearch
-
- ; function BMSearch(var Buffer; BufLength : Word; BT : BTable; MatchString : string) : Word;
- ; Search Buffer for MatchString
- ; Return FFFF for failure
- ; Else return number of bytes searched to find MatchString
-
- MString EQU DWORD PTR [BP+6]
- BTable EQU DWORD PTR [BP+10]
- BufSize EQU WORD PTR [BP+14]
- Buffer EQU DWORD PTR [BP+16]
- BufOfs EQU WORD PTR [BP+16]
-
- BMSearch PROC FAR
-
- StackFrameBP
- PUSH DS ;Will wipe out DS
- PUSH BP ;Will use BP for temp storage later
-
- MOV CX,BufSize ;CX = Buffer size
- LES DI,Buffer ;ES:DI => Buffer
- LDS BX,BTable ;DS:BX => BTable
- MOV AX,DS ;Keep BTable segment in AX a moment
- LDS SI,MString ;DS:SI => MatchString
- MOV BP,AX ;Keep BTable segment in BP
-
- XOR AX,AX ;AX = 0
- MOV DX,AX ;DX = 0
- MOV DL,[SI] ;DL = length(MatchString)
- CMP DL,1 ;Check for trivial cases
- JA BMSinit ;Do Boyer-Moore if longer than one char
- JB BMSnotFound ;Fail for empty string
-
- MOV AL,[SI+1] ;AL = one and only char to find
- MOV BX,DI ;Save offset of Buffer
- CLD ;Forward
- REPNE SCASB ;Scan Buffer for AL
- JNE BMSnotFound ;Char wasn't found
- MOV AX,DI ;AX holds offset where char was found
- DEC AX ;Back up one
- SUB AX,BX ;Subtract base offset of Buffer
- JMP BMSdone ;We're done
-
- BMSinit:
- DEC DL ;DX = length(MatchString)-1
- ADD SI,DX ;DS:SI => MatchString[length(MatchString)-1]
- ADD CX,DI ;CX = offset of last char in buffer
- ADD DI,DX ;ES:DI => first position to search
- MOV DH,[SI+1] ;DH = MatchString[length(MatchString)]
- STD ;Go backwards
- JMP SHORT BMScomp ;Skip link table first time
-
- BMSnext:
- PUSH DS ;Save DS a moment
- MOV DS,BP ;Get segment of link table
- XLAT ;Get size of link at DS:[BX+AL]
- POP DS ;Restore DS
- ADD DI,AX ;Compute next place to search
-
- BMScomp:
- CMP DI,CX ;At end of buffer?
- JAE BMSnotFound ;Done if so
- MOV AL,ES:[DI] ;AL = next char to try
- CMP DH,AL ;Does it match the end of MatchString?
- JNE BMSnext ;If not same, go back and try again
-
- PUSH CX ;Save end of buffer position
- DEC DI ;Start comparing one character before
- MOV CL,DL ;Compare length(MatchString)-1 characters
- MOV CH,AH ;CH = 0
- REPE CMPSB ;Compare backwards while matched
- JE BMSfound ;Matched!
-
- MOV AL,DL ;Restore SI,DI,AL
- SUB AL,CL
- ADD SI,AX
- ADD DI,AX
- INC DI
- MOV AL,DH ;Put matched char back in AL
- POP CX ;Restore end of buffer
- JMP SHORT BMSnext ;Try again
-
- BMSfound: ;DI points to start of match
- INC SP ;End of buffer off stack
- INC SP
- POP BP ;Get frame pointer back
- SUB DI,BufOfs ;Subtract buffer start address
- MOV AX,DI
- INC AX ;Return 0 if found in first byte
- JMP SHORT BMSDone2 ;We're done
-
- BMSnotFound:
- MOV AX,0FFFFh ;Result = FFFF
- BMSDone: ;Result returned in AX
- POP BP
- BMSDone2:
- CLD
- POP DS
- ExitCode 14
-
- BMSearch ENDP
-
- ;***************************************************** BMSearchUC
-
- ; function BMSearchUC(var Buffer;
- ; BufLength : Word;
- ; BT : BTable;
- ; MatchString : string) : Word;
- ; Case-insensitive search of Buffer for MatchString
- ; Return FFFF for failure
- ; Else return number of bytes searched to find MatchString
- ; Assumes MatchString is already raised to uppercase
-
- BMSearchUC PROC FAR
-
- StackFrameBP
- PUSH DS ;Will wipe out DS
- PUSH BP ;Will use BP for temp storage later
-
- MOV CX,BufSize ;CX = Buffer size
- LES DI,Buffer ;ES:DI => Buffer
- LDS BX,BTable ;DS:BX => BTable
- MOV AX,DS ;Keep BTable segment in AX a moment
- LDS SI,MString ;DS:SI => MatchString
- MOV BP,AX ;Keep BTable segment in BP
-
- XOR AX,AX ;AX = 0
- MOV DX,AX ;DX = 0
- MOV DL,[SI] ;DL = length(MatchString)
- OR DL,DL ;Check for trivial case
- JZ BMSUnotFound ;Fail for empty string
-
- BMSUinit:
- DEC DL ;DX = length(MatchString)-1
- ADD SI,DX ;DS:SI => MatchString[length(MatchString)-1]
- ADD CX,DI ;CX = offset of last char in buffer
- ADD DI,DX ;ES:DI => first position to search
- MOV DH,[SI+1] ;DH = MatchString[length(MatchString)]
- STD ;Go backwards
- JMP SHORT BMSUcomp ;Skip link table first time
-
- BMSUnext:
- PUSH DS ;Save DS a moment
- MOV DS,BP ;Get segment of link table
- XLAT ;Get size of link at DS:[BX+AL]
- POP DS ;Restore DS
- ADD DI,AX ;Compute next place to search
-
- BMSUcomp:
- CMP DI,CX ;At end of buffer?
- JAE BMSUnotFound ;Done if so
- MOV AL,ES:[DI] ;AL = next char to try
- UpCase ;Raise it to uppercase
- CMP DH,AL ;Does it match the end of MatchString?
- JNE BMSUnext ;If not same, go back and try again
-
- PUSH CX ;Save end of buffer position
- DEC DI ;Start comparing one character before
- MOV CL,DL ;Compare length(MatchString)-1 characters
- MOV CH,AH ;CH = 0
- JCXZ BMSUfound ;Completely matched if CX = 0
-
- BMSUcomp2:
- LODSB ;Next match character in AL
- MOV AH,ES:[DI] ;Next buffer character in AH
- DEC DI ;Decrement buffer index
- XCHG AL,AH ;Uppercase it
- UpCase
- CMP AH,AL ;A match?
- LOOPE BMSUcomp2 ;Loop while AH=AL and CX<>0
- JE BMSUfound ;Matched!
-
- XOR AH,AH ;Restore SI,DI,AX
- MOV AL,DL
- SUB AL,CL
- ADD SI,AX
- ADD DI,AX
- INC DI
- MOV AL,DH ;Put matched char back in AL
- POP CX ;Restore end of buffer
- JMP SHORT BMSUnext ;Try again
-
- BMSUfound: ;DI points to start of match
- INC SP ;End of buffer off stack
- INC SP
- POP BP ;Get frame pointer back
- SUB DI,BufOfs ;Subtract buffer start address
- MOV AX,DI
- INC AX ;Return 0 if found in first byte
- JMP SHORT BMSUDone2 ;We're done
-
- BMSUnotFound:
- MOV AX,0FFFFh ;Result = FFFF
- BMSUDone: ;Result returned in AX
- POP BP
- BMSUDone2:
- CLD
- POP DS
- ExitCode 14
-
- BMSearchUC ENDP
-
- CODE ENDS
-
- END