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