IF1 %%SCAN==0 ;so files .insrt'ing can do right thing; should IF2 %%SCAN==1 ;have their .INSRT as follows: ; if1 ifndef %%scan, .insrt ksc;nscan > ; if2 ife %%scan, .insrt ksc;nscan > ifndef pushae,[ DEFINE PUSHAE AC,LIST IRP LOC,,[LIST] PUSH AC,LOC TERMIN TERMIN DEFINE POPAE AC,LIST IRP LOC,,[LIST] POP AC,LOC TERMIN TERMIN ] DEFINE SCAN ?INPUT,BRKTBL,RESULT,BRKCHR PUSH P,[BRKCHR] PUSH P,[RESULT] PUSH P,[BRKTBL] PUSH P,[INPUT] PUSHJ P,SCANRT TERMIN %BRKAD==1 ;break char flag for appending to result SCBRAD: TLO A,%BRKAD JRST 2(B) ;return to right place in SCANRT %BRKSK==2 ;break char flag for skip of break char SCBRSK: TLO A,%BRKSK JRST 2(B) %BRKLV==4 ;break char flag for leaving on front of input SCBRLV: TLO A,%BRKLV JRST 2(B) %BRKQT==10 ;break char flag for gobbling following char SCBRQT: TLO A,%BRKQT JRST 2(B) SCANRT: .begin scnblk define arg1 (p)-5!termin define arg2 arg1-1!termin define arg3 arg2-1!termin define arg4 arg3-1!termin PUSHAE P,[A,B,C,D] MOVE D,ARG1 ;get addr of input string MOVE C,1(D) ;get BP HRRZ D,(D) ;get char cnt JUMPE D,[MOVE A,[-1,,3] ;none left? Then EOS, no result string. MOVEM A,@ARG4 ;store -1,,3 as "break char" SETZM @ARG3 ;and clear 1st descriptor wd of result string (count) JRST SCNR90] ;and return. SCNR20: ILDB A,C ;get char from input string JSP B,@ARG2 ;execute break table. SOJG D,SCNR20 ;no break, continue JRST SCNR70 ;again none left, EOS. ;break char found! decipher flag(s) and return TLNE A,%BRKQT ; quote next JRST SCNR45 TLNE A,%BRKSK JRST SCNR50 ;skip break char. TLNE A,%BRKAD JRST SCNR55 ;go append break char to result TLNE A,%BRKLV JRST SCNR60 ;leave break char on front of input. JRST SCNR20 ;no flags found?! continue. ; quote next char SCNR45: SOJLE D,SCNR70 ; jump if none left. ILDB A,C ; get it, ignore it. SOJG D,SCNR20 ; get next. JRST SCNR70 ;skip break char - goes on neither result nor input. SCNR50: SOS @ARG1 ;D is subtracted from this for result cnt, so ensure brkchar ;isn't included within result. ;append break char to result string SCNR55: SUBI D,1 ;D becomes new input cnt, so ensure brkchr isn't included. JRST SCNR80 ;and return thusly. ;retain break char on front of input string SCNR60: ADD C,[70000,,0] ;must decrement bp to point back at brkchar. CAIG C, SUB C,[430000,,1] ;(reset if go off wd edge) JRST SCNR80 ;EOS found and non-null result string. SCNR70: MOVE A,[-1,,3] ;"break char". MOVEM A,@ARG4 JRST .+2 ;return result and update input as determined by count in D. ;if control came directly here, result string would contain everything up to ;break char, and input string cnt would include brk char but bp would point ;immediately after it. SCNR80: HRRZM A,@ARG4 ;store break char MOVE A,ARG1 ;get addr of input string again. MOVE B,(A) ;get 1st wd of descriptor before clobbering. HRRM D,(A) ;store updated input string count. SUB B,D ;get descriptor with proper result string cnt EXCH C,1(A) ;exchange bp's to update input and get bp for result. MOVE A,ARG3 ;get addr of result string now MOVEM B,(A) ;store 1st descriptor wd MOVEM C,1(A) ;and 2nd (bp). SCNR90: POPAE P,[D,C,B,A] SUB P,[5,,5] ;flush args and return addr JRST @5(P) ;and return. .end scnblk