/* * Copyright (c) 1985 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that: (1) source distributions retain this entire copyright * notice and comment, and (2) distributions including binaries display * the following acknowledgement: ``This product includes software * developed by the University of California, Berkeley and its contributors'' * in the documentation or other materials provided with the distribution * and in all advertising materials mentioning features or use of this * software. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #if defined(LIBC_SCCS) && !defined(lint) .asciz "@(#)fgets.s 5.6 (Berkeley) 6/1/90" #endif /* LIBC_SCCS and not lint */ /* * char *fgets(s, n, iptr); * char *s; * int n; * FILE *iptr; * * arguments: a target string, a length, and a file pointer. * side effects: reads up to and including a newline, or up to n-1 bytes, * whichever is less, from the file indicated by iptr into the target * string and null terminates. * result: the target string if successful, 0 otherwise. */ #include "DEFS.h" #define NL 0xa ENTRY(fgets, R11|R10|R9) #define OLD_S 4(ap) #define S r11 movl OLD_S,S #define N 8(ap) #define IPTR r10 #define _CNT #define _PTR 4 #define _BASE 8 movl 12(ap),IPTR #define COUNT r9 /* * Sanity check -- is the buffer big enough? */ cmpl N,$1 jleq Lerror subl3 $1,N,COUNT /* We scan at most COUNT chars */ /* * If no characters, call _filbuf() to get some. */ tstl _CNT(IPTR) jgtr Lscan Lloop: pushl IPTR calls $1,__filbuf tstl r0 jlss Leof movb r0,(S)+ /* Save the returned character */ decl N decl COUNT jleq 1f cmpb r0,$NL /* If it was a newline, we're done */ jneq 2f 1: clrb (S) jbr Lret 2: tstl _BASE(IPTR) /* Is the input buffered? */ jeql Lloop /* If not, loop inefficiently */ /* * Look for a newline in the buffer. */ Lscan: cmpl _CNT(IPTR),COUNT /* Is buffer bigger than N-1? */ jgeq 1f movl _CNT(IPTR),COUNT /* If not, don't read off the end */ 1: locc $NL,COUNT,*_PTR(IPTR) /* Scan the buffer */ jeql Lagain /* * Success -- copy the data and return. */ decl r0 /* How many characters did we read? */ subl2 r0,COUNT movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ clrb (r3) subl2 COUNT,_CNT(IPTR) /* Fix up the I/O buffer */ movl r1,_PTR(IPTR) Lret: movl OLD_S,r0 ret /* * If we run out of characters, copy the buffer and loop if needed. */ Lagain: movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ subl2 COUNT,_CNT(IPTR) /* Adjust the buffers and counts */ movl r1,_PTR(IPTR) subl2 COUNT,N movl r3,S subl3 $1,N,COUNT jgtr Lloop /* * End of file? Check to see if we copied any data. */ Leof: cmpl S,OLD_S jeql Lerror clrb (S) jbr Lret /* * Error return -- null pointer. */ Lerror: clrl r0 ret