.NLIST TOC,SYM .TITLE $GETLN .SBTTL ULBLIB 008 - Get the next line .IDENT \V01.01\ ;001 .PSECT .LIBC. .ENABL LC,GBL ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. ; Edit History: ; ; 001 23-Jul-80 05:14 AM Metsch, James (29602) [240,122] ; Fix boundary problem ; (001) ; 002 15-May-90 Bill Gavin Recognize line ending with ;+ ; $GETLN ; The Get Line routine returns the next line in a file. Lines are terminated ; with line feed, vertical tab, or form feed. Vertical tab and form feed are ; returned in the buffer, and carriage return/line feed pairs are not. ; ; R0 -> File Descriptor Block (FDB) ; ; CALL $GETLN ; ; C-bit = 0 => success ; F.NRBD(R0) = the size of the line ; F.NRBD+2(R0) -> the start of the line ; ; C-bit = 1 => failure ; F.ERR(R0) contains the error code. ;- .MCALL .READW ERRBYT =: 52 ; 002 LF =: 12 VT =: 13 FF =: 14 CR =: 15 $GETLN:: CALL $SAVAL ; Save caller's registers ; Get buffer info from caller's File Descriptor Block MOV R0,R1 ;Copy -> FDB MOV F.URBA(R1),R4 ;Get -> user buffer MOV R4,R5 ;We need to find the end of it, ADD F.RSIZ(R1),R5 ; so add in the maximum record size. MOV F.IOBF(R1),R3 ;Get the pointer to the start of the buffer ADD F.BFSZ(R1),R3 ;Get the end of the buffer ; Start at the beginning of the buffer 10$: MOV F.BPTR(R1),R2 ; Get the input buffer pointer ; Scan the contents of the buffer 20$: CMP R2,R3 ; Anything left in the input buffer? BHIS 30$ ; No, try to get some more CMP R4,R5 ; Any room left in the user buffer? BHI 50$ ; Branch if not. Error MOVB (R2)+,@R4 ; Move the character to caller's buffer BICB #200,@R4 ; Clear the parity BEQ 20$ ; Ignore nulls CMPB #LF,@R4 ; Is it a line feed? BEQ 60$ ; Branch if so CMPB #VT,@R4 ; Is it a vertical tab? BEQ 70$ ; Branch if not CMPB #FF,@R4 ; How about a form feed? BEQ 70$ ; Branch if so TSTB (R4)+ ; Get past the character BR 20$ ; and go get another one. ; End of buffer - Read in another block, adjust parameters 30$: ADD #F.IO.,R0 ;Point to the I/O block .READW ; and issue the read BCS 40$ ; Branch if error ;CG01 MOV F.IOWC(R1),R0 ;Get the number of words read BIC #377,R0 ;Need to make it blocks SWAB R0 ; (/256.) ADD R0,F.IOBK(R1) ;Bump the block number for the next read MOV F.IOBF(R1),F.BPTR(R1) ;Reset the buffer pointer MOV R1,R0 ;Restore R0 BR 10$ ; and try again ; Error on file READW 40$: TSTB @#ERRBYT ; Is it End Of File ? ; 002 BNE 45$ ; No, must be hard error ; 002 CMP R4,F.URBA(R1) ; Anything in current line ? ; 002 BGT 80$ ; Yes, return line to caller ; 002 45$: JMP $IERR ; Set F.ERR with correct code;Set C-bit ;CG01 ; Error, we ran out of room in user buffer 50$: MOVB #FE.RTL,F.ERR(R1) ;Record length too long BR 90$ ;Return with error ; found in buffer 60$: CMP R4,F.URBA(R1) ; Is it beginning of line? ;001 BEQ 80$ ; Yes, skip the ;001 CMPB #CR,-(R4) ; Was prev char ? ;001 BEQ 80$ ; Yes, skip the ;**-1 ; or found in buffer 70$: TSTB (R4)+ ; Point past last char in out buf ; Clear next char to provide termination 80$: CLRB @R4 ;Clear a byte to make it ASCIZ ; Update info in File Descriptor Block MOV F.URBA(R1),R5 ;Copy the line's starting address SUB R5,R4 ;Get its length MOV R5,F.NRBD+2(R1) ;Copy the start address for the user MOV R4,F.NRBD(R1) ; and its length MOV R2,F.BPTR(R1) ;Save the new buffer pointer, ; Good RETURN to caller TST (PC)+ ;Indicate success ; Bad RETURN to caller 90$: SEC ;Indicate failure RETURN .END