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.2 (Berkeley) 10/30/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 decl N 65 decl COUNT 66 jleq 1f 67 cmpb r0,$NL /* If it was a newline, we're done */ 68 jneq 2f 691: 70 clrb (S) 71 jbr Lret 722: 73 tstl _BASE(IPTR) /* Is the input buffered? */ 74 jeql Lloop /* If not, loop inefficiently */ 75 76 /* 77 * Look for a newline in the buffer. 78 */ 79Lscan: 80 cmpl _CNT(IPTR),COUNT /* Is buffer bigger than N-1? */ 81 jgeq 1f 82 movl _CNT(IPTR),COUNT /* If not, don't read off the end */ 831: 84 locc $NL,COUNT,*_PTR(IPTR) /* Scan the buffer */ 85 jeql Lagain 86 87 /* 88 * Success -- copy the data and return. 89 */ 90 decl r0 /* How many characters did we read? */ 91 subl2 r0,COUNT 92 movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ 93 clrb (r3) 94 subl2 COUNT,_CNT(IPTR) /* Fix up the I/O buffer */ 95 movl r1,_PTR(IPTR) 96 97Lret: 98 movl OLD_S,r0 99 ret 100 101 /* 102 * If we run out of characters, copy the buffer and loop if needed. 103 */ 104Lagain: 105 movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ 106 subl2 COUNT,_CNT(IPTR) /* Adjust the buffers and counts */ 107 movl r1,_PTR(IPTR) 108 subl2 COUNT,N 109 movl r3,S 110 subl3 $1,N,COUNT 111 jgtr Lloop 112 113 /* 114 * End of file? Check to see if we copied any data. 115 */ 116Leof: 117 cmpl S,OLD_S 118 jeql Lerror 119 clrb (S) 120 jbr Lret 121 122 /* 123 * Error return -- null pointer. 124 */ 125Lerror: 126 clrl r0 127 ret 128