;******************************************************************************* ;* Module : CHANGESTR.SUB ;* Programmer: Tony Papadimitriou <tonyp@acm.org> ;* Purpose : Replace all occurrences of one string to another inside a string ;* Language : Motorola/Freescale/NXP HC08/9S08 Assembly Language (aspisys.com/ASM8) ;* Status : FREEWARE Copyright (c) 2021 by Tony Papadimitriou <tonyp@acm.org> ;* Original : http://www.aspisys.com/code/hc08/changestr.html ;* History : 11.11.30 v1.00 Original ;* : 11.12.05 v1.01 BugFix: If S1 (target) string is null, skip action ;* : 12.01.30 v1.02 BugFix: If S2 contains S1, no more infinite loop ;* : 12.01.31 v1.03 BugFix: If S2 is null, simply delete S1 ;* : 12.02.03 v1.04 Removed redundant check of S2 length ;* : (which is now done in string/stringinsertstring) ;* : 20.12.09 v1.05 Made HC08 compatible ;******************************************************************************* #ifmain ;----------------------------------------------------------------------- #ListOff #Uses mcu.inc #ListOn AAX rtc #endif ;------------------------------------------------------------------------ #Uses length.sub #Uses findsubstr.sub #Uses deletechar.sub #Uses insertstring.sub #Uses copy.sub ?_OBJECT_? ;******************************************************************************* ; Purpose: In string "s" replace all occurrences of "s1" with "s2" ; Input : Stack: three pointers (from TOS): -> s, -> s1, -> s2 ; Output : None ; Note(s): All strings are in ASCIZ format ChangeStr macro [#]String,[#]TargetStr,[#]ReplacementStr mreq 1,2,3:[#]String,[#]TargetStr,[#]ReplacementStr #push #spauto :sp pshhx #psp ldhx ~3~ pshhx @@_ldhx_ ~2~ 1,psp pshhx @@_ldhx_ ~1~ pshhx call ~0~ ais #:psp pulhx #pull endm ;------------------------------------------------------------------------------- #spauto :ab ChangeStr proc @parms .s,.s1,.s2 push #ais #ifhcs ldhx .s@@,sp pshhx .s@@ ;.s@@ now holds local copy #else lda .s@@+1,sp psha lda .s@@,sp psha .s@@,2 ;.s@@ now holds local copy #endif @local len1,len2,.pos ;len(target), len(replacement), current string pointer tsx @StringLength .s1@@,spx ;get length of target sta len1@@,spx beq Done@@ ;if null target, exit (2011.12.05) @StringLength .s2@@,spx ;get length of replacement sta len2@@,spx Loop@@ @cop ;in case of many iterations @StringFindSubStr, .s1@@,sp len1@@,sp .s@@,sp update bcs Done@@ #ifhcs sthx .pos@@,sp tsx #else stx .pos@@+1,sp tha tsx sta .pos@@,spx #endif lda len1@@,spx Delete@@ @StringDeleteChar, .pos@@,spx dbnza Delete@@ @StringInsertString, .s2@@,sp .pos@@,sp ;-------------------------------------- ; Update the s pointer to point past the replaced string to avoid ; infinite loop in case s2 contains s1 (2012.01.30) lda len2@@,spx add .pos@@+1,spx sta .s@@+1,spx clra adc .pos@@,spx sta .s@@,spx ;-------------------------------------- bra Loop@@ Done@@ ais #:ais pull rtc #sp ;******************************************************************************* #Exit ;******************************************************************************* @EndStats cs fcs 'String S1 and string S2, and string S1' s1 fcs 'S1' s2 fcs 'S2' s @var ::cs Start proc @rsp clra ;(keeps simulator happy) @StringCopy #cs,#s @ChangeStr #s,#s1,#s2 bra * @vector Vreset,Start