Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_3_19910112
-
utilities/redit.mac
There are 8 other files named redit.mac in the archive. Click here to see a list.
;<UTILITIES>REDIT.MAC.33, 4-Feb-81 02:45:35, Edit by ADMIN.MRC
; More "?Failed to find..." stuff
;<UTILITIES>REDIT.MAC.32, 4-Feb-81 02:38:39, Edit by ADMIN.MRC
; Fixed "?Failed to find..." message to not output a line feed at the end
;<MURPHY>REDIT.MAC.31, 6-Jun-77 22:58:49, EDIT BY MURPHY
;<MURPHY>REDIT.MAC.28, 1-APR-76 17:56:40, EDIT BY MURPHY
TITLE REDIT
SALL
.DIRECT FLBLST
SEARCH MONSYM,MACSYM
.REQUIRE SYS:MACREL
SUBTTL DEFINITIONS
DEFINE SCALL (NAM,ARGS)<
..AC==T1
IRP ARGS,<
MOVE ..AC,ARGS
..AC=..AC+1>
CALL NAM>
DEFINE MV (FRM,TO)<
MOVE T1,FRM
MOVEM T1,TO>
;GENERAL ERROR
DEFINE ERROR (TAG,MSG)<
JRST [ TMSG <
MSG
>
JRST TAG]>
;ERROR WITH JSYS MESSAGE
DEFINE ERRORJ (TAG,MSG)<
JRST [ TMSG <
MSG, >
CALL JSERRM
JRST TAG]>
DEFINE TXTPTR (MSG)<POINT 7,[ASCIZ \MSG\]>
;INITIAL PARAMETERS
IMINDI==^D5 ;MINIMUM DIFFERENCE
INMAT==^D5 ;NUMBER LINES FOR MATCH
MAXCHL==^D120 ;MAX CHARS/LINE
;ACS
T1=1
T2=2
T3=3
T4=4
P=17
;16,15 USED BY MACSYM
BP1=14 ;BLOCK POINTER 1
BP2=13 ;BLOCK POINTER 2
F=0 ;FLAGS
;FLAGS
TOPF==1B0 ;TOP OF FILE
;STRUCTURE OF POINTER BLOCK
BFA==0 ;LINE POINTER TABLE ORIGIN
BFA2==1 ;MID-POINT OF LINE POINTER TABLE
NL==2 ;NEXT LINE IN LINE POINTER TABLE
FRE==3 ;FREE WORD IN LINE POINTER TABLE
INJFN==4 ;INPUT JFN
SFRE==5 ;STRING FREE ORIGIN
SBFR==6 ;STRING BUFFER ORIGIN
ESBFR==7 ;END OF STRING BUFFER
INCNT==10 ;INPUT BUFFER COUNT
IPTR==11 ;INPUT BYTE POINTER
BFADR==12 ;ADDRESS OF FILE BUFFER
paglin==13 ;page number,,line number
ipagln==14 ;paglin at start of difference
NBPW==15 ;NUMBER WORDS IN POINTER BLOCK
;STORAGE
PGSIZ==1000
LOC 20000
MINDIF: BLOCK 1 ;MINIMUM NUMBER LINES DIFFERENCES OUTPUT
NMATCH: BLOCK 1 ;NUMBER LINES FOR MATCH AFTER DIFFERENCE
MAXDIF: BLOCK 1 ;MAXIMUM NUMBER LINES DIFFERENT
CNGNO: BLOCK 1 ;CHANGE NUMBER
;COMND STORAGE
CBFSIZ==^D200/5
CBFR: BLOCK CBFSIZ ;COMMAND LINE BUFFER
ACBSIZ==^D200/5
ACBFR: BLOCK ACBSIZ ;ATOM BUFFER
CBLK: BLOCK .CMGJB+1 ;COMMAND STATE BLOCK
GJBLK: BLOCK .GJBFP+1
DEFDIR: BLOCK 10
DEFNAM: BLOCK 10
DEFEXT: BLOCK 10
DEFVER: BLOCK 10
INL1: BLOCK 1 ;FIRST LINE OF DIFFERENCE
INL2: BLOCK 1 ; "
BBP1: BLOCK NBPW ;POINTER BLOCK
BBP2: BLOCK NBPW
NLMAX==^D1000 ;MAX NUMBER LINES BUFFERED
LPTR1: BLOCK NLMAX*^D20 ;LINE POINTER TABLES
LPTR2: BLOCK NLMAX
NBUF==NLMAX*^D10 ;SIZE OF STRING BUFFERS
BUF1: BLOCK NBUF*^D10 ;STRING BUFFERS
EBUF1: BLOCK 0
BUF2: BLOCK NBUF
EBUF2: BLOCK 0
FBUF1: BLOCK PGSIZ ;FILE BUFFERS
FBUF2: BLOCK PGSIZ
FBUFO: BLOCK PGSIZ
NCHBF==PGSIZ*5
OUTCNT: BLOCK 1 ;OUTPUT FILE BUFFER COUNT
OPTR: BLOCK 1 ;OUTPUT BYTE PTR
OUTJFN: BLOCK 1 ;OUTPUT JFN
NPDL==100 ;SIZE OF PDL
PDL: BLOCK NPDL ;PDL
RELOC 0
SUBTTL START AND INITIALIZE
START:
REINIT: MOVE P,[IOWD NPDL,PDL]
RESET
MOVX T1,.FHSLF
MOVEI T2,[JRST START
JRST REINIT] ;ESTABLISH ENTRY VECTOR
HRLI T2,2
SEVEC
MOVEI BP1,BBP1 ;SETUP BLOCK ADDRESSES
MOVEI BP2,BBP2
MOVEI T1,LPTR1 ;INIT BLOCKS
MOVEM T1,BFA(BP1)
MOVEM T1,NL(BP1)
MOVEM T1,FRE(BP1)
MOVEI T1,LPTR2
MOVEM T1,BFA(BP2)
MOVEM T1,NL(BP2)
MOVEM T1,FRE(BP2)
MOVEI T1,LPTR1+NLMAX/2
MOVEM T1,BFA2(BP1)
MOVEI T1,LPTR2+NLMAX/2
MOVEM T1,BFA2(BP2)
MOVEI T1,BUF1
MOVEM T1,SFRE(BP1)
MOVEM T1,SBFR(BP1)
MOVEI T1,EBUF1
MOVEM T1,ESBFR(BP1)
MOVEI T1,BUF2
MOVEM T1,SFRE(BP2)
MOVEM T1,SBFR(BP2)
MOVEI T1,EBUF2
MOVEM T1,ESBFR(BP2)
MOVEI T1,FBUF1
MOVEM T1,BFADR(BP1)
MOVEI T1,FBUF2
MOVEM T1,BFADR(BP2)
MOVEI T1,IMINDI
MOVEM T1,MINDIF
MOVEI T1,INMAT
MOVEM T1,NMATCH
MOVEI T1,NLMAX-^D100
MOVEM T1,MAXDIF
SETZM CNGNO
MOVE T1,[ICBLK,,CBLK] ;INIT COMMAND STATE BLOCK
BLT T1,CBLK+.CMGJB
CLRST: SETO T1,
CLOSF
JFCL
RLJFN
JFCL
; ..
;TOP OF COMMAND LOOP
RESTRT: MOVE P,[IOWD NPDL,PDL] ;RESET STACK
MOVEI T1,CBLK
MOVEI T2,[FLDDB. .CMINI]
COMND
REPAR1: MOVEI T1,CBLK
MOVEI T2,[FLDDB. .CMKEY,,CTBL,<COMMAND NAME>]
COMND ;GET KEYWORD
TXNE T1,CM%NOP
ERROR RESTRT,<?Not a defined command>
HRRZ T2,0(T2) ;GET DISPATCH
JRST 0(T2) ;DO IT
;REPARSE DISPATCH
REPAR0: JRST REPAR1 ;RETRY
;COMMAND COMPLETED
CDONE: JRST REINIT
;CONFRM - PRESERVES ALL ACS
CONFRM: PUSH P,T1
PUSH P,T2
PUSH P,T3
MOVEI T1,CBLK
MOVEI T2,[FLDDB. .CMCFM]
COMND
TXNE T1,CM%NOP
ERROR RESTRT,<?Not confirmed>
POP P,T3
POP P,T2
POP P,T1
RET
;INITIAL COMND STATE BLOCK
ICBLK: REPAR0
.PRIIN,,.PRIOU
POINT 7,[ASCIZ /REDIT>/]
POINT 7,CBFR
POINT 7,CBFR
CBFSIZ*5
0
POINT 7,ACBFR
ACBSIZ*5
GJBLK
;COMMAND DISPATCH TABLE
DEFINE TB (DAT,TXT)<
XWD [ASCIZ \TXT\],DAT>
CTBL: NCTBL,,NCTBL
TB $CMP,<COMPARE>
TB $EXIT,<EXIT>
TB $HELP,<HELP>
TB $MERGE,<MERGE>
TB $MINM,<MINIMUM>
NCTBL==.-CTBL-1
;COMMANDS...
;EXIT
$EXIT: CALL CONFRM
HALTF
JRST CDONE
;HELP
$HELP: CALL CONFRM
HRROI T1,HLPMSG
PSOUT
JRST CDONE
HLPMSG: ASCIZ /
COMPARE compares a "new source" with a previous version to produce a
"differences file" which can be given to a subsequent MERGE.
MERGE merges a "differences file" with a related source to produce
a new version of the source.
/
;MINIMUM LINES FOR MATCH
$MINM: MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <LINES TO MATCH>>]
COMND
MOVEI T2,[FLDDB. .CMNUM,,^D10]
COMND
TXNE T1,CM%NOP
ERROR RESTRT,<?Not a decimal number>
CALL CONFRM
MOVEM T2,MINDIF
JRST CDONE
;COMPARE NEW-SOURCE OLD-SOURCE DIFFERENCES
$CMP: MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <NEW SOURCE FILE>>]
COMND
SETZM GJBLK+.GJDIR ;FLUSH DEFAULTS
SETZM GJBLK+.GJNAM
SETZM GJBLK+.GJEXT
MOVX T2,GJ%OLD
MOVEM T2,GJBLK+.GJGEN ;SET TO GET EXISTING FILE
MOVEI T2,[FLDDB. .CMFIL]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?Invalid source file>
MOVEM T2,INJFN(BP2)
MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <WITH FILE>>]
COMND
SCALL SETFDF,<INJFN(BP2)> ;SET DEFAULTS FROM FIRST FILE
repeat 0,< ;default to previous generation - not used
HRROI T1,DEFVER ;GET GENERATION NUMBER FROM FIRST FILE
MOVE T2,INJFN(BP2)
MOVX T3,1B14
JFNS
HRROI T1,DEFVER
MOVEI T3,^D10
NIN
JSERR
SOS T2 ;DEFAULT TO ONE BEFORE THAT
MOVEM T2,GJBLK+.GJGEN
> ;end repeat 0
MOVX T2,GJ%OLD
moveM T2,GJBLK+.GJGEN
MOVEI T1,CBLK
MOVEI T2,[FLDDB. .CMFIL]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?Invalid source file>
MOVEM T2,INJFN(BP1)
MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <DIFFERENCES TO>>]
COMND
HRROI T2,[ASCIZ /DIF/]
MOVEM T2,GJBLK+.GJEXT ;SET SPECIFIC DEFAULT EXT
MOVX T2,GJ%FOU+GJ%MSG
MOVEM T2,GJBLK+.GJGEN
MOVEI T2,[FLDDB. .CMFIL]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?Invalid destination file>
MOVEM T2,OUTJFN
CALL CONFRM
CALL FILSET ;OPEN FILES
CALL CMP ;DO THE WORK
CALL FILFIN ;CLOSE FILES
JRST CDONE
;UPDATE DIFFERENCES SOURCE NEW-SOURCE
$MERGE: MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <DIFFERENCES FROM>>]
COMND
SETZM GJBLK+.GJDIR ;FLUSH DEFAULTS
SETZM GJBLK+.GJNAM
HRROI T2,[ASCIZ /DIF/]
MOVEM T2,GJBLK+.GJEXT ;STANDARD DEFAULT EXT
MOVX T2,GJ%OLD
MOVEM T2,GJBLK+.GJGEN
MOVEI T2,[FLDDB. .CMFIL]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?Invalid source file>
MOVEM T2,INJFN(BP2)
MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <WITH SOURCE>>]
COMND
SCALL SETFDF,<INJFN(BP2)> ;SET DEFAULTS FROM FIRST FILE
SETZM GJBLK+.GJEXT ;BUT NOT EXTENSION
MOVX T2,GJ%OLD
MOVEM T2,GJBLK+.GJGEN
MOVEI T1,CBLK
MOVEI T2,[FLDDB. .CMFIL]
COMND
TXNE T2,CM%NOP
ERRORJ RESTRT,<?Invalid source file>
MOVEM T2,INJFN(BP1)
MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <TO>>]
COMND
SCALL SETFDF,<INJFN(BP1)> ;SET DEFAULTS FROM SECOND FILE
MOVX T2,GJ%FOU+GJ%MSG
MOVEM T2,GJBLK+.GJGEN
MOVEI T1,CBLK
MOVEI T2,[FLDDB. .CMFIL]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?Invalid destination file>
MOVEM T2,OUTJFN
CALL CONFRM
CALL FILSET ;OPEN FILES
CALL SCH ;DO THE WORK
CALL FILFIN ;CLOSE FILES
JRST CDONE
;SETUP FILES
FILSET: MOVE T1,INJFN(BP1)
MOVX T2,<FLD(7,OF%BSZ)+OF%RD>
OPENF
JSHLT
MOVE T1,INJFN(BP2)
MOVX T2,<FLD(7,OF%BSZ)+OF%RD>
OPENF
JSHLT
MOVE T1,OUTJFN
MOVX T2,<FLD(7,OF%BSZ)+OF%WR>
OPENF
JSHLT
SETZM INCNT(BP1) ;INIT BUFFERS
SETZM INCNT(BP2)
CALLRET FBFINI
;FINISH FILES
FILFIN: CALL FBFOUT ;DUMP LAST BUFFER
MOVE T1,OUTJFN
CLOSF
JFCL
SKIPL T1,INJFN(BP1)
CLOSF
JFCL
SKIPL T1,INJFN(BP2)
CLOSF
JFCL
RET
;SET FILE DEFAULTS
; T1/ JFN
SETFDF: ACVAR <JFN,P1>
MOVEM T1,JFN ;SAVE SOURCE JFN
MOVSI P1,-NJFLD ;NUMBER OF FIELDS TO DO
SETFD1: HRRO T1,JFLD1(P1) ;DEFAULT STRING BUFFER
MOVEM T1,GJBLK+.GJNAM(P1)
MOVE T2,JFN
MOVE T3,JFLD2(P1) ;BIT FOR JFNS
JFNS
AOBJN P1,SETFD1
RET
JFLD1: GJ%NAM+DEFNAM
GJ%EXT+DEFEXT
NJFLD==.-JFLD1
JFLD2: 1B8
1B11
SUBTTL MAIN COMPARE LOOP
CMP: ACVAR <P1>
TXO F,TOPF ;NOTE NOW AT TOP
move t1,[1,,1] ;init page and line numbers
movem t1,paglin(bp1)
movem t1,paglin(bp2)
JRST DIF1 ;FIND FIRST SYNCH POINT
CMPLP: SCALL FILL,<BP1> ;FILL BOTH BUFFERS IF NECESSARY
SCALL FILL,<BP2>
SCALL LCOMP,<NL(BP1),NL(BP2)> ;COMPARE ONE LINE
JUMPN T1,DIF1 ;JUMP IF DIFFERENT
SCALL BUMPL,<BP1> ;INCREMENT LINE
MOVE T1,NL(BP1)
CAML T1,BFA2(BP1) ;LINE BUFFER HALF FULL?
JRST [ SCALL SHIFT,<BP1> ;YES, SHIFT IT DOWN
JRST .+1]
SCALL BUMPL,<BP2> ;INCREMENT LINE
MOVE T1,NL(BP2)
CAML T1,BFA2(BP2) ;DITTO
JRST [ SCALL SHIFT,<BP2>
JRST .+1]
MOVE T1,NL(BP1)
MOVE T2,NL(BP2)
CAML T1,FRE(BP1) ;BOTH AT EOF?
CAMGE T2,FRE(BP2)
JRST CMPLP ;NO, CONTINUE SCAN
RET ;YES, DONE
;FOUND ONE LINE DIFFERENT, BEGIN SCAN TO LOOK FOR MATCH
DIF1: SCALL SHIFT,<BP1> ;SHIFT OUT ALL GOOD STUFF
SCALL SHIFT,<BP2>
mv paglin(bp1),ipagln(bp1) ;and line numbers
mv paglin(bp2),ipagln(bp2)
MV NL(BP1),INL1 ;SAVE START OF DIFFERENCE AREA
MV NL(BP2),INL2
MOVE P2,MAXDIF ;INIT COUNT
DIF4: SCALL BUMpx,<BP1> ;MOVE TO NEXT LINE IN EACH FILE
SCALL BUMpx,<BP2>
SCALL FILL,<BP1> ;ADD TEXT TO BUFFERS
SCALL FILL,<BP2>
SCALL LCOMPN,<NL(BP1),NL(BP2)> ;COMPARE LAST GROUP IN EACH FILE
JUMPE T1,MCH
MOVE P1,NL(BP2) ;COMPARE FILE 1 WITH ALL GROUPS IN FILE 2
DIF2: SOS P1 ;BACKUP ONE LINE IN FILE 2
SCALL LCOMPN,<NL(BP1),P1> ;COMPARE GROUP OF LINES
JUMPE T1,[MOVEM P1,NL(BP2) ;MATCH, UPDATE CURRENT LINE
JRST MCH]
CAMLE P1,INL2 ;DONE ALL GROUPS IN FILE 2?
JRST DIF2 ;NO
MOVE P1,NL(BP1) ;COMPARE FILE 2 WITH ALL GROUPS IN FILE 1
DIF3: SOS P1 ;BACKUP ONE LINE IN FILE 1
SCALL LCOMPN,<P1,NL(BP2)> ;COMPARE GROUP OF LINES
JUMPE T1,[MOVEM P1,NL(BP1) ;MATCH, UPDATE CURRENT LINE
JRST MCH]
CAMLE P1,INL1 ;DONE ALL GROUPS IN FILE 1?
JRST DIF3 ;NO
SOJG P2,DIF4 ;YES, STILL NO MATCH
TMSG <
?Apparent change of at least >
MOVEI T1,.PRIOU
MOVE T2,MAXDIF
MOVX T3,^D10
NOUT
JSERR
TMSG < lines, files cannot be compared.
>
HALTF
;HAVE FOUND MATCH, OUTPUT DIFFERENCES TO FILE
MCH: HRROI T1,[ASCIZ /***** Change #/]
CALL STOUT
AOS T1,CNGNO
CALL NOUT10
hrroi t1,[asciz /; Page /]
call stout
hlrz t1,ipagln(bp2)
call nout10
hrroi t1,[asciz /, line /]
call stout
hrrz t1,ipagln(bp2)
call nout10
hrroi t1,[asciz /; Page /]
call stout
hlrz t1,ipagln(bp1)
call nout10
hrroi t1,[asciz /, line /]
call stout
hrrz t1,ipagln(bp1)
call nout10
MOVEI T1,.CHLFD
CALL COUT
TXZE F,TOPF ;WERE AT TOP?
JRST MCH1 ;YES, NO OUTPUT
SCALL BFOUT,<BP1> ;OUTPUT BUFFER 1
MCH1: MOVEI T1,.CHESC
CALL COUT
hrroi t1,[asciz / ---------------------------------
/]
call stout
SCALL BFOUT,<BP2>
MOVEI T1,.CHESC
CALL COUT
MOVEI T1,.CHLFD
CALL COUT
move p1,inl1 ;reset to initial line
exch p1,nl(bp1)
camle p1,nl(bp1) ;have moved past change?
jrst [ scall bumpl,<bp1> ;no, step line and account position
jrst .-1]
move p1,inl2 ;ditto
exch p1,nl(bp2)
camle p1,nl(bp2)
jrst [ scall bumpl,<bp2>
jrst .-1]
SCALL SHIFTA,<BP1> ;SHIFT OUT COMPLETED STUFF
SCALL SHIFTA,<BP2>
JRST CMPLP
;UPDATE SECTION, SEARCH AND REPLACE
SCH:
SCH0: SCALL FILL,<BP2> ;GET MORE DIFFERENCES
MOVE T1,@NL(BP2) ;FIND BEGINNING OF NEXT REPLACE
MOVE T2,0(T1)
CAME T2,[ASCII /*****/]
JRST [ SCALL BUMPL,<BP2>
MOVE T1,NL(BP2)
CAML T1,FRE(BP2) ;AT EOF?
JRST SCH8 ;YES
JRST SCH0]
SCALL BUMPL,<BP2>
;FIND FIRST MATCHING LINE
SCHLP: MOVE T1,@NL(BP2) ;CHECK FOR NULL SEARCH
MOVE T2,0(T1)
CAMN T2,[<.CHESC>B6] ;END OF STRING?
JRST SCH9 ;YES
SCALL FILL,<BP1> ;GET MORE INPUT IF NECESSARY
SCALL LCOMP,<NL(BP1),NL(BP2)>
JUMPE T1,SCH1 ;JUMP IF LINES MATCH
SCH3: SCALL BUMPL,<BP1> ;NO MATCH, BUMP INPUT
MOVE T1,NL(BP1)
CAMGE T1,FRE(BP1) ;EOF?
JRST SCHLP ;NO, KEEP SEARCHING
TMSG <
?Failed to find >
MOVE T1,NL(BP2) ;GET CURRENT LINE
HRRZ T2,-1(T1) ;CHANGE BANNER IS ONE BEFORE IT
TLOA T2,(<POINT 7,>) ;OUTPUT THE TEXT SANS TERMINATING LINE FEED
SCH3A: PBOUT
ILDB T1,T2
CAIE T1,.CHLFD
JRST SCH3A
MV BFA(BP1),NL(BP1) ;RESET INPUT POINTER
JRST SCH0 ;GO ON TO NEXT CHANGE
;FOUND FIRST MATCHING LINE, CHECK REMAINDER
SCH1: MV NL(BP1),INL1 ;SAVE CURRENT POINTERS
MV NL(BP2),INL2
SCH2: SCALL BUMPL,<BP1> ;STEP TO NEXT LINE
SCALL BUMPL,<BP2>
MOVE T1,@NL(BP2)
MOVE T2,0(T1)
CAMN T2,[<.CHESC>B6] ;END OF SEARCH?
JRST SCH4 ;YES, COMPLETE MATCH
SCALL FILL,<BP1> ;NO, GET MORE INPUT
SCALL FILL,<BP2>
SCALL LCOMP,<NL(BP1),NL(BP2)> ;CHECK NEXT LINE
JUMPE T1,SCH2 ;JUMP IF MATCH
MV INL1,NL(BP1) ;NO MATCH, RESET POINTERS
MV INL2,NL(BP2)
JRST SCH3
;COMPLETE MATCH, EFFECT REPLACEMENT
SCH9: MV NL(BP1),INL1 ;SET BEG OF CHANGE POINTS
MV NL(BP2),INL2
SCH4: scall bumpl,<bp2> ;bypass junk
MOVE T1,NL(BP1) ;SET POINTER TO BEG OF DELETION
EXCH T1,INL1 ;AND SAVE END OF DELETION
CAMG T1,BFA(BP1) ;ANYTHING BEFORE DELETION?
JRST SCH5 ;NO
MOVEM T1,NL(BP1)
SCALL BFOUT,<BP1>
SCH5: MV INL1,NL(BP1) ;STEP POINTER BEYOND DELETION
SCALL SHIFTA,<BP1> ;FLUSH EVERYTHING ALREADY PROCESSED
SCALL BUMPL,<BP2> ;STEP TO FIRST LINE TO INSERT
SCALL SHIFTA,<BP2> ;FLUSH EVERYTHING BEFORE THAT
MV NL(BP2),INL2 ;SAVE TOP OF INSERT
SCH6: SCALL FILL,<BP2> ;GET MORE INSERT TEXT
MOVE T1,@NL(BP2)
MOVE T2,0(T1) ;CHECK FOR END OF INSERT
CAME T2,[<.CHESC>B6]
JRST [ SCALL BUMPL,<BP2> ;NOT END, STEP LINE
JRST SCH6]
SCALL BFOUT,<BP2> ;OUTPUT INSERTION
AOS NL(BP2)
SCALL SHIFTA,<BP2> ;FLUSH EVERYTHING PROCESSED
JRST SCH0 ;DO NEXT CHANGE
;EOF IN DIFFERENCE FILE
SCH8: MV FRE(BP1),NL(BP1) ;SET CURRENT LINE TO END
SCALL BFOUT,<BP1> ;DUMP ALL CURRENT BUFFER
SCH7: SCALL CIN,<BP1> ;COPY REST OF FILE
RET ;DONE
CALL COUT
JRST SCH7
SUBTTL SUBROUTINES
;COMPARE ROUTINES
;COMPARE ONE LINE
; T1/ LINE INDEX
; T2/ LINE INDEX
; RETURNS +1,
; T1/ 0 IF LINES IDENTICAL, NON-0 IF LINES DIFFERENT
LCOMP: ACVAR <P1,P2>
CAML T1,FRE(BP1) ;AT EOF?
JRST [ CAML T2,FRE(BP2) ;YES, BOTH FILES?
TDZA T1,T1 ;YES, EQUAL
SETO T1, ;NO, DIFFERENT
RET]
CAML T2,FRE(BP2) ;AT EOF?
JRST [ SETO T1, ;YES, DIFFERENT
RET]
MOVE P1,0(T1) ;GET STRING ADDRESSES
MOVE P2,0(T2)
LCOM1: MOVE T1,0(P1)
CAME T1,0(P2) ;SAME?
JRST [ SETO T1, ;NO
RET]
AOS P1 ;BUMP WORDS
AOS P2
TRNE T1,177B34 ;LAST WORD?
JRST LCOM1 ;NO
SETZ T1, ;YES, LINES IDENTICAL
RET
;COMPARE 'NMATCH' LINES, SAME ARGS AS LCOMP
LCOMPN: ACVAR <P1,P2,P3>
MOVEM T1,P1
MOVEM T2,P2
MOVE P3,NMATCH
LCOMN1: SCALL LCOMP,<P1,P2>
JUMPN T1,R ;STOP NOW IF DIFFERENT
AOS P1 ;BUMP LINE INDEXES
AOS P2
SOJG P3,LCOMN1 ;DO NEXT LINE
RET ;ALL COMPARE OK
;SHIFT OUT LINES ALREADY PROCESSED
; T1/ BLOCK ADDRESS
SHIFTA: TDZA T2,T2 ;SHIFT OUT EVERYTHING BEFORE CURRENT LINE
SHIFT: MOVE T2,MINDIF ;SHIFT OUT UP TO MINDIF BEFORE CURRENT LINE
ACVAR <BP>
MOVEM T1,BP ;SAVE BLOCK ADDRESS
MOVE T1,NL(BP)
SUB T1,T2 ;FIND FIRST LINE TO KIIP
MOVN T3,T1
ADD T3,BFA(BP) ;COMPUTE (NEG) NUMBER LINES TO DELETE
JUMPGE T3,R ;QUIT IF NONE
HRLZ T1,T1 ;SETUP BLT FROM
HRR T1,BFA(BP) ; .. TO
ADDM T3,NL(BP) ;UPDATE POINTERS
ADDM T3,FRE(BP)
MOVE T2,FRE(BP) ;SETUP BLT FINAL ADR
BLT T1,-1(T2)
RET
;BUMP CURRENT LINE
; T1/ BLOCK ADDRESS
; RETURN +1, CHECKS FOR END OF BUFFER
BUMPL: AOS T2,NL(T1) ;BUMP LINE POINTER
CAMLE T2,FRE(T1) ;PAST END?
jrst [ SOS T2,NL(T1) ;YES, UNDO IT
ret]
move t3,-1(t2) ;check previous line for ffd
move t3,0(t3)
came t3,[<.chffd>b6]
jrst bumpl1
movsi t3,1 ;increment page number
add t3,paglin(t1)
hllzm t3,paglin(t1)
bumpl1: aos paglin(t1) ;increment line number
RET
;same as above but no position accounting - used during
;difference scan
bumpx: aos t2,nl(t1)
camle t2,fre(t1)
sos t2,nl(t1)
ret
;FILL BUFFER SO THAT AT LEAST MINDIF LINES PRESENT FOLLOWING NL
; T1/ BLOCK ADDRESS
FILL: ACVAR <BP,P1>
MOVEM T1,BP ;SAVE BLOCK ADDRESS
FILL3: MOVE T1,NL(BP)
ADD T1,MINDIF
CAMGE T1,FRE(BP) ;ENOUGH LINES PRESENT?
RET ;YES, DONE
SKIPGE INJFN(BP) ;HAVE A JFN?
RET ;NO, ALREADY AT EOF
MOVE P1,SFRE(BP) ;ASSIGN STRING STORAGE
ADDI P1,MAXCHL/5 ;SEE IF ENOUGH LEFT
CAML P1,ESBFR(BP)
JRST [ MOVE P1,SBFR(BP) ;NO, WRAPAROUND
MOVEM P1,SFRE(BP)
JRST .+1]
MOVE P1,SFRE(BP)
MOVEM P1,@FRE(BP) ;PUT ADDRESS IN LINE PTR TABLE
HRLI P1,(POINT 7,0)
FILL1: SCALL CIN,<BP> ;GET A CHAR
JRST [ MOVE T1,INJFN(BP) ;EOF
CLOSF
JSERR
SETOM INJFN(BP) ;NOTE NO JFN
RET]
IDPB T1,P1 ;STORE CHAR
CAIE T1,.CHLFD ;END OF LINE?
CAIN T1,.CHFFD
JRST FILL2 ;YES
CAIN T1,.CHESC ;ESC TREATED AS EOL
JRST FILL2
JRST FILL1 ;NO
FILL2: SETZ T1, ;TIE OFF LINE
IDPB T1,P1
TXNE P1,76B5 ;FILLED WORD?
JRST FILL2 ;NO, KEEP APPENDING NULLS
AOS P1 ;UPDATE STRING FREE
HRRM P1,SFRE(BP)
AOS FRE(BP)
JRST FILL3
;OUTPUT CONTENTS OF BUFFER FROM TOP TO CURRENT LINE
; T1/ BLOCK PTR
; RETURNS +1
BFOUT: ACVAR <BP,P1,P2>
MOVEM T1,BP
MOVE P1,BFA(BP) ;GET FIRST LINE
BFOU2: CAML P1,NL(BP) ;BUFFER EMPTY?
RET ;YES
MOVE P2,0(P1) ;GET STRING ADDRESS
HRLI P2,(POINT 7,0)
BFOU1: ILDB T1,P2
JUMPN T1,[CALL COUT ;OUTPUT CHAR
JRST BFOU1]
AOJA P1,BFOU2 ;DO ALL LINES
;STRING OUT TO FILE
; T1/ POINTER
STOUT: ACVAR <P1>
HLRZ T2,T1
CAIN T2,-1 ;DEFAULT?
HRLI T1,(POINT 7,0) ;YES
MOVEM T1,P1
STOUT1: ILDB T1,P1
JUMPN T1,[CALL COUT ;OUTPUT A CHAR
JRST STOUT1]
RET
;NUMBER OUTPUT, DECIMAL
; T1/ NUMBER
NOUT10: STKVAR <<NBF,3>>
MOVE T2,T1 ;SETUP NUMBER
HRROI T1,NBF
MOVEI T3,^D10
NOUT ;WRITE TO TEMP STACK BUFFER
JSERR
HRROI T1,NBF ;COPY BUFFER TO FILE
CALLRET STOUT
;FILE IO
;CHARACTER IN
; T1/ BLOCK PTR
; RETURNS +1, END OF FILE
; +2, SUCCESS, T1/ CHARACTER
CIN: MOVEM T1,T4 ;SAVE BLOCK PTR
CIN1: SOSGE INCNT(T4) ;CHAR IN BUFFER?
JRST GBF1 ;NO
ILDB T1,IPTR(T4) ;GET IT
RETSKP
GBF1: SKIPGE T1,INJFN(T4)
RET ;FILE ALREADY CLOSED
GTSTS ;GET FILE STATUS
TXNE T2,GS%EOF ;AT EOF?
RET ;YES
MOVE T2,BFADR(T4)
HRLI T2,(POINT 7,0)
MOVEM T2,IPTR(T4) ;INIT PTR
MOVNI T3,NCHBF
SIN
ADDI T3,NCHBF ;COMPUTE NUMBER BYTES STORED
MOVEM T3,INCNT(T4)
JRST CIN1
;CHARACTER OUT
; T1/ CHARACTER
; RETURNS +1
COUT: SOSGE OUTCNT
JRST [ SETZM OUTCNT
CALL FBFOUT
JRST COUT]
IDPB T1,OPTR
RET
FBFOUT: STKVAR <CH>
MOVEM T1,CH
MOVE T1,OUTJFN
HRROI T2,FBUFO
MOVNI T3,NCHBF
ADD T3,OUTCNT
SOUT
CALL FBFINI
MOVE T1,CH
RET
FBFINI: MOVEI T1,NCHBF
MOVEM T1,OUTCNT
MOVE T1,[POINT 7,FBUFO]
MOVEM T1,OPTR
RET
JSERRM: MOVEI T1,.PRIOU
HRLOI T2,.FHSLF ;THIS FORK, LAST ERROR
SETZ T3,
ERSTR
JFCL
JFCL
TMSG <
>
RET
END START