;***************************************************************************
;
; GLOBAL.M68
;
;
; Written By: James A. Jarboe IV
; 1401 19th Street
; Huntsville, TX 77340
; 409-295-5767
;
; 04/14/86
; GR/AM
; copyright @ 1986 James A. Jarboe IV
;****************************************************************************
; Description: Replace 1 string with another within a given string
; Similiar to VUE's global command
; Type: XCALL GLOBAL,STRING,WHAT,WITH
; The WHAT variable will be replaced by the WITH variable
; within the STRING variable as long as the length of the
; STRING variable is long enough to handle the LEN(WITH)+
; the LEN(STRING).
; If the WHAT string is longer than the WITH string then
; the entire STRING will be truncated.
; If the WHAT string is shorter than the WITH string then
; the entire STRING will be expanded if the LEN(STRING) is
; long enough.
; If WITH string is empty then WHAT string will be replaced
; with nothing and the entire STRING will be truncated.
; WARNING: it will replace strings just as the vue global
; does. If WHAT=is and WITH=as it will change
; "this" to "thas"
; Example:
; STRING = a string variable any length
; WHAT = string to change, any length
; WITH = string to change WHAT to any length
; as long as the length + length of the rest of STRING
; is not greater than the mapped length of STRING
;
; 10 MAP1 STRING,S,20,"ABCDEFG" ! size of string longer than Len(string)
; 20 MAP1 WHAT ,S,5 ,"ABC" ! variable to change
; 30 MAP1 WITH ,S,5 ,"Z" ! variable to change to
; 40 ? STRING
; 50 XCALL GLOBAL,STRING,WHAT,WITH
; 60 ? STRING
; 70 END
; Would look like;
; ABCDEFG
; ZDEFG
;
; WHAT="B"
; WITH="XYZ"
;
; Would look like;
; ABCDEFG
; AXYZCDEFG
;
; WHAT="ABC"
; WITH=""
;
; Would look like:
; ABCDEFG
; DEFG
PHDR -1,0,PH$REE!PH$REU
;
; Check for variable & set up registers
;
CMMW P.TOP(A3),#3 ; must be 3 variables
JNE NOTHRE ; no ... then quit
MOV A.SIZ(A3),D3 ; D3 is size of main STRING
MOV A.ADR(A3),A0 ; A0 points to start of STRING
MOV B.ADR(A3),A1 ; A1 points to WHAT string
; to set up we make A0 point to the begining of STRING and
; A4 points past the end of the string as mapped in BASIC
; then we find the LEN(STRING) by looking for null
; then move end'char to end of string
; before:
; STRING |ABCDEFG | ! mapped as in BASIC
; after:
; STRING | ABCDEFG|
; Later we move it back adding the WITH for WHAT
; later:
; STRING |ZDEFG |
;
SETUP:
MOV A0,A4 ; A4 points to start of STRING
ADD D3,A4 ; A4 points past end of STRING
CLR D2 ; D2 now 0
10$:
TSTB @A0 ; end of STRING ?
BEQ 20$ ; yes... go forward
INC A0 ; lets find the end of STRIN
INC D2 ; add 1 to counter
BR 10$ ; do it again
20$:
CMP D2,#0 ; counter=0 ?
BEQ LOOP ; yes...go forward
MOVB -(A0),-(A4) ; mov STRING char to end of STRING
DEC D2 ; counter=-1
DEC D3 ;ADDED
BR 20$ ; do it again
LOOP:
CTRLC OUTOF ; control c then quit
CLR D2
TSTB @A4 ; TEST FOR NULL
BEQ NOMORE ; QUIT IF THROUGH VARIABLE WITH null
CMP D3,A.SIZ(A3) ; test for size of string
BEQ NOMORE ; quit if through variable by size
CMMB @A4,@A1 ; compare STRING to WHAT
BNE A.DIT ; branch if no match
SAVE A4,A1,D3 ; save pointer in case a match
10$:
TSTB @A1 ; at end of LEN(WHAT) string ?
BEQ REPLC ; yes then lets process
CMP D2,B.SIZ(A3) ; at end of size WHAT string ?
BEQ REPLC ; yes then lets process
INC D2 ; add 1 to counter
INC D3
CMMB (A4)+,(A1)+ ; compare STRING char to WHAT char
BEQ 10$ ; If equal then goto next char
REST A4,A1,D3 ; no match restore pointers
A.DIT:
MOVB (A4)+,(A0)+ ; increment variable place
INC D3
JMP LOOP ; do it again
REPLC:
MOV A4,D1 ; make D1 hold pointer
MOV D3,D2
REST A4,A1,D3 ; restore because we saved
MOV D2,D3
MOV D1,A4 ; now make A4 what it was
CLR D2 ; clear counter
MOV C.ADR(A3),A2 ; point to WITH string
10$:
TSTB @A2
BEQ NOWITH
CMP D2,C.SIZ(A3)
BEQ NOWITH
MOVB (A2)+,(A0)+
INC D2
BR 10$
NOWITH:
JMP LOOP
NOMORE:
CLRB @A0 ; clear end of string
RTN ; return to basic
NOTHRE:
TYPECR Not enough variables passed in GLOBAL.SBR
RTN
OUTOF:
EXIT
END