TIP: Click on subject to list as thread! ANSI
echo: power_bas
to: ALL
from: BRIAN MCLAUGHLIN
date: 1998-03-14 10:19:00
subject: Code for reverse INSTR

From: Brian McLaughlin 
Subject: Code for reverse INSTR
 
The code below is a reverse INSTR implementation. Instead of the first
instance of a sub-string, it finds the last instance. This can be
helpful
when you are parsing the filename from a pathname, based on the last
instance of the "\" delimiter. I am releasing the code to the public
domain.
 
$LIB ALL OFF
 DECLARE FUNCTION GETSTRLOC& (BYVAL Handle%)   'REQUIRED for use of
RINSTR%
 DECLARE FUNCTION RINSTR% (Main$, SearchFor$)
 
'Demo code -----------------------------------------
 Main$ = "12345678901234567890"
 Search$ = "90"
 PRINT  RINSTR%(Main$, Search$)
 END ' ----------------------------------------------
 
 
'========================================
 FUNCTION RInstr% (Main$, SearchFor$)
'========================================
'  Written by Brian McLaughlin. Released into the public domain.
 
'  This FUNCTION is a reverse implementation of INSTR.  You pass it the
'  string to be searched in Main$, and the string to search for in
'  SearchFor$.
'
'  RInstr% then searches for the last occurence of SearchFor$ within
Main$.
'  If it finds SearchFor$, it returns the position of the first
character
'  of the final occurence of SearchFor$, as a an offset from the first
'  char of Main$. For example, if Main$ were identical to SearchFor$,
'  RInstr% would return 1.
'
'  RInstr% returns a zero if:
'      1) Main$ is null, or
'      2) SearchFor$ is null, or
'      3) SearchFor$ is longer than Main$, or
'      4) SearchFor$ was not found within Main$
'--------------------------------------------------------------------------
 
LOCAL  Position%
 
 Position% = 0          ' assume failure
 
ASM     Push SI
ASM     Push DI
ASM     Push DS
ASM     Les BX, SearchFor$
ASM     Mov AX, ES:[BX]
ASM     Push AX
ASM     Call GETSTRLOC    ; puts SearchFor$ address in DX:AX, length in
CX
ASM     Jcxz ReturnZero   ; we can't search for a null$
ASM     Push DX           ; save them all
ASM     Push AX
ASM     Push CX
ASM     Les BX, Main$
ASM     Mov AX, ES:[BX]
ASM     Push AX
ASM     Call GETSTRLOC    ; puts Main$ address in DX:AX, length in CX
ASM     Mov ES, DX
ASM     Mov DI, AX        ; ES:DI = points to first byte of Main$
ASM     Pop DX            ; DX = length of SearchFor$
ASM     Pop SI
ASM     Pop DS            ; DS:SI points to first byte of SearchFor$
ASM     Jcxz ReturnZero   ; we can't search if main$ is a null$
ASM     Add DI, CX        ; points ES:DI one byte past end of Main$
ASM     Sub DI, DX        ; points ES:DI at last "possible" byte of
Main$
ASM     Mov AL, Byte Ptr [SI] ; AL = value of first char of Search$
ASM     Sub CX, DX
ASM     Js  ReturnZero    ; if CX < 0 then SearchFor$ longer than Main$
ASM     Inc CX            ; adjust CX to get proper number of bytes to
scan
 
ScanStr:
ASM     Std               ; set direction flag for backward scan
ASM     Repne Scasb       ; scan for a match to AL at ES:DI
ASM     Jnz ReturnZero    ; zero flag cleared if no match found
ASM     Push SI           ; save the necessary registers before
ASM     Push DI           ; they're destroyed by Cmpsb, and note that
ASM     Push CX           ; ES:DI points one byte prior to matching char
ASM     Cld               ; now we'll search forward again
ASM     Mov CX, DX        ; for the length of Search$
ASM     Inc DI            ; but first, re-point ES:DI at matching char
ASM     Repe Cmpsb        ; do the comparison
ASM     Pop CX            ; restore earlier loop counter
 
Continued with next message...
 
*** QwkNews (tm) v2.1
 * [TN71] Toast House Import
--- GEcho 1.20/Pro
---------------
* Origin: Toast House Remote (1:100/561)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.