NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF bin/sed *-------------------------------------- .INB inc/macros.i .INB inc/a2osx.i .INB inc/kernel.i .INB inc/mli.i .INB inc/mli.e.i *-------------------------------------- .DUMMY .OR ZPBIN ZS.START ArgIndex .BS 1 ArgPattern .BS 1 ZPPtr1 .BS 2 ZPPatternPtr .BS 2 ZPBufPtr .BS 2 hFile .BS 1 hBuf .BS 1 LineNum .BS 2 char .BS 1 delimiter .BS 1 replaceidx .BS 1 bIgnoreCase .BS 1 ZS.END .ED *-------------------------------------- * File Header (16 Bytes) *-------------------------------------- CS.START cld jmp (.1,x) .DA #$61 6502,Level 1 (65c02) .DA #1 BIN Layout Version 1 .DA #0 S.PS.F.EVENT .DA #0 .DA CS.END-CS.START Code Size (without Constants) .DA DS.END-DS.START Data Segment Size .DA #16 Stack Size .DA #ZS.END-ZS.START Zero Page Size .DA 0 *-------------------------------------- * Relocation Table *-------------------------------------- .1 .DA CS.INIT .DA CS.RUN .DA CS.DOEVENT .DA CS.QUIT L.MSG.USAGE .DA MSG.USAGE L.MSG.CRLF .DA MSG.CRLF .DA 0 *-------------------------------------- CS.INIT clc rts *-------------------------------------- CS.RUN jsr CS.RUN.CheckArgs bcs CS.RUN.LOOP.RTS stz LineNum stz LineNum+1 CS.RUN.LOOP >SLEEP >PUSHB hFile >PUSHW ZPBufPtr >PUSHWI 256 >SYSCALL FGetS bcs .9 inc LineNum bne .2 inc LineNum+1 .2 jsr CS.RUN.PRINT bcc CS.RUN.LOOP rts .9 cmp #MLI.E.EOF bne .99 lda #0 Exit with no Error .99 sec CS.RUN.LOOP.RTS rts *-------------------------------------- CS.RUN.CheckArgs jsr CS.RUN.NextArg bcs .4 lda (ZPPtr1) cmp #'-' beq .1 lda ArgPattern bne .11 lda ArgIndex sta ArgPattern >LDYA ZPPtr1 >STYA ZPPatternPtr jsr CS.RUN.SEDParser bcs .97 bra CS.RUN.CheckArgs .11 lda hFile bne .97 >LDYA ZPPtr1 jsr CS.RUN.OPEN bcs .9 sta hFile bra CS.RUN.CheckArgs .1 ldy #1 lda (ZPPtr1),y ldx #OptionList.Cnt-1 .2 cmp OptionList,x beq .3 dex bpl .2 bra .97 .3 txa lsr beq .98 tax lda #$80 sta bIgnoreCase-1,x bra CS.RUN.CheckArgs .4 lda hFile bne .80 ldy #S.PS.hStdIn lda (pPS),y tax lsr bcs .97 lda Nod.Table.hFD-2,x >SYSCALL GetMemPtr >STYA ZPPtr1 lda (ZPPtr1) cmp #S.FD.T.PIPE bne .97 ldy #S.PS.hStdIn lda (pPS),y sta hFile .80 >LDYAI 256 >SYSCALL GetMem bcs .9 >STYA ZPBufPtr stx hBuf * clc .9 rts .97 lda #E.SYN .98 pha >PUSHW L.MSG.USAGE >PUSHBI 0 >SYSCALL PrintF pla sec rts *-------------------------------------- CS.RUN.NextArg inc ArgIndex lda ArgIndex >SYSCALL ArgV bcs .9 >STYA ZPPtr1 .9 rts *-------------------------------------- CS.RUN.SEDParser * On entry, the expression is in ZPPatternPtr * We are looking for "s/search string/replace string/" * The '/' delimiter can be any char * On exit. ZPPatternPtr points to delimiter-terminated search string, * replaceidx contains the offset to the start of replacement str stz LineNum Reusing this as cntr lda (ZPPatternPtr) cmp #'s' Substitute cmd bne .8 If not, error ldy #$01 Delimiter char lda (ZPPatternPtr),y sta delimiter Stash for later .2 iny lda (ZPPatternPtr),y beq .4 End of string cmp delimiter Is it delimiter? bne .2 inc LineNum Keep count lda LineNum cmp #$01 Second delim bne .2 sty replaceidx bra .2 .4 lda LineNum Check # of delims cmp #$02 bne .8 inc ZPPatternPtr Eat 's/' bne .5 inc ZPPatternPtr+1 .5 inc ZPPatternPtr bne .7 inc ZPPatternPtr+1 .7 clc rts No error return .8 sec rts *-------------------------------------- CS.RUN.OPEN >PUSHYA >PUSHBI O.RDONLY+O.TEXT >PUSHBI S.FI.T.TXT >PUSHWZ Aux type >SYSCALL FOpen bcs .9 sta hFile .9 rts *-------------------------------------- CS.RUN.PRINT >LDYA ZPBufPtr >STYA ZPPtr1 .1 lda (ZPPtr1) beq .7 EOL. No match. ldy #$ff .2 iny lda (ZPPtr1),y bne .3 lda (ZPPatternPtr),y EOL cmp delimiter bne .7 Not end of pattern * No match. .3 lda (ZPPatternPtr),y cmp delimiter beq .5 Match jsr CS.RUN.toUpper sta char lda (ZPPtr1),y jsr CS.RUN.toUpper cmp char beq .2 bra .6 No match * Found a match .5 jsr CS.RUN.GotMatch bra .1 * Mismatch with pattern, keep going .6 jsr CS.RUN.NoMatch bra .1 * Hit EOL but not end of pattern, return .7 jsr CS.RUN.NoMatch lda #C.CR >SYSCALL PutChar lda #C.LF >SYSCALL PutChar clc rts *-------------------------------------- CS.RUN.GotMatch phy ldy replaceidx dey .1 lda (ZPPatternPtr),y cmp delimiter beq .5 phy >SYSCALL PutChar ply iny bra .1 .5 ply tya Advance ZPPtr1 by Y clc adc ZPPtr1 sta ZPPtr1 lda #$00 adc ZPPtr1+1 sta ZPPtr1+1 ldy #$00 rts *-------------------------------------- CS.RUN.NoMatch lda (ZPPtr1) Print ZPPtr1->ZPPtr1+Y phy >SYSCALL PutChar ply inc ZPPtr1 bne .2 inc ZPPtr1+1 .2 dey cpy #$ff bne CS.RUN.NoMatch ldy #$00 rts *-------------------------------------- CS.RUN.toUpper bit bIgnoreCase bpl .9 cmp #'a' bcc .9 cmp #'z'+1 bcs .9 eor #$20 .9 rts *-------------------------------------- CS.QUIT lda hFile beq .1 >SYSCALL FClose .1 lda hBuf beq .8 >SYSCALL FreeMem .8 clc rts *-------------------------------------- CS.DOEVENT sec rts *-------------------------------------- CS.END *-------------------------------------- OptionList .AS "HhIi" OptionList.Cnt .EQ *-OptionList *-------------------------------------- MSG.USAGE .AS "Usage : SED [-I] s/pattern/replacement/ \r\n" .AS " or : CMD|SED [-I] s/pattern/replacement/\r\n" .AS " -I : Ignore Case" MSG.CRLF .AZ "\r\n" *-------------------------------------- .DUMMY .OR 0 DS.START DS.END .ED *-------------------------------------- MAN SAVE usr/src/bin/sed.s ASM