Trailing-Edge
-
PDP-10 Archives
-
RMS-10_T10_704_FT2_880425
-
10,7/rms10/rmssrc/rmsasc.b36
There are 6 other files named rmsasc.b36 in the archive. Click here to see a list.
MODULE ASCII =
BEGIN
GLOBAL BIND ASCIV = 1^24 + 0^18 + 8; !EDIT DATE: 12-Jan-82
%([
FUNCTION: THIS MODULE CONTAINS ALL ROUTINES WHICH PROCESS
RECORDS WITH AN ASCII OR LINE-SEQUENCED (LSA) FILE
AUTHOR: S. BLOUNT
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
!COPYRIGHT (C) 1977, 1982 BY DIGITAL EQUIPMENT CORPORATION
********** TABLE OF CONTENTS **************
ROUTINE FUNCTION
======= ========
PUTASCII PROCESS THE $PUT MACRO FOR ASCII/LSA FILES
PUTLSN WRITE A LINE-SEQUENCE NUMBER INTO A LSA FILE
GETASCII PROCESS THE $GET MACRO FOR ASCII/LSA FILE
GETLSN READ A LINE-SEQUENCE NUMBER FROM LSA FILE
REVISION HISTORY:
EDIT WHO DATE PURPOSE
==== === ==== =======
1 JK 5-AUG-76 NEW ASCII CHANGES.
2 JK 17-AUG-76 'USRSTV' SHOULD HAVE PARTIAL RECORD SIZE FOR 'ER$RTB'.
3 SB 3-OCT-76 CLEAN-UP SOME CODE, ADD UPDPTR BIT
4 SB 23-NOV-76 CHANGE ER$REX TO ER$NEF
5 SB 7-FEB-77 SET UPDPTR FLAG WHEN READING PAGE MARK
6 SB 23-FEB-77 FIX GET PAGE MARK TO RETURN CR-FF
7 SB 7-APR-77 CHANGE HYBYTE TO RST
*************************************************
* *
* NEW REVISION HISTORY *
* *
*************************************************
PRODUCT MODULE SPR
EDIT EDIT QAR DESCRIPTION
====== ====== ===== ===========
56 8 XXXXX Don't give ER$UDF-ER$LSA when
there is a word of nulls right
before the TOPS-10 block boundary in an
LSA file. Some editors do this so programs
can read the linenumber-tab sequence in the
same buffer. If there are nulls instead
of a line number in a random place however,
still give the error.
***** END OF REVISION HISTORY *****
])%
%([ EXTERNAL ROUTINES ])%
EXTERNAL ROUTINE
DUMP,
CRASH,
WRITEBUFFER,
READBUFFER;
%([ ERROR MESSAGES REFERENCED WITHIN THIS MODULE ])%
EXTERNAL
MSGMOVESTRING; ! MOVE-STRING FAILED
FORWARD ROUTINE GETLSN: NOVALUE,
GETASCII,
PUTLSN: NOVALUE;
REQUIRE 'RMSREQ';
EXTDECLARATIONS;
%([ SYMBOLS USED FOR LINE-SEQUENCED FILES: ])%
LITERAL PAGEMARKCODE = %O'777777', ! LINE-NUMBER FOR PAGE MARK
PAGEMARKSIZE = 2*5, ! # OF CHARS IN PAGE-MARK
PMRECSIZE = 2, ! SIZE OF DATA IN PAGE MARK
LINENUMFLAG = BITN ( 35 ), ! FLAG TO DENOTE LINE-NUMBER
LSNBUFSIZE = %O'200', ! SIZE OF A TOPS-10 BUFFER !A56
PAGEMARK1 = %ASCII ' ' + LINENUMFLAG,
PAGEMARK2 = ( ( CHARCR ^ 7 ) + CHARFF ) ^ 22;
! PUTASCII
! ========
! THIS ROUTINE PROCESSES THE $PUT MACRO FOR ASCII AND LINE-SEQUENCED
! ASCII FILES. IT IS PLACED IN THIS MODULE IN ORDER TO
! LOCALIZE ALL ACCESS TO NON-RMS FILE ORGANIZATIONS.
! INPUT:
! <NONE>
! OUTPUT:
! <NONE>
! GLOBALS USED:
! <NONE>
! NOTES:
!
! 1. THE FOLLOWING SYMBOLS ARE MACROS WHICH ARE DEFINED
! IN "RST.REQ". DO NOT CONFUSE THEM WITH LOCAL VARIABLES:
!
! CURRENTBUFFERADR
GLOBAL ROUTINE PUTASCII: NOVALUE =
BEGIN
LOCAL
TEMP1,
TEMP2,
TEMP3,
TEMP4,
FILEPOINTER, ! PTR TO THE FILE BUFFER
USERPOINTER, ! PTR TO THE USER'S RECORD BUFFER
DESTSIZE, ! SIZE OF THE DESTINATION BUFFER
RECORDSIZE, ! SIZE OF THE CURRENT RECORD
BYTESTOMOVE, ! # OF BYTES TO BE TRANSFERRED TO USER'S BUFFER
ASCIIBYTESLEFT;
REGISTER
R5 = 5;
TRACE ( 'PUTASCII' );
%([ IF THIS IS A TTY DEVICE, THEN WE MUST RESET ALL BUFFER
COUNTERS AND POINTERS, ETC. IF IT IS NOT A TTY, WE
MUST MAKE SURE THAT WE ARE AT THE EOF ])%
IF TTY
THEN
BEGIN %(TO RESET BUFFER)%
RST [ RSTBYTECOUNT ] = ZERO; ! CLEAR BUFFER
RST [ RSTPAGPTR ] = POINT ( .CURENTBUFFERADR, 36, 7 ); !CLEAR BUFFER
END %(OF IF TTY)%
ELSE
BEGIN %(TO CHECK FOR EOF)%
IF NOT ENDOFFILE THEN USERERROR ( ER$NEF ) ! MUST BE AT EOF
END; %(F ELSE...)%
%([ FOR SEQUENCED FILES, WE MUST FIRST CREATE A LINE NUMBER ])%
IF SEQUENCED
THEN
BEGIN %( PUT A LSN )%
CALLPUTLSN; ! WRITE LSN INTO FILE
IF .RAB [ RABLSN ] IS PAGEMARKCODE
THEN
RETURN !IGNORE USER'S RECORD IF PAGEMARK IS OUTPUT
END; %( OF PUT A LSN )%
%([ SET UP FILE AND USER BUFFER POINTERS ])%
USERPOINTER = POINT ( .RAB [ RABRBF ] ,36, 7 ); ! GET USER ADDRESS
RECORDSIZE = .RAB [ RABRSZ ]; ! AGET # BYTES TO WRITE
%([ THIS IS THE MAIN LOOP. IT CONTINUES UNTIL THE
ENTIRE USER RECORD HAS BEEN WRITTEN TO THE FILE ])%
WHILE .RECORDSIZE GTR ZERO DO
BEGIN
%([ IS OUR BUFFER FULL? ])%
IF .RST [ RSTBYTECOUNT ] IS PAGESIZE * ASCIIBYTPERWORD
THEN CALLWRITEBUFFER; ! OUTPUT FULL BUFFER
FILEPOINTER = .RST [ RSTPAGPTR ]; ! FETCH FILE PONTER
BYTESTOMOVE = .RECORDSIZE; ! ASSUM RECORD CAN FT IN FILE
ASCIIBYTESLEFT = PAGESIZE * ASCIIBYTPERWORD - .RST [ RSTBYTECOUNT ]; ! ASSUME ASCII FILE
%([ USE THE RECORD SIZE OR THE BUFFER SPACE LEFT, WHICHEVER
IS SMALLER ])%
IF .RECORDSIZE GTR .ASCIIBYTESLEFT THEN BYTESTOMOVE = .ASCIIBYTESLEFT;
DESTSIZE = .BYTESTOMOVE; ! ASSUME SAME SIZE
%([ DEBUGGING ])%
LOOKAT ( ' FILEPTR: ', FILEPOINTER );
LOOKAT ( ' # BYTES: ', BYTESTOMOVE );
LOOKAT ( ' ASCII BYTES: ', ASCIIBYTESLEFT );
%([ DO A MOVE-STRING WITH LEFT JUSTIFICATION TO FILE ])%
TEMP1 = .USERPOINTER;
TEMP2 = .FILEPOINTER;
TEMP3 = .BYTESTOMOVE;
TEMP4 = .DESTSIZE;
IF MOVELEFT ( %(FROM)% TEMP1,
%(TO)% TEMP2,
%(SIZE)% TEMP3,
%(SIZE)% TEMP4 ) IS FALSE
THEN
RMSBUG ( MSGMOVESTRING ); ! MOVE-STRING FAILED
%([ UPDATE OUR FILE AND BUFFER POINTERS ])%
FILEPOINTER = .TEMP2; ! UPDATE POINTERS
USERPOINTER = .TEMP1;
RECORDSIZE = .RECORDSIZE - .BYTESTOMOVE;
RST [ RSTPAGPTR ] = .FILEPOINTER; ! UPDATE POINTER
%([ UPDATE # OF BYTES LEFT IN BUFFER ])%
RST [ RSTBYTECOUNT ] = .RST [ RSTBYTECOUNT ] + .BYTESTOMOVE;
END; %( OF WHILE LOOP )%
%([ WE HAVE NOW MOVED THE ENTIRE RECORD FROM THE USER'S BUFFER
INTO THE INTERNAL RMS-20 FILE BUFFER. WE MUST ALSO RESET
"HYBYTE" TO REFLECT THE HIGHEST BYTE IN THE FILE ])%
RST [ RSTHYBYTE ] = .RST [ RSTHYBYTE ] + .RAB [ RABRSZ ]; ! BUMP THE HIGH BYTE
%([ IF WE ARE WRITING THIS RECORD TO A TERMINAL, THEN WE
SHOULD OUTPUT IT IMMEDIATELY ])%
IF TTY THEN CALLWRITEBUFFER;
RETURN
END; %( OF PUTASCII )%
! PUTLSN
! ======
!
! THIS ROUTINE TAKES THE SEQUENCE NUMBER FROM THE USER'S RAB
! AND INSERTS IT INTO THE FILE AS 5 ASCII DIGITS ( WITH BIT 35
! TURNED ON ) FOLLOWED BY A HORIZONTAL TAB CHARACTER. NOTE
! THAT THE FIRST DIGIT IS FORCED TO BE ON A WORD BOUNDARY.
! ANY BYTES BETWEEN THE VFE OF THE LAST RECORD AND THE LSN WILL
! BE NULLS.
!
! INPUT:
! <NONE>
! OUTPUT:
! <NONE>
! GLOBALS USED:
! WRITEBUFFER
!
!
! FORMAT OF A LSA RECORD
! ====== == = === ======
!
! <FIVE-DIGIT-ASCII-NUMBER><BIT-35><TAB><THE-DATA-RECORD><VFE>
!
!
! FORMAT OF A PAGEMARK
! ====== == = ========
!
! <FIVE-ASCII-BLANKS><BIT-35><CR><FF><THREE-NULLS>
!
GLOBAL ROUTINE PUTLSN: NOVALUE =
BEGIN
! DEVEL PTR TO NEXT WORD TO FILL IN BUFF (READ NEW BUFF IF NECES)
!
MACRO SET_WORDPTR =
BEGIN
IF ( .RST [ RSTBYTECOUNT ] ) EQL PAGESIZE * ASCIIBYTPERWORD
THEN CALLWRITEBUFFER; ! GET NEW BUF
WORDPTR = .RST [RSTPAGPTR]; !NEED SUBFIELD
IF .WORDPTR<30,6> NEQ 36 !WORD-ALIGNED ALREADY?
THEN WORDPTR = .WORDPTR<RH> + 1 !ALIGN AT WORD BOUND
ELSE WORDPTR = .WORDPTR<RH>; !ALREADY THERE, JUST ISOL ADDR
END %;
! UPDATE THE MANY PTRS/CTRS ASSOC WITH WRITE TO BUF JUST DONE
!
MACRO UPD_BUFLOC(NBYTE$)=
BEGIN
RST [RSTBYTECOUNT] = .RST [RSTBYTECOUNT] + NBYTE$; !CNT OF WRIT CHARS IN BUF
RST [RSTHYBYTE] = .RST [RSTHYBYTE] + NBYTE$; !CNT OF WRIT CHARS SINC OP
RST [RSTPAGPTR] = CH$PLUS(.RST [RSTPAGPTR], NBYTE$); !UPD BYTE PTR
END %;
LOCAL
BYTESLEFT,
LINENUMBER,
WORDPTR,
TEMP;
REGISTER
R5 = 5;
MAP
WORDPTR: POINTER;
TRACE ( 'PUTLSN' );
%([ FORCE PAGE POINTER TO A WORD BOUNDARY, LEAVING NULLS
IN LAST PARTIAL WORD. ])%
TEMP = ( ASCIIBYTPERWORD - .RST [ RSTBYTECOUNT ] MOD ASCIIBYTPERWORD ) MOD ASCIIBYTPERWORD; ! NO. BYTES TO SKIP
UPD_BUFLOC(.TEMP); !HOP OVER NULS
LINENUMBER = .RAB [ RABLSN ]; ! FETCH LINE NUMBER
IF .LINENUMBER IS PAGEMARKCODE
THEN BEGIN %( TO WRITE A PAGE MARK )%
SET_WORDPTR; !PT TO NEXT AVAIL WORD IN BUF
WORDPTR [ WHOLEWORD ] = PAGEMARK1; ! STORE 1ST WORD
UPD_BUFLOC(5); !RESET CNTERS
SET_WORDPTR; !RESET BUF PTR
WORDPTR [ WHOLEWORD ] = PAGEMARK2; ! 2ND WORD
UPD_BUFLOC(5); !RESET CNTERS
RETURN ! EXIT
END; %( OF IF THIS IS A PAGE MARK )%
SET_WORDPTR; !PT TO NEXT AVAIL WORD IN BUF
%([ FETCH THE USER'S LINE NUMBER ])%
IF .LINENUMBER GTR MAXLSN THEN USERERROR ( ER$LSN );
%([ CONVERT IT TO DECIMAL AND OUTPUT IT TO FILE ])%
IF BINARYTODECIMAL ( %(NUMBER)% .LINENUMBER,
%(DEST)% .RST [RSTPAGPTR],
%(SIZE)% ASCIIBYTPERWORD ) IS FALSE
THEN USERERROR ( ER$LSN );
%([ SET BIT 35 IN THE LINE-NUMBER ])%
WORDPTR [ WHOLEWORD ] = .WORDPTR [ WHOLEWORD ] OR LINENUMFLAG;
UPD_BUFLOC(5); !ACCT FOR LSN
! NOW THE TAB
SET_WORDPTR;
(.WORDPTR)<29,7> = CHARTAB; !PUT OUT TAB
UPD_BUFLOC(1); !ACCT FOR TAB
RETURN
END; %( OF PUTLSN )%
! GETASCII
! ========
! THIS ROUTINE PROCESSES THE $GET MACRO FOR FILES WITH ASCII
! AND LINE-SEQUENCED ASCII RECORD FORMAT. FOR ASCII
! FILES, IT TRANSFERS ONE RECORD INTO THE USER'S BUFFER,
! WHERE A RECORD IS DEFINED AS BEING A STREAM OF ASCII
! BYTES TERMINATED BY A VERTICAL FORMAT EFFECTOR.
!
! FOR SEQUENCED FILES, FULL WORDS WILL BE TRANSFERED UNTIL
! THE NEXT LINE-NUMBER IS FOUND.
! INPUT:
! MOVEFLAG FLAG FOR RECORD TRANSFER
! TRUE: MOVE THE RECORD ( $GET )
! FALSE: SKIP THE RECORD ( PARTIAL RECORD )
! OUTPUT:
! NO. BYTES IN RECORD (NO. BYTES MOVED IF PARTIALFLAG HAS BEEN SET.)
!
! NOTES:
! 1) THIS ROUTINE SETS 'RSTRHSIZE' WHICH IS THE RECORD HEADER SIZE.
! FOR ASCII STREAM FILES THE RHSIZE IS ZERO (NO RECORD HEADER).
! FOR LSA STREAM FILES THE RHSIZE IS 6 IF RECORD BEGINS WITH
! A LSN, OR 10 IF THE RECORD IS A PAGEMARK. THIS FIELD IS USED
! BY THE $TRUNCATE PROCESSOR TO KNOW HOW MUCH TO SUBTRACT FROM
! RSTDATARFA TO FIND THE BEGINNING OF THE CURRENT PHYSICAL
! RECORD.
!
! 2) A "LOGICAL RECORD" IS DEFINED AS THE DATA THAT THE USER SEES.
!
! 3) A "PHYSICAL RECORD" IS DEFINED AS THE RECORD HEADER PLUS THE
! USER'S DATA.
GLOBAL ROUTINE GETASCII ( MOVEFLAG ) =
BEGIN
ARGUMENT (MOVEFLAG,VALUE);
LOCAL
TEMP1,
TEMP2,
TEMP3,
TEMP4,
FILEPOINTER, ! POINTER TO FILE BUFFER
USERPOINTER, ! POINTER TO USER'S BUFFER
EXITFLAG, ! FLAG FOR LEAVING THE LOOP
RECORDSIZE, ! CURRENT LENGTH OF RECORD
NEXTWORD, ! NEXT FILE WORD FOR LSA FILES
MOVESTATUS, ! TEMP VARIABLE
BUFFERSIZE, ! SIZE OF USER'S BUFFER
BYTESMOVED, !BYTES ACTU COPIED TO USER
BYTESCANNED, !BYTES SCANNED IN DOING COPY (LEADING NULS STRIPPED)
BYTESTOMOVE; ! # OF BYTES IN THIS TRANSFER
MAP
FILEPOINTER: POINTER,
USERPOINTER: POINTER;
TRACE ( 'GETASCII' );
%([ IF EOF, DON'T BOTHER ])%
IF ENDOFFILE THEN USERERROR ( ER$EOF );
%([ SET UP USER BUFFER POINTER, ETC. ])%
USERPOINTER = POINT ( .RAB [ RABUBF ] ,36, 7 ); !FORM BYTE POINTER
BUFFERSIZE = .RAB [ RABUSZ ] * ASCIIBYTPERWORD; ! REMEMBER SIZE OF HIS BUFFER
RECORDSIZE = ZERO; ! CLEAR TOTAL SIZE
RAB [ RABRSZ ] = ZERO; ! CLEAR HIS RECORD SIZE
EXITFLAG = FALSE; ! LOOP FOREVER
%([ IF WE ARE SKIPPING A RECORD, THEN DONT USE A USER POINTER ])%
IF .MOVEFLAG IS FALSE THEN USERPOINTER = ZERO; ! NO DATA WILL BE MOVED
%([ PROCESS LSN IF READING AN LSA STREAM FILE ])%
IF SEQUENCED AND ( PARTIALFLAG IS OFF )
THEN
BEGIN %( GET AN LSN )%
CALLGETLSN; ! FETCH THE LINE-NUMBER
IF .RAB [ RABLSN ] IS PAGEMARKCODE
THEN
BEGIN %( HANDLE PAGEMARK )%
RST [ RSTRHSIZE ] = STMRHPM; ! SET RECORD HEADER SIZE
SETFLAG ( RST [ RSTFLAGS ], FLGUPDPTR ); ! MUST UPDATE POINTER
RST [ RSTRSZ ] = ASCIIBYTPERWORD; ! RECORD SIZE=5
IF .BUFFERSIZE ISNT ZERO
THEN %(MOVE THE PAGE MARK RECORD)%
BEGIN
REPLACEI ( USERPOINTER, CHARCR );
REPLACEI ( USERPOINTER, CHARFF )
END;
RETURN PMRECSIZE ! SO, RECORDSIZE IS ZERO
END %( OF HANDLE PAGEMARK )%
ELSE RST [ RSTRHSIZE ] = STMRHLSN ! SET RECORD HEADER SIZE
END; %( OF GET AN LSN )%
IF NOT ( SEQUENCED )
THEN RST [ RSTRHSIZE ] = STMRHASC; ! SET RECORD HEADER SIZE FOR ASCII STREAM FILE
%([ THIS IS THE MAIN LOOP. IT CONTINUES UNTIL A VFE IS
SEEN OR THE USER'S BUFFER IS FILLED ])%
UNTIL .EXITFLAG
DO
BEGIN
%([ IF BUFFER IS EMPTY, THEN RE-FILL IT ])%
IF .RST [ RSTBYTECOUNT ] IS ZERO THEN CALLREADBUFFER;
IF ENDOFFILE THEN USERERROR ( ER$EOF ); ! CHECK FOR EOF
FILEPOINTER = .RST [ RSTPAGPTR ]; ! GET BUFFER PTR
BYTESTOMOVE = .RST [ RSTBYTECOUNT ]; ! ASSUME WE WILL MOVE BUFFER
IF ( .BUFFERSIZE LSS .BYTESTOMOVE ) AND ( .MOVEFLAG ISNT FALSE )
THEN BYTESTOMOVE = .BUFFERSIZE;
%([ DEBUGGING ])%
LOOKAT ( ' BYTESTOMOVE:', BYTESTOMOVE );
LOOKAT ( ' FILEPTR: ', FILEPOINTER );
%([ WE WILL NOW MOVE THE ENTIRE RECORD
UNTIL WE COME TO EITHER THE END
OF THE FILE, OR THE END OF THE
USER'S BUFFER, OR A VFE. WE WILL SAVE
THE STATUS OF THIS MOVE BECAUSE WE
HAVE TO DO SOME COMMON CLEAN-UP BEFORE
WE NEED TO CHECK IT ])%
TEMP1 = .FILEPOINTER;
TEMP2 = .USERPOINTER;
TEMP3 = .BYTESTOMOVE;
TEMP4 = .TEMP3;
MOVESTATUS = MOVEASCIIRECORD ( %(FROM)% TEMP1,
%(TO)% TEMP2,
%(SIZE)% TEMP3,
%(SIZE)% TEMP4 );
%([ UPDATE POINTERS ])%
FILEPOINTER = .TEMP1;
USERPOINTER = .TEMP2;
BYTESMOVED = .BYTESTOMOVE - .TEMP4 < RH >; ! SUB # OF UNMOVED BYTES
BYTESCANNED = .BYTESTOMOVE - .TEMP3 < RH >; ! SUB # OF UNSCANNED BYTES
RECORDSIZE = .RECORDSIZE + .BYTESMOVED;
%([ IF WE ABORTED WITH A VFE, DEPOSIT IT ])%
IF .MOVESTATUS IS FALSE
THEN
BEGIN
IF .MOVEFLAG
THEN BEGIN
COPYNI ( FILEPOINTER, USERPOINTER ); !MOVE VFE
RECORDSIZE = .RECORDSIZE+1; !INCL VFE IN RECSIZ
END;
EXITFLAG = TRUE ! EXIT FROM LOOP
END; %( OF IF .MOVESTATUS IS FALSE )%
%([ AT THIS POINT, WE HAVE DONE THE FOLLOWING:
1 ) MOVED A FULL RECORD, OR
2 ) FILLED THE USER'S BUFFER, OR
3 ) EXHAUSTED THE CURRENT FILE BUFFER.
])%
%([ SET UP THE RECORD SIZE FIELD AND CHECK FOR
A RECORD WHICH IS TOO BIG FOR THE USER'S
BUFFER. ])%
IF .MOVEFLAG
THEN
BEGIN
RAB [ RABRSZ ] = .RECORDSIZE; ! UPDATE USER'S RSZ
%([ UPDATE NUMBER OF BYTES IN BUFFER ])%
BUFFERSIZE = .BUFFERSIZE - .BYTESMOVED;
%([ IF WE ARE STILL TRYING TO PROCES THE
RECORD, BUT THE BUFFER IS FULL... ])%
IF ( .EXITFLAG IS FALSE ) AND (.BUFFERSIZE LEQ ZERO ) %( WE HAVE FILLED THE BUFFER )%
THEN
BEGIN
USRSTS = ER$RTB; ! SET PARTIAL RECORD
USRSTV = .RECORDSIZE; ! RETURN PARTIAL RECORD SIZE
SETFLAG ( RST [ RSTFLAGS ], FLGPARTIAL ); ! REMEMBER THIS
EXITFLAG = TRUE ! LEAVE
END %( OF .BUFFERSIZE IS ZERO )%
END; %( OF IF .MOVEFLAG )%
%([ RESET THE BUFFER BYTE COUNT AND POINTER ])%
RST [ RSTBYTECOUNT ] = .RST [ RSTBYTECOUNT ] - .BYTESCANNED;
RST [ RSTPAGPTR ] = .FILEPOINTER ! RESET BUFFER PTR
END; %( OF UNTIL EXITFLAG )%
%([ STORE THE SIZE OF THIS RECORD IN THE USER'S RAB ])%
RST [ RSTRSZ ] = .RECORDSIZE; ! PASS THE RECORD SIZE BACK
%([ SET THE RST FLAG BIT WHICH TELLS FINDASC THAT
THE FILE POINTER (PAGPTR) MUST BE UPDATED BEFORE
THE NEXT OPERATION CAN BE DONE ])%
SETFLAG ( RST [ RSTFLAGS ], FLGUPDPTR );
%([ WE HAVE NOW DONE EVERYTHING AND WE CAN EXIT ])%
RETURN .RECORDSIZE
END; %( OF GETASCII )%
! GETLSN
! ======
! THIS ROUTINE PARSES A LINE SEQUENCE NUMBER. THE FILE
! IS ASSUMED TO HAVE BEEN POSITIONED TO A WORD BOUNDARY BY
! THE 'FINDASC' ROUTINE. THE TAB FOLLOWING THE LINE NUMBER
! WILL BE STRIPPED OFF BY THIS ROUTINE. SEE THE 'PUTLSN'
! ROUTINE FOR THE FORMAT OF A LSA RECORD. ALSO NOTE THAT
! THIS ROUTINE HANDLES PAGE MARKS ( SEE THE 'PUTLSN' ROUTINE
! FOR THE FORMAT OF A PAGE MARK. )
!
! INPUT:
! <NONE>
!
! OUTPUT:
! <NONE>
!
! GLOBALS USED:
! <NONE>
!
! NOTES:
!
! 1. THERE IS NO CHECK TO MAKE SURE THAT THE CHARACTER
! WHICH IS STRIPPED OFF IS REALLY A "TAB".
!
GLOBAL ROUTINE GETLSN: NOVALUE =
BEGIN
LOCAL
TEMP,
EXITFLAG,
FILEPOINTER: POINTER;
TRACE ( 'GETLSN' );
%([ MAKE SURE BUFFER IS NON-EMPTY ])%
IF .RST [ RSTBYTECOUNT ] LSS 5 !IGNORE END OF REC CRUFT
THEN
BEGIN %( BUFFER IS EMPTY -- READ NEXT BUFFER )%
CALLREADBUFFER; ! READ IN NEXT BUFFER
IF ENDOFFILE THEN USERERROR (ER$EOF ) ! HANDLE END-OF-FILE CONDITION
END;
TEMP = .RST [RSTPAGPTR]; !PREP TO GET SUBFLD
IF .TEMP<30,6> NEQ 36 !WORD-ALIGNED ALREADY?
THEN
RST [ RSTPAGPTR ] = POINT ( .RST [ RSTPAGPTR ] + 1, 36, 7); !INCR POINTER TO NEW WORD
FILEPOINTER = .RST [ RSTPAGPTR ]; ! GET POINTER TO LSN IN FILE
%([ CHECK TO SEE IF THIS IS A PAGE MARK ])%
IF .FILEPOINTER [ WHOLEWORD ] IS PAGEMARK1
THEN
BEGIN %( HANDLE PAGEMARK )%
RAB [ RABLSN ] = PAGEMARKCODE; ! PASS PAGEMARK CODE BACK TO USER
%([ MAKE CHECK TO SEE IF PAGE MARK SPANS PAGES ])%
IF .RST [ RSTBYTECOUNT ] IS ASCIIBYTPERWORD
THEN
BEGIN %( PART OF PAGEMARK IS IN NEXT BUFFER )%
CALLREADBUFFER; ! GET NEXT BUFFER
RST [ RSTBYTECOUNT ] = .RST [ RSTBYTECOUNT ] - ASCIIBYTPERWORD;
RST [ RSTPAGPTR ] = POINT ( .RST [ RSTPAGPTR ], 1, 7 );
END %( OF PART OF PAGEMARK IS IN NEXT BUFFER )%
ELSE
BEGIN %( ENTIRE PAGEMARK IS IN THIS BUFFER )%
RST [ RSTBYTECOUNT ] = .RST [ RSTBYTECOUNT ] - PAGEMARKSIZE;
RST [ RSTPAGPTR ] = POINT ( .RST [ RSTPAGPTR ] + 1, 1, 7);
END; %( OF ENTIRE PAGEMARK IS IN THIS BUFFER )%
%([ UPDATE THE BYTE # OF THE CURRENT RECORD ])%
RST [ RSTDATARFA ] = .RST [ RSTDATARFA ] + ASCIIBYTPERWORD
END %( OF HANDLE PAGEMARK )%
ELSE
BEGIN %( HANDLE NORMAL LSN )%
!+ !A56
! There may be a word of nulls next to a TOPS-10 buffer !A56
! boundary, because some editors like to keep the LSN and !A56
! the following TAB in the same buffer. !A56
!- !A56
IF (.FILEPOINTER [ WHOLEWORD ] IS ZERO ) !A56
AND !A56
((.FILEPOINTER<RH> MOD LSNBUFSIZE ) EQL (LSNBUFSIZE - 1) ) !A56
THEN %( NULL NEXT TO BUFFER BOUNDARY )% !A56
BEGIN !A56
CALLREADBUFFER; ! GET NEXT BUFFER !A56
IF ENDOFFILE THEN USERERROR (ER$EOF ); ! HANDLE END-OF-FILE CONDITION !A56
FILEPOINTER = .RST [ RSTPAGPTR ]; ! GET NEW VALUE !A56
END; %( OF HANDLE NULL AT END OF PAGE )% !A56
%([ CONVERT THE LINE NUMBER TO BINARY ])%
IF DECIMALTOBINARY ( %(SOURCE)% .FILEPOINTER,
%(SIZE)% ASCIIBYTPERWORD ,
%(RESULT)% TEMP ) IS FALSE
THEN
BEGIN
FILEPROBLEM ( ER$LSN ); ! BAD LINE SEQ NUMBER
USEXITERR
END; %(OF IF DEC-TO-BINARY FAILED)%
%([ WE HAVE NOW CONVERTED THE LINE NUMBER...STORE IT ])%
RAB [ RABLSN ] = .TEMP; ! STORE SEQUENCE NUMBER
RST [ RSTBYTECOUNT ] = .RST [ RSTBYTECOUNT ] - ASCIIBYTPERWORD;
RST [ RSTPAGPTR ] = POINT ( .RST [ RSTPAGPTR ] + 1, 36, 7 ); ! POINT TO CHAR AFTER LINE NUMBER
%([ CHECK FOR EMPTY BUFFER ])%
IF .RST [ RSTBYTECOUNT ] IS ZERO
THEN
BEGIN %( BUFFER IS EMPTY -- READ NEXT BUFFER )%
CALLREADBUFFER; ! READ IN NEXT BUFFER
IF ENDOFFILE THEN USERERROR (ER$EOF ) ! HANDLE END-OF-FILE CONDITION
END;
%([ WE CAN NOW STRIP OFF THE TAB CHARACTER AT
THE START OF THE RECORD. NOTE THAT THERE IS NO
ACTUAL CHECK TO MAKE SURE THAT THE FIRST
CHARACTER IS A TAB. ])%
INCP ( RST [ RSTPAGPTR ] ); ! STRIP OFF THE < TAB> CHAR
RST [ RSTBYTECOUNT ] = .RST [ RSTBYTECOUNT ] - 1; ! COUNT THE <TAB> CHAR
RST [ RSTDATARFA ] = .RST [ RSTDATARFA ] + ASCIIBYTPERWORD + 1
END; %( OF HANDLE NORMAL LSN )%
%([ DONE. RETURN TO CALLER. ])%
RETURN
END; %(OF GETLSN )%
END
ELUDOM