1/* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8#if defined(LIBC_SCCS) && !defined(lint) 9 .asciz "@(#)fgets.s 5.6 (Berkeley) 06/01/90" 10#endif /* LIBC_SCCS and not lint */ 11 12/* 13 * char *fgets(s, n, iptr); 14 * char *s; 15 * int n; 16 * FILE *iptr; 17 * 18 * arguments: a target string, a length, and a file pointer. 19 * side effects: reads up to and including a newline, or up to n-1 bytes, 20 * whichever is less, from the file indicated by iptr into the target 21 * string and null terminates. 22 * result: the target string if successful, 0 otherwise. 23 */ 24 25#include "DEFS.h" 26 27#define NL 0xa 28 29ENTRY(fgets, R11|R10|R9) 30 31#define OLD_S 4(ap) 32#define S r11 33 movl OLD_S,S 34 35#define N 8(ap) 36 37#define IPTR r10 38#define _CNT 39#define _PTR 4 40#define _BASE 8 41 movl 12(ap),IPTR 42 43#define COUNT r9 44 45 /* 46 * Sanity check -- is the buffer big enough? 47 */ 48 cmpl N,$1 49 jleq Lerror 50 51 subl3 $1,N,COUNT /* We scan at most COUNT chars */ 52 53 /* 54 * If no characters, call _filbuf() to get some. 55 */ 56 tstl _CNT(IPTR) 57 jgtr Lscan 58 59Lloop: 60 pushl IPTR 61 calls $1,__filbuf 62 tstl r0 63 jlss Leof 64 movb r0,(S)+ /* Save the returned character */ 65 decl N 66 decl COUNT 67 jleq 1f 68 cmpb r0,$NL /* If it was a newline, we're done */ 69 jneq 2f 701: 71 clrb (S) 72 jbr Lret 732: 74 tstl _BASE(IPTR) /* Is the input buffered? */ 75 jeql Lloop /* If not, loop inefficiently */ 76 77 /* 78 * Look for a newline in the buffer. 79 */ 80Lscan: 81 cmpl _CNT(IPTR),COUNT /* Is buffer bigger than N-1? */ 82 jgeq 1f 83 movl _CNT(IPTR),COUNT /* If not, don't read off the end */ 841: 85 locc $NL,COUNT,*_PTR(IPTR) /* Scan the buffer */ 86 jeql Lagain 87 88 /* 89 * Success -- copy the data and return. 90 */ 91 decl r0 /* How many characters did we read? */ 92 subl2 r0,COUNT 93 movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ 94 clrb (r3) 95 subl2 COUNT,_CNT(IPTR) /* Fix up the I/O buffer */ 96 movl r1,_PTR(IPTR) 97 98Lret: 99 movl OLD_S,r0 100 ret 101 102 /* 103 * If we run out of characters, copy the buffer and loop if needed. 104 */ 105Lagain: 106 movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ 107 subl2 COUNT,_CNT(IPTR) /* Adjust the buffers and counts */ 108 movl r1,_PTR(IPTR) 109 subl2 COUNT,N 110 movl r3,S 111 subl3 $1,N,COUNT 112 jgtr Lloop 113 114 /* 115 * End of file? Check to see if we copied any data. 116 */ 117Leof: 118 cmpl S,OLD_S 119 jeql Lerror 120 clrb (S) 121 jbr Lret 122 123 /* 124 * Error return -- null pointer. 125 */ 126Lerror: 127 clrl r0 128 ret 129