Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_1_19910112
-
6-sources/redit.mac
There are 8 other files named redit.mac in the archive. Click here to see a list.
;<V-SOURCES>REDIT.MAC.15, 22-Sep-83 11:17:24, EDIT BY MURPHY
;Optional output of failed changes to file.
;<V-SOURCES>REDIT.MAC.14, 3-May-83 16:57:09, EDIT BY MURPHY
;Handle unexpected EOF in RED file during MERGE/UNMERGE.
;Note superfluous change in RED file.
;<V-SOURCES>REDIT.MAC.13, 29-Apr-83 18:12:53, EDIT BY MURPHY
;Check for superfluous changes and report them.
;<V-SOURCES>REDIT.MAC.12, 11-Oct-82 17:35:03, EDIT BY MURPHY
;Increase size of command line buffer.
;Increase number lines buffered.
;<MURPHY.1>REDIT.MAC.30, 7-Dec-81 11:55:09, EDIT BY MURPHY
;Fix handling of nulls in input files.
;<MURPHY.1>REDIT.MAC.29, 13-Oct-81 17:19:08, EDIT BY MURPHY
;Fix UNMERGE command.
;<MURPHY.1>REDIT.MAC.25, 3-Aug-81 16:36:39, EDIT BY MURPHY
;Fix bug with changes files having ***** in them.
;<MURPHY.1>REDIT.MAC.23, 20-Jul-81 12:06:30, EDIT BY MURPHY
;Fix bug in parse of MERGE command.
;<MURPHY.1>REDIT.MAC.22, 16-Jul-81 17:07:47, EDIT BY MURPHY
;Real entry vector and version number
;Header in RED file to identify source files.
;Check for ambiguous changes
;<MURPHY.1>REDIT.MAC.14, 14-Jul-81 14:27:38, EDIT BY MURPHY
;Get initialization in right place.
;<MURPHY.1>REDIT.MAC.13, 1-Jul-81 14:45:40, EDIT BY MURPHY
;UNMERGE COMMAND
;NOTE WHEN CHANGE ALREADY MADE
;USE RED AS DEFAULT EXTENSION
;HANDLE RESCAN LINE
;ASSUME INSERT AT BEGINNING ONLY IF FIRST LINES DON'T MATCH
;<MURPHY>REDIT.MAC.3, 13-Oct-80 12:25:30, EDIT BY MURPHY
;FIX ACVAR
;<MURPHY>REDIT.MAC.1, 8-Oct-80 12:33:59, EDIT BY MURPHY
;INCLUDE ONE LINE AFTER CHANGE TO DETECT INSERTION CONFLICTS
;<MURPHY.DDT>REDIT.MAC.3, 10-Jun-80 13:47:28, EDIT BY MURPHY
;NORMALIZE CRLF SEQUENCES
;<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
;VERSION INFO
VERS==1
VUPDAT==0
VEDIT==104
VCUST==0
;VARIOUS DEFS
DEFINE SCALL (NAM,ARGS)<
..AC==T1
IRP ARGS,<
MOVE ..AC,ARGS
..AC=..AC+1>
CALL NAM>
;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==^D140 ;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
UNMF==1B1 ;UNMERGE COMMAND
TRYUF==1B2 ;TRYING FOR CHANGE ALREADY MADE
RSCF==1B3 ;DOING RESCAN COMMAND
SDUPF==1B4 ;SEARCH FOR DUPLICATE IN PROGRESS
DUPF==1B5 ;DO DUPLICATE SEARCHES
JUNKL==1B6 ;JUNK LINE FOUND
JUNKC==1B7 ;JUNK CHANGE POSSIBLE
BPEOF==1B8 ;EOF DETECTED IN BUMPL
;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
SAVECH==15 ;SAVED CHARACTER FOR NEXT CIN
NBPW==16 ;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
NJUNK: BLOCK 1 ;NUMBER JUNK CHANGES FOUND
;COMND STORAGE
CBFSIZ==^D400/5
CBFR: BLOCK CBFSIZ ;COMMAND LINE BUFFER
ACBSIZ==^D400/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 ; "
INL3: BLOCK 1 ;FIRST LINE OF CHANGE BLOCK
INL4: BLOCK 1 ;END OF CHANGE BLOCK
CINL1: BLOCK 1 ;SAVED VARIABLES DURING DUP SEARCH
CINL2: BLOCK 1
CINL3: BLOCK 1
CINL4: BLOCK 1
BBP1: BLOCK NBPW ;POINTER BLOCK
BBP2: BLOCK NBPW
NLMAX==^D1600 ;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
FAIJFN: BLOCK 1 ;JFN FOR FAILED CHANGES
LSTRNG==^D200 ;TEMP STRING BUFFER
STRING: BLOCK LSTRNG/5
NPDL==100 ;SIZE OF PDL
PDL: BLOCK NPDL ;PDL
RELOC 0
SUBTTL START AND INITIALIZE
EVEC: JRST START
JRST START
BYTE (3)VCUST(9)VERS(6)VUPDAT(18)VEDIT
LEVEC==.-EVEC
;DEFAULT FLAGS
DEFF: DUPF ;DO DUPLICATE SEARCHES
START:
MOVE P,[IOWD NPDL,PDL]
RESET
MOVEI T1,IMINDI
MOVEM T1,MINDIF
MOVEI T1,INMAT
MOVEM T1,NMATCH
MOVE F,DEFF ;DEFAULT FLAGS
MOVEI T1,NLMAX-^D100
MOVEM T1,MAXDIF
MOVEI T1,.RSINI
RSCAN% ;GET RESCAN LINE IF ANY
ERJMP .+1
MOVEI T1,.RSCNT
RSCAN% ;SEE IF RESCAN CHARACTERS
SETZ T1, ;ASSUME NO
CAIE T1,0 ;ARE THERE?
TXO F,RSCF ;YES
MOVE T1,[ICBLK,,CBLK] ;INIT COMMAND STATE BLOCK
BLT T1,CBLK+.CMGJB
SETO T1,
CLOSF
JFCL
RLJFN
JFCL
SETOM FAIJFN
; ..
;TOP OF COMMAND LOOP
RESTRT: MOVE P,[IOWD NPDL,PDL] ;RESET STACK
SETZM CNGNO
SETZM NJUNK
CALL INIBLK ;INIT BUFFER BLOCKS
MOVEI T1,CBLK
IFXN. F,RSCF ;DOING RESCAN LINE?
MOVEI T2,.NULIO ;YES, NO TTY OUTPUT
HRRM T2,.CMIOJ(T1)
ENDIF.
MOVEI T2,[FLDDB. .CMINI]
COMND
REPAR1: MOVEI T1,CBLK
IFXN. F,RSCF ;DOING RESCAN LINE?
MOVEI T2,[FLDDB. .CMTOK,,<TXTPTR <REDIT>>]
COMND ;YES, SHOULD START WITH PROGRAM NAME
TXNE T1,CM%NOP ;DID IT?
JRST NORSC ;NO
ENDIF.
MOVEI T2,[FLDDB. .CMKEY,,CTBL,<COMMAND NAME>]
COMND ;GET KEYWORD
TXNN T1,CM%NOP
IFSKP.
JXN F,RSCF,NORSC ;NOT A VALID RESCAN LINE, FORGET IT
ERROR RESTRT,<?NOT A DEFINED COMMAND>
ENDIF.
HRRZ T2,0(T2) ;GET DISPATCH
JRST 0(T2) ;DO IT
;REPARSE DISPATCH
REPAR0: JRST REPAR1 ;RETRY
;REJECT RESCAN LINE
NORSC: MOVEI T2,.PRIIN ;FLUSH RESCAN LINE, DO NORMAL COMMAND
HRRM T2,.CMIOJ(T1)
TXZ F,RSCF
JRST RESTRT
;COMMAND COMPLETED
CDONE: TXZE F,RSCF ;WAS A RESCAN COMMAND?
HALTF ;YES, DONE
JRST RESTRT
;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 $FAICH,<FAILED-CHANGES>
TB $HELP,<HELP>
TB $MERGE,<MERGE>
TB $MINM,<MINIMUM>
TB $NOVER,<NOVERIFY>
TB $UNMRG,<UNMERGE>
TB $VERIF,<VERIFY>
NCTBL==.-CTBL-1
;COMMANDS...
;EXIT
$EXIT: CALL CONFRM
HALTF
JRST CDONE
;HELP
$HELP: CALL CONFRM
HRROI T1,HLPMSG
PSOUT
JRST CDONE
HLPMSG: ASCIZ /
REDIT is used to duplicate changes which have been made in source
files. If there is a source A and a modified version A', and
we wish to make the same modifications to a related source B so
as to produce B', the following steps are performed:
1. COMPARE A' with A to produce the changes file C.
2. MERGE the changes file C with source B to produce B'.
This assumes that A and B are similar, perhaps derived from
a single source via different development paths. In particular,
the areas which were modified in A to produce A' must be
present in B. If this is not so, an error message will be
produced during the MERGE for any change which could not
be duplicated. This typically occurs because changes were made
in the same areas in both A and B, and manual resolution of
the conflict is required.
The commands are:
"COMPARE" compares a "new source" with a previous version to
produce a "changes file" which can be given to a subsequent
"MERGE".
"MERGE" merges a "changes file" with a related source to
produce a new version of the source.
"UNMERGE" removes the changes represented by a "changes file"
from a source. This undoes the effects of a MERGE
of the same changes file.
"MINIMUM" sets the number of lines of 'context' to be found
for each change. The number of lines of text preceding
the actual change will be included in the changes file.
"FAILED-CHANGES" specifies an output filespec to be used during
the next MERGE or UNMERGE operation. Any changes which
are not found will be written to this file in standard
RED format so that additional attempts at merging
these changes may be made.
"VERIFY" is effective only during a MERGE or UNMERGE command. It causes
REDIT to verify that the context for each change is not
ambiguous by searching the entire file for the context.
The context must be found exactly once. If it is found
multiple times, the change is flagged as ambiguous as
is not made. "NOVERIFY" causes REDIT to accept the first
matching context found and not check for multiple matching contexts.
Definition: A superfluous difference is one which exists only
because blanks have been added to or removed from the
end of lines.
/
;FAILED-CHANGES (TO FILE)
$FAICH: MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <TO FILE>>]
COMND
SETZM GJBLK+.GJDIR ;FLUSH DEFAULTS
SETZM GJBLK+.GJNAM
HRROI T2,[ASCIZ /RED/]
MOVEM T2,GJBLK+.GJEXT ;SET USUAL DEFAULT EXT
MOVX T2,GJ%FOU+GJ%MSG
MOVEM T2,GJBLK+.GJGEN
MOVEI T2,[FLDDB. .CMFIL,,,<NAME OF OUTPUT FILE FOR FAILED CHANGES>]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?INVALID DESTINATION FILE>
CALL CONFRM
MOVEM T2,FAIJFN ;SET THE JFN
MOVE T1,FAIJFN
MOVX T2,<FLD(7,OF%BSZ)+OF%WR>
OPENF
JSHLT
JRST CDONE
;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
;VERIFY/NOVERIFY CHANGE CONTEXT
$NOVER: TDZA T4,T4
$VERIF: SETO T4,
MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <CHANGE CONTEXT>>]
COMND
CALL CONFRM
SKIPE T4
TXOA F,DUPF ;VERIFY
TXZ F,DUPF ;NO VERIFY
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,,,<NEW SOURCE FILE>]
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,,,<OLD VERSION OF SOURCE>]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?INVALID SOURCE FILE>
MOVEM T2,INJFN(BP1)
MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <CHANGES TO>>]
COMND
HRROI T2,[ASCIZ /RED/]
MOVEM T2,GJBLK+.GJEXT ;SET SPECIFIC DEFAULT EXT
MOVX T2,GJ%FOU+GJ%MSG
MOVEM T2,GJBLK+.GJGEN
MOVEI T2,[FLDDB. .CMFIL,,,<CHANGE FILE>]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?INVALID DESTINATION FILE>
MOVEM T2,OUTJFN
CALL CONFRM
CALL FILSET ;OPEN FILES
CALL WRFID ;WRITE FILE ID LINES
CALL CMP ;DO THE WORK
CALL FILFIN ;CLOSE FILES
JRST CDONE
;WRITE IDENTIFICATION LINES AT BEGINNING OF CHANGE FILE
WRFID: HRROI T1,[ASCIZ /REDIT /]
CALL STOUT
HRROI T1,STRING
LOAD T2,VI%MAJ,EVEC+2 ;MAJOR VERSION
MOVEI T3,^D8
NOUT
JSERR
LOAD T2,VI%MIN,EVEC+2
IFN. T2
ADDI T2,"A"-1
IDPB T2,T1
ENDIF.
MOVEI T2,"("
IDPB T2,T1
LOAD T2,VI%EDN,EVEC+2
NOUT
JSERR
MOVEI T2,")"
IDPB T2,T1
SETZ T2,
IDPB T2,T1
HRROI T1,STRING
CALL STOUT
HRROI T1,[ASCIZ / COMPARE by user /]
CALL STOUT
GJINF%
MOVE T2,T1
HRROI T1,STRING
DIRST%
JSHLT
HRROI T1,STRING
CALL STOUT
HRROI T1,[ASCIZ /, /]
CALL STOUT
HRROI T1,STRING
SETO T2, ;CURRENT TAD
MOVX T3,<OT%SCL> ;NO TABS
ODTIM%
ERJMP [JSERR
JRST .+1]
HRROI T1,STRING
CALL STOUT
HRROI T1,[ASCIZ /
File 1: /]
CALL STOUT
HRROI T1,STRING
MOVE T2,INJFN(BP1) ;OLD SOURCE
MOVE T3,JSFLGS
JFNS% ;RENDER FILE NAME
HRROI T1,STRING
CALL STOUT ;SEND IT TO RED FILE
HRROI T1,[ASCIZ /
File 2: /]
CALL STOUT
HRROI T1,STRING
MOVE T2,INJFN(BP2) ;NEW SOURCE
MOVE T3,JSFLGS
JFNS%
HRROI T1,STRING
CALL STOUT
HRROI T1,[ASCIZ /
/]
CALL STOUT
RET
JSFLGS: 1B2+1B5+1B8+1B11+1B14+JS%PAF
;UPDATE DIFFERENCES SOURCE NEW-SOURCE
$UNMRG: TXOA F,UNMF ;SAY WHICH COMMAND
$MERGE: TXZ F,UNMF
MOVEI T2,[FLDDB. .CMNOI,,<TXTPTR <CHANGES FROM>>]
COMND
SETZM GJBLK+.GJDIR ;FLUSH DEFAULTS
SETZM GJBLK+.GJNAM
HRROI T2,[ASCIZ /RED/]
MOVEM T2,GJBLK+.GJEXT ;STANDARD DEFAULT EXT
MOVX T2,GJ%OLD
MOVEM T2,GJBLK+.GJGEN
MOVEI T2,[FLDDB. .CMFIL,,,<REDIT CHANGE FILE>]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?INVALID CHANGE FILESPEC>
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,,,<SOURCE TO BE UPDATED>]
COMND
TXNE T1,CM%NOP
ERRORJ RESTRT,<?INVALID SOURCE FILESPEC>
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,,,<NEW SOURCE>]
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
ENDAV.
SUBTTL MAIN COMPARE LOOP
CMP: ACVAR <P1,P2>
TXO F,TOPF ;NOTE NOW AT TOP
TXZ F,JUNKC ;NO JUNK CHANGE YET
MOVE T1,[1,,1] ;init page and line numbers
MOVEM T1,PAGLIN(BP1)
MOVEM T1,PAGLIN(BP2)
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
TXZ F,TOPF ;NORMAL CHANGE HEREAFTER
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
MOVE T2,CNGNO ;DONE, SEE HOW MANY CHANGES
CAIE T2,1 ;EXACTLY ONE?
IFSKP.
TMSG <There was one change found>
;GET THE GRAMMAR RIGHT
ELSE.
IFE. T2
TMSG <There were no changes found>
ELSE.
TMSG <There were >
MOVEI T1,.PRIOU
MOVE T2,CNGNO
MOVEI T3,^D10
NOUT
NOP
TMSG < changes found>
ENDIF.
ENDIF.
SKIPG NJUNK ;ANY JUNK CHANGES?
IFSKP.
TMSG <,
of which >
MOVE T2,NJUNK
CAIE T2,1 ;GET THE GRAMMAR RIGHT
IFSKP.
TMSG <one was superfluous>
ELSE.
MOVEI T1,.PRIOU
MOVEI T3,^D10
NOUT
NOP
TMSG < were superfluous>
ENDIF.
ENDIF.
TMSG <.
>
RET ;YES, DONE
;FOUND ONE LINE DIFFERENT, BEGIN SCAN TO LOOK FOR MATCH
DIF1: TXNE F,JUNKL ;A JUNK DIFFERENCE?
TXO F,JUNKC ;YES, POSSIBLE JUNK CHANGE HERE
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
TXNE F,JUNKL ;A JUNK DIFFERENCE?
TXON F,JUNKC ;YES, STILL POSSIBLE JUNK CHANGE
TXZ F,JUNKC ;NOT POSSIBLE JUNK CHANGE
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
TXZ F,JUNKC ;NOT A JUNK CHANGE IF LINE ADDED
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
TXZ F,JUNKC ;NOT A JUNK CHANGE IF LINE ADDED
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(BP1)
CALL NOUT10
HRROI T1,[ASCIZ /, LINE /]
CALL STOUT
HRRZ T1,IPAGLN(BP1)
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
TXZN F,JUNKC ;A JUNK CHANGE?
IFSKP.
AOS NJUNK ;YES
HRROI T1,[ASCIZ / (superfluous)/]
CALL STOUT
ENDIF.
MOVEI T1,.CHLFD
CALL COUT
TXZE F,TOPF ;WERE AT TOP?
JRST MCH1 ;YES, NO OUTPUT
SCALL BUMPL,<BP1> ;INCLUDE ONE LINE AFTER CHANGE
SCALL BUMPL,<BP2>
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
ENDAV.
SUBTTL MERGE and UNMERGE
;UPDATE SECTION, SEARCH AND REPLACE
SCH:
SCH0: TXZ F,TRYUF!SDUPF ;NOT TRYING ALTERNATE MATCH OR SEARCH FOR DUP
SCALL FILL,<BP2> ;GET MORE DIFFERENCES
MOVE T1,NL(BP2)
MOVEI T2,[ASCIZ /***** CHANGE #/]
CALL SCOMP ;FIND BEGINNING OF NEXT REPLACE
IFL. T1 ;IF NO MATCH
SCALL BUMPL,<BP2>
MOVE T1,NL(BP2)
CAML T1,FRE(BP2) ;AT EOF?
JRST SCH8 ;YES
JRST SCH0
ENDIF.
SCALL BUMPL,<BP2>
JXN F,BPEOF,UXEOF ;CHECK FOR UNEXPECTED EOF
SCHTR: MV. NL(BP2),INL3 ;SAVE BEG OF CHANGE BLOCK
IFXN. F,UNMF!TRYUF ;IF UNMERGE OR TRYING FOR ALTERNATE MATCH
SCALL STPESC,<BP2> ;STEP TO FIRST ESC IN CHANGE BLOCK
SCALL BUMPL,<BP2> ;AND SKIP DIVIDING LINE
JXN F,BPEOF,UXEOF ;CHECK FOR UNEXPECTED EOF
ENDIF.
; ..
;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
JXN F,SDUPF,SCH11 ;JUMP IF WERE SEARCHING FOR DUP
MV. BFA(BP1),NL(BP1) ;RESET INPUT POINTER
MV. INL3,NL(BP2) ;RESET TOP OF CHANGE BLOCK
IFXE. F,UNMF ;IF NOT UNMERGE
TXCN F,TRYUF ;WERE TRYING FOR ALTERNATE MATCH?
JRST SCHTR ;NO, GO DO IT
ENDIF.
TMSG <?FAILED TO FIND >
MOVE T1,NL(BP2) ;GET CURRENT LINE
HRRO T1,-1(T1) ;CHANGE BANNER IS ONE BEFORE IT
PSOUT
SKIPGE FAIJFN ;WRITING FAILED CHANGES?
JRST SKIPCH ;NO
SOS NL(BP2) ;BACK UP TO BANNER
SCALL WRESC,<BP2> ;WRITE OLD TEXT
SCALL WRESC,<BP2> ;WRITE NEW TEXT
MOVE T1,FAIJFN ;TERMINATE LAST ESC LINE
HRROI T2,[ASCIZ /
/]
SETZ T3,
SOUT
JRST SCH0 ;GO ON TO NEXT CHANGE
;SKIP THIS CHANGE
SKIPCH: SCALL STPESC,<BP2> ;PASS OLD TEXT
SCALL STPESC,<BP2> ;PASS NEW TEXT
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>
JXN F,BPEOF,UXEOF ;CHECK FOR UNEXPECTED EOF
MOVE T1,@NL(BP2)
MOVE T2,0(T1)
CAMN T2,[<.CHESC>B6] ;END OF SEARCH?
JRST SCHCD ;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
SCH10: MV. INL1,NL(BP1) ;NO MATCH, RESET POINTERS
MV. INL2,NL(BP2)
JRST SCH3
;SEARCH SUCCESSFUL, ANALYZE STATE
SCHCD: JXE F,DUPF,SCH4 ;IF NOT VERIFYING, GO DO INSERT
IFXN. F,SDUPF ;WERE DOING DUP SEARCH?
MV. BFA(BP1),NL(BP1) ;RESET PTRS
MV. INL3,NL(BP2)
TMSG <?Ambiguous > ;YES, FOUND ANOTHER MATCH
MOVE T1,NL(BP2)
HRRO T1,-1(T1) ;MAKE PTR TO CHANGE ID LINE
PSOUT
TMSG < - this change skipped.
>
JRST SKIPCH ;GO ON TO NEXT CHANGE
ENDIF.
MV. INL1,CINL1 ;SAVE VARIABLES
MV. INL2,CINL2
MV. NL(BP1),CINL3
MV. NL(BP2),CINL4
TXO F,SDUPF ;NOTE DOING DUP SEARCH
JRST SCH10 ;CONTINUE AS IF SEARCH FAILED
;HERE WHEN REACHED END OF FILE ON DUP SEARCH. THAT MEANS WE
;DIDN'T FIND A SECOND MATCH, AND WE WILL GO AHEAD AND MAKE
;THE CHANGE WHERE THE ORIGINAL MATCH WAS FOUND.
SCH11: MV. CINL1,INL1 ;RESTORE VARIABLES
MV. CINL2,INL2
MV. CINL3,NL(BP1)
MV. CINL4,NL(BP2)
JRST SCH4
;COMPLETE MATCH, EFFECT REPLACEMENT
SCH9: MV. NL(BP1),INL1 ;SET BEG OF CHANGE POINTS
MV. NL(BP2),INL2
SCH4: IFXN. F,TRYUF ;IF TRYING ALTERNATE MATCH
TMSG <% >
MOVE T1,INL3 ;TOP OF CHANGE BLOCK
HRRO T1,-1(T1) ;PTR TO CHANGE BANNER
PSOUT
TMSG <% has already been made.
>
SCALL BFOUT,<BP1> ;WRITE THROUGH CHANGE
SCALL SHIFTA,<BP1> ;AND FLUSH IT
JRST SCHU1 ;DONE WITH THIS CHANGE
ENDIF.
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
IFXN. F,UNMF ;IF UNMERGE
MV. INL3,NL(BP2) ;INSERT FIRST PART OF CHANGE BLOCK
ELSE.
SCALL BUMPL,<BP2> ;STEP TO FIRST LINE TO INSERT
ENDIF.
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
JXN F,BPEOF,UXEOF ;CHECK FOR UNEXPECTED EOF
JRST SCH6]
SCALL BFOUT,<BP2> ;OUTPUT INSERTION
SCHU1: AOS NL(BP2)
IFXN. F,UNMF ;IF UNMERGE,
SCALL STPESC,<BP2> ;GO TO END OF CHANGE BLOCK
ENDIF.
SCALL SHIFTA,<BP2> ;FLUSH EVERYTHING PROCESSED
JRST SCH0 ;DO NEXT CHANGE
;UNEXPECTED EOF IN DIFFERENCES FILE, I.E. BEFORE TERMINATING ESC'S
UXEOF: TMSG <
?Unexpected EOF in differences file--probable missing ESC.
Balance of source file will be copied to destination.
>
; ..
;EOF IN DIFFERENCE FILE
SCH8: MV. FRE(BP1),NL(BP1) ;SET CURRENT LINE TO END
SCALL BFOUT,<BP1> ;DUMP ALL CURRENT BUFFER
SKIPGE T1,FAIJFN
IFSKP.
CLOSF
ERJMP .+1
ENDIF.
SCH7: SCALL CIN,<BP1> ;COPY REST OF FILE
RET ;DONE
CALL COUT
JRST SCH7
SUBTTL SUBROUTINES
;STEP TO NEXT ESC IN CHANGE BLOCK
; T1/ LINE INDEX
; RETURNS +1 ALWAYS
STPESC: ACVAR <P1>
MOVEM T1,P1
DO.
SCALL FILL,<P1>
MOVE T1,@NL(P1) ;LOOK AT BEGINNING OF LINE
MOVE T2,0(T1)
CAMN T2,[<.CHESC>B6] ;AN ESC?
EXIT. ;YES
SCALL BUMPL,<P1> ;NO, STEP TO NEXT LINE
JXE F,BPEOF,TOP. ;LOOP IF NO EOF
OD.
SCALL BUMPL,<P1> ;STEP TO LINE AFTER ESC
RET
ENDAV.
;WRITE FROM CURRENT LINE TO NEXT ESC TO FAILED-CHANGES FILE
; T1/ LINE INDEX
; RETURNS +1 ALWAYS
WRESC: ACVAR <P1>
MOVEM T1,P1
DO.
SCALL FILL,<P1>
MOVE T1,FAIJFN
HRRO T2,@NL(P1)
SETZ T3,
SOUT ;WRITE THE LINE
MOVE T1,@NL(P1) ;LOOK AT BEGINNING OF LINE
MOVE T2,0(T1)
CAMN T2,[<.CHESC>B6] ;AN ESC?
EXIT. ;YES
SCALL BUMPL,<P1> ;NO, STEP TO NEXT LINE
JXE F,BPEOF,TOP. ;LOOP IF NO EOF
OD.
SCALL BUMPL,<P1> ;STEP TO LINE AFTER ESC
RET
ENDAV.
;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>
TXZ F,JUNKL ;NOT JUNK DIFFERENCE YET
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 RETO ;YES, DIFFERENT
MOVE P1,0(T1) ;GET STRING ADDRESSES
MOVE P2,0(T2)
LCOM1: MOVE T1,0(P1)
CAME T1,0(P2) ;SAME?
JRST LCOM2 ;NO, SEE WHY
AOS P1 ;BUMP WORDS
AOS P2
TRNE T1,177B34 ;LAST WORD?
JRST LCOM1 ;NO
RETZ: SETZ T1, ;YES, LINES IDENTICAL
RET
LCOM2: HRLI P1,(POINT 7,0)
HRLI P2,(POINT 7,0) ;SETUP TO CHECK EACH BYTE
DO.
ILDB T1,P1
ILDB T2,P2
CAMN T1,T2 ;BYTES SAME?
JUMPN T1,TOP. ;YES, LOOP IF NOT NULL
ENDDO.
DO.
CAIN T1,.CHLFD
JRST ENDLP.
JUMPE T1,ENDLP. ;IF FIRST STRING ENDED, CHECK SECOND
CAIN T1,.CHCRT ;CR EQUIVALENT TO BLANK
MOVEI T1," "
CAIE T1," " ;SEE IF FIRST STRING ENDS WITH BLANKS
CAIN T1,.CHTAB
IFNSK.
ILDB T1,P1 ;MAYBE, KEEP CHECKING
JRST TOP.
ENDIF.
JRST RETO ;DIFFERENCE IS NON-BLANK CHARACTER
ENDDO.
DO.
CAIE T2,.CHLFD ;IF SECOND STRING ENDED, JUNK DIFFERENCE
CAIN T2,0
IFNSK.
TXO F,JUNKL ;IF SECOND STRING ENDED, JUNK DIFFERENCE
JRST RETO
ENDIF.
CAIN T2,.CHCRT ;CR EQUIVALENT TO BLANK
MOVEI T2," "
CAIE T2," "
CAIN T2,.CHTAB
IFNSK.
ILDB T2,P2 ;BLANK - KEEP CHECKING
JRST TOP.
ENDIF.
JRST RETO ;NON-BLANK, REAL DIFFERENCE.
ENDDO.
ENDAV.
;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
ENDAV.
;COMPARE ONE LINE WITH LITERAL TEXT
; T1/ LINE INDEX
; T2/ ADR OF ASCIZ TEXT
; RETURNS +1,
; T1/ 0 IF LINES IDENTICAL, 1 IF TEXT A SUBSTRING, -1 IF DIFFERENT
SCOMP: ACVAR <P1,P2>
MOVE P1,0(T1) ;GET STRING ADDRESSES
MOVE P2,T2
DO.
MOVE T1,0(P1)
CAME T1,0(P2)
IFSKP.
AOS P1 ;SAME SO FAR, STEP WORDS
AOS P2
TRNE T1,177B34 ;LAST WORD?
LOOP. ;NO
SETZ T1, ;YES, IDENTICAL
RET
ENDIF.
OD. ;FALL OUT OF LOOP WHEN WORDS DIFFERENT
HRLI P1,(POINT 7,0) ;MAKE BYTE PTRS
HRLI P2,(POINT 7,0)
DO.
ILDB T1,P1 ;GET BYTES
ILDB T2,P2
CAMN T1,T2 ;SAME?
LOOP. ;YES, FIND THE DIFFERENT ONE
OD.
IFE. T2 ;TEXT STRING ENDED?
MOVEI T1,1 ;YES, NOTE SUBSTRING
RET
ENDIF.
RETO: SETO T1, ;JUST DIFFERENT
RET
ENDAV.
;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
ENDAV.
;BUMP CURRENT LINE
; T1/ BLOCK ADDRESS
; RETURN +1, CHECKS FOR END OF BUFFER
BUMPL: TXZ F,BPEOF ;INIT FLAG
AOS T2,NL(T1) ;BUMP LINE POINTER
CAMLE T2,FRE(T1) ;PAST END?
JRST [ SOS T2,NL(T1) ;YES, UNDO IT
TXO F,BPEOF ;NOTE EOF
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
ENDAV.
;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
ENDAV.
;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
ENDAV.
;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
ENDSV.
;FILE IO
;CHARACTER IN
; T1/ BLOCK PTR
; RETURNS +1, END OF FILE
; +2, SUCCESS, T1/ CHARACTER
CIN: MOVEM T1,T4 ;SAVE BLOCK PTR
SKIPE T1,SAVECH(T4) ;SAVED CHAR FROM BEFORE?
JRST [ SETZM SAVECH(T4) ;YES, ONCE ONLY
RETSKP] ;RETURN IT
CIN1: SOSGE INCNT(T4) ;CHAR IN BUFFER?
JRST GBF1 ;NO
ILDB T1,IPTR(T4) ;GET IT
JUMPE T1,CIN1 ;FLUSH NULLS
CAIN T1,.CHCRT ;FLUSH CR'S TO NORMALIZE CRLF SEQUENCE
JRST CIN1
CAIN T1,.CHLFD ;LF?
JRST [ MOVEM T1,SAVECH(T4) ;YES, SAVE IT FOR NEXT TIME
MOVEI T1,.CHCRT ;RETURN CR NOW
JRST .+1]
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
ENDSV.
;INIT BUFFER BLOCKS
INIBLK: 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)
RET
;JSYS ERROR MESSAGE
JSERRM: MOVEI T1,.PRIOU
HRLOI T2,.FHSLF ;THIS FORK, LAST ERROR
SETZ T3,
ERSTR
JFCL
JFCL
TMSG <
>
RET
END LEVEC,,EVEC