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