* RPAT (REPLACE OR DELETE PATTERN) * USED IN CONJUNCTION WITH THE TXT-2 EDITOR * WRITTEN BY DREW ROGGE * * SYNTAX OF COMMAND LINE AFTER CNTL-V IS AS FOLLOWS: * * PATT [R OR D] > * * [ ] DENOTES MUST BE ONE OR THE OTHER * < > DENOTES OPTIONAL USE * Only PA is significant in PATT. Any word beginning * with PA can be used, but it must be followed by at * least one blank. Line numbers are separated from * each other by at least one blank. Otherwise blanks * are ignored. * * [R OR D] USE R TO REPLACE ONE PATTERN * WITH ANOTHER. USE D TO DELETE ALL * OCCURANCES OF THE PATTERN (REPLACE * EACH PATTERN WITH THE NULL PATTERN). * * OPTIONAL SELECT MODE WILL DISPLAY * EACH LINE CONTAINING THE PATTERN FOR * EVERY OCCURANCE OF THE PATTERN, * POSITION THE CURSOR ON THE NEXT LINE * DIRECTLY UNDER THE FIRST CHARACTER * OF THE CURRENT PATTERN TO REPLACE * AND WAIT FOR RESPONSE FROM THE USER. * THAT RESPONSE CAN CONSIST OF: * (ESC): ABORT SEARCH, CLOSE UP FILE * AND RETURN TO EDITOR. * (N): DO NOT REPLACE OR DELETE THIS * OCCURANCE OF THE PATTERN BUT * CONTINUE WITH SEARCH. * (ANY OTHER KEY): REPLACE OR DELETE * THIS OCCURANCE OF PATTERN AND * CONTINUE WITH SEARCH. * * > ALLOWS YOU TO CON- * FINE THE SEARCH TO A SECTION IN THE * FILE DEFINED BY THE FIRST LINE TO * SEARCH THRU THE LAST LINE TO SEARCH, * INCLUSIVE. THE DEFAULT FOR IS THE FIRST LINE OF THE FILE * AND THE DEFAULT FOR IS THE * LAST LINE OF THE FILE. TO REPLACE A * PATTERN IN ONLY ONE LINE, USE THAT * LINE NUMBER FOR BOTH AND * . * * ERROR CONDITIONS: * * FATAL ERRORS: * * 1) No 'R' or 'D' found after 'PA ' * 2) VALUE OF IS LARGER THAN * VALUE OF or appears * later in the file than . * 3) OR WAS NOT * FOUND IN THE FILE. IF EITHER OR IS LARGER THAN * THE LAST LINE NUMBER IN THE FILE * THIS PROGRAM WILL RETURN TO THE EDITOR * WITHOUT ANY ACTION BEING TAKEN AND * WITH NO RESPONSE COMING FROM ANYWHERE. * 4) IF, DUE TO THE REPLACEMENT PATTERN * BEING LONGER THAN THE EXISTING * PATTERN, THE ADDRESS OF THE END * OF THE FILE WILL EXCEED THE VALUE * SET BY THE COMMAND 'SET' THIS PRO- * GRAM WILL CLOSE THE FILE AND RET- * URN TO THE EDITOR WITH A PROMPT TELLING * YOU WHAT HAS HAPPENED. * * NON-FATAL ERRORS: * * 4) LENGTH OF PATTERN WAS LONGER THAN * MAXIMUM ALLOWED BY THE VARIABLE * 'MXPT'. PROGRAM WILL REPRINT PROMPT * AND ACCEPT A NEW PATTERN. * 5) AFTER REPLACEMENT OF THE PATTERN, THE * LINE WILL BE LONGER THAN THE MAXIMUM * ALLOWED BY THE VARIABLE 'MAXL'. THE * PROGRAM WILL PRINT AN ERROR PROMPT, * DISPLAY THE LINE AND WAIT FOR RES- * PONSE FROM THE USER. THAT RESPONSE * IS TREATED THE SAME AS IN THE SELECT * MODE. * * * First we must process the arguments. * RPAT CALL HFARG * CPI 'R' 'Replace' option? JZ RP1 CPI 'D' 'Delete' option? JNZ WHAT XRA A RP1 STA RMODE Replace mode. * CALL NONBL Next non-blank should be an 'S', line #, or CR CPI 'S' 'Select' option? JZ RP2 DCX H So NONBL will read this char again. XRA A Not 'Select'. RP2 STA SMODE Select mode. * XCHG . Save HL. LHLD BFP Get 1st address of file and SHLD BOSP save it in case no 1st line # specified. XCHG . Get HL back (pointer to arguments). CALL ZBUF Zero ABUF where line numbers will go. * LXI D,ABUF DE-> where to put next line number. CALL GETNUM 1st line # to ABUF (HL stays on terminator) JZ RP3 Missing -- defaults to 1st line of file. PUSH H CALL FIND Get address of line with this number. JNZ LNFE Doesn't exist. SHLD BOSP Save new start address. POP H LXI D,ABUF+7 Where second line number goes. CALL GETNUM JZ RP3 Missing -- use end of file. LXI H,ABUF+3 Compare 1st and 2nd line numbers. LXI D,ABUF+10 CALL COM0 JC WHAT 1st was larger. LXI H,ABUF+10 CALL FIND+3 Get address of line with 2nd line #. JNZ LNFE Not found. MOV A,M Compute start of next line. CALL ADR JMP RP4 * * * SCAN IN THE FIRST ARGUMENT FROM INPUT LINE * HFARG LXI H,IBUF HL-> Argument line. * RP00 MOV A,M Find end of command ('PA', 'PAT', etc) INX H CPI CR JZ WHAT No arguments at all. CPI SPACE Space terminates command. JNZ RP00 CALL NONBL First nonblank after command should be R or D RET * * * Move line number from HL to DE. Leave HL at the * terminator which may be either a blank or CR. Any * illegal characters result in a jump to WHAT which * terminates execution of RPAT and returns to the editor. * GETNUM CALL NONBL Get next non-blank from HL. DCX H Point to it. CPI CR RZ . Line number is missing. CALL CNTDIG Count # of digits in number (to A and C). CPI 4 Can't have more than 4. JZ COPNUM Exactly four--don't need leading zeroes. JP WHAT Too many. MVI A,4 SUB C A=4-C is # of leading zeroes to add. MOV B,A MVI A,'0' Lead with ascii zeroes. LEAD0 STAX D INX D DCR B JNZ LEAD0 Not done yet. COPNUM MOV A,M Copy number from HL to DE. STAX D INX D Next destination. INX H Next source. DCR C JNZ COPNUM Still more to copy. INR C Reset zero flag. RET * * Count number of digits starting at HL. * CNTDIG PUSH H Save old pointer. MVI C,0 Count. CNT0 MOV A,M CPI SPACE JZ CNT1 Done. CPI CR JZ CNT1 Ditto. CPI '0' JM WHAT Bad digit. CPI '9'+1 JP WHAT INR C count=count+1 INX H JMP CNT0 CNT1 POP H Get old pointer back. MOV A,C Copy count to A. RET * * Return next non-blank character beginning at HL. * HL is left pointing just after this char. * NONBL MOV A,M INX H CPI SPACE JZ NONBL CALL MAP Change lower case to upper. RET * RP3 LHLD EFP RP4 MOV A,M GET R.L. FOR THIS LINE STA EOSC AND SAVE IT. THEN PUT END MVI M,2+80H OF SEARCH MARKER IN FILE. LXI H,PPRM 'PATTERN:' PROMPT LXI D,PTMP-1 PATTERN STOREAGE CALL GPAT GET PATTERN TO REPLACE LDA RMODE REPLACE OR DELETE? ORA A JNZ RP5 IS REPLACE SO GET STRING LXI H,RTMP-1 IS NOT SO USE MOV M,A DUMMY STRING. NEEDS R.L. INX H OF ZERO AND A MVI M,0DH CARRIAGE RETURN JMP RP6 RP5 LXI H,RPRM 'REPLACE:' PROMPT LXI D,RTMP-1 REPLACEMENT STOREAGE CALL GPAT RP6 CALL CRLF * * CALCULATE DIFFERENCE OF LENGTHS * LDA PTMP-1 MOV B,A LDA RTMP-1 SUB B STA DIFF DIFFERENCE OF LENGTHS XRA A STA NCHNG INITIALIZE NUM. PAT'S CHANGED LHLD BOSP BEGINING OF SEARCH POINTER NMCH SHLD RADR ADDR. OF CURRENT LINE R.L. MVI A,0FFH STA CCC SET CURRENT CHAR. COUNT NM1 INX H NM2 SHLD ATMP BEGINING OF CURRENT STRING LXI D,CCC CURRENT CHAR. COUNT LDAX D INR A INCREMENT CHAR. COUNT STAX D INX D PATTERN LENGTH LDAX D MOV C,A COUNTER FOR SEAR ROUTINE INX D PATTERN TO COMP. AGAINST MOV A,M GET CURRENT CHARACTER CPI 0DH CHECK FOR CARRIAGE RETURN JNZ EOL2 IS NOT CHECK FOR PAT. MATCH EOL INX H WAS CR SO NEXT CHAR. IS RL MVI A,2+80H END OF SEARCH MARKER CMP M SEE IF AT END OF SEARCH JNZ NMCH WE'RE NOT THERE YET EOL1 LDA EOSC GET CHAR. TO PUT BACK. MOV M,A PUT IT BACK IN FILE CALL CRLF LDA NCHNG GET NUM. PATTERNS CHANGED CALL DOUT PRINT NUM. PATTERNS LXI H,NPAT POINT TO NUM. PAT., PRINT CALL PRINT IT AND GO HOME. JMP STRTED EOL2 CALL SEAR COMPARE STRINGS SHLD AT1 ADDR. OF CHAR. AFTER STRING LHLD ATMP START OF LAST STRING JNZ NM1 NO MATCH. TRY AGAIN LDA DIFF CHECK FOR FILE OVERFLOW ORA A PUSH H JZ EOL3 FILE WILL STAY SAME LENGTH JM EOL3 FILE WILL GET SHORTER LHLD EFP CURRENT END OF FILE CALL ADR CALCULATE NEW EFP XCHG LHLD EOSP GET LAST USEABLE MEMORY LOCATION INX H ADJUST IT A LITTLE MOV A,D SEE IF EFP IS STILL CMP H SMALLER THAN THE VALUE JC EOL3 IN EOSP MOV A,E CMP L JC EOL3 CALL CRLF LXI H,FOFE FILE OVERFLOW ERROR CALL PRINT Print it. POP H CLEAN UP STACK JMP OL3 RETURN TO EDITOR EOL3 POP H LDA SMODE SELECTED REPLACEMENT ORA A OR NOT? JZ EOL4 IS NOT. REPLACE IT CALL OUTL WANTS TO LOOK AT IT FIRST JZ NM1 DOESN'T WANT TO CHANGE IT EOL4 LHLD RADR GET ADDR. OF CURENT R.L. LDA DIFF GET LENGTH DIFF. OF STRINGS ADD M ADJUST RECORD LENGTH CPI MAXL+3 LONGER THAN MAXIMUM? JC EOL5 IF NOT GO AHEAD AND REPLACE MOV E,A SAVE ADJUSTED LENGTH CALL CRLF LXI H,LOFE 'LINE OVERFLOW ERROR' CALL PRINT PRINT ERROR COMMENT MOV A,E GET LENGTH BACK SUI MAXL+2 CALCULATE OVERFLOW CALL DOUT PRINT IT LXI H,INLN REST OF ERROR COMMENT CALL PRINT PRINT IT CALL OUTL SHOW'EM WHICH LINE LHLD RADR Skip to next line -- we can't change this one. MOV A,M Get length of this line. CALL ADR HL-> length byte of next line. DCX H HL-> preceding CR. JMP EOL Take care of end of line. EOL5 MOV M,A PUT NEW LENGTH IN FILE LDA NCHNG INR A STA NCHNG LDA RTMP-1 GET LENGTH OF PATTERN LXI H,CCC ADJUST CURRENT ADD M CHARACTER COUNT. DCR A MOV M,A SAVE IT LDA DIFF GET DIFF. OF LENGTHS ORA A SET FLAGES LHLD AT1 ADDR. OF CHAR. AFTER STRING JZ MPAT DIFF=ZERO. JUST MOVE PATT. JM CFIL DIFF