124421Smckusick/* 224421Smckusick * Copyright (c) 1985 Regents of the University of California. 334435Sbostic * All rights reserved. 434435Sbostic * 5*42637Sbostic * %sccs.include.redist.c% 624421Smckusick */ 724421Smckusick 834826Sbostic#if defined(LIBC_SCCS) && !defined(lint) 9*42637Sbostic .asciz "@(#)fgets.s 5.6 (Berkeley) 06/01/90" 1034826Sbostic#endif /* LIBC_SCCS and not lint */ 1124421Smckusick 1224421Smckusick/* 1324421Smckusick * char *fgets(s, n, iptr); 1424421Smckusick * char *s; 1524421Smckusick * int n; 1624421Smckusick * FILE *iptr; 1724421Smckusick * 1824421Smckusick * arguments: a target string, a length, and a file pointer. 1924421Smckusick * side effects: reads up to and including a newline, or up to n-1 bytes, 2024421Smckusick * whichever is less, from the file indicated by iptr into the target 2124421Smckusick * string and null terminates. 2224421Smckusick * result: the target string if successful, 0 otherwise. 2324421Smckusick */ 2424421Smckusick 2524421Smckusick#include "DEFS.h" 2624421Smckusick 2724421Smckusick#define NL 0xa 2824421Smckusick 2924421SmckusickENTRY(fgets, R11|R10|R9) 3024421Smckusick 3124421Smckusick#define OLD_S 4(ap) 3224421Smckusick#define S r11 3324421Smckusick movl OLD_S,S 3424421Smckusick 3524421Smckusick#define N 8(ap) 3624421Smckusick 3724421Smckusick#define IPTR r10 3824421Smckusick#define _CNT 3924421Smckusick#define _PTR 4 4024421Smckusick#define _BASE 8 4124421Smckusick movl 12(ap),IPTR 4224421Smckusick 4324421Smckusick#define COUNT r9 4424421Smckusick 4524421Smckusick /* 4624421Smckusick * Sanity check -- is the buffer big enough? 4724421Smckusick */ 4824421Smckusick cmpl N,$1 4924421Smckusick jleq Lerror 5024421Smckusick 5124421Smckusick subl3 $1,N,COUNT /* We scan at most COUNT chars */ 5224421Smckusick 5324421Smckusick /* 5424421Smckusick * If no characters, call _filbuf() to get some. 5524421Smckusick */ 5624421Smckusick tstl _CNT(IPTR) 5724421Smckusick jgtr Lscan 5824421Smckusick 5924421SmckusickLloop: 6024421Smckusick pushl IPTR 6124421Smckusick calls $1,__filbuf 6224421Smckusick tstl r0 6324421Smckusick jlss Leof 6424421Smckusick movb r0,(S)+ /* Save the returned character */ 6525339Smckusick decl N 6625339Smckusick decl COUNT 6725339Smckusick jleq 1f 6824421Smckusick cmpb r0,$NL /* If it was a newline, we're done */ 6925339Smckusick jneq 2f 7025339Smckusick1: 7124421Smckusick clrb (S) 7224421Smckusick jbr Lret 7325339Smckusick2: 7424421Smckusick tstl _BASE(IPTR) /* Is the input buffered? */ 7524421Smckusick jeql Lloop /* If not, loop inefficiently */ 7624421Smckusick 7724421Smckusick /* 7824421Smckusick * Look for a newline in the buffer. 7924421Smckusick */ 8024421SmckusickLscan: 8124421Smckusick cmpl _CNT(IPTR),COUNT /* Is buffer bigger than N-1? */ 8224421Smckusick jgeq 1f 8324421Smckusick movl _CNT(IPTR),COUNT /* If not, don't read off the end */ 8424421Smckusick1: 8524421Smckusick locc $NL,COUNT,*_PTR(IPTR) /* Scan the buffer */ 8624421Smckusick jeql Lagain 8724421Smckusick 8824421Smckusick /* 8924421Smckusick * Success -- copy the data and return. 9024421Smckusick */ 9124421Smckusick decl r0 /* How many characters did we read? */ 9224421Smckusick subl2 r0,COUNT 9324421Smckusick movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ 9424421Smckusick clrb (r3) 9524421Smckusick subl2 COUNT,_CNT(IPTR) /* Fix up the I/O buffer */ 9624421Smckusick movl r1,_PTR(IPTR) 9724421Smckusick 9824421SmckusickLret: 9924421Smckusick movl OLD_S,r0 10024421Smckusick ret 10124421Smckusick 10224421Smckusick /* 10324421Smckusick * If we run out of characters, copy the buffer and loop if needed. 10424421Smckusick */ 10524421SmckusickLagain: 10624421Smckusick movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ 10724421Smckusick subl2 COUNT,_CNT(IPTR) /* Adjust the buffers and counts */ 10824421Smckusick movl r1,_PTR(IPTR) 10924421Smckusick subl2 COUNT,N 11024421Smckusick movl r3,S 11124421Smckusick subl3 $1,N,COUNT 11224421Smckusick jgtr Lloop 11324421Smckusick 11424421Smckusick /* 11524421Smckusick * End of file? Check to see if we copied any data. 11624421Smckusick */ 11724421SmckusickLeof: 11824421Smckusick cmpl S,OLD_S 11924421Smckusick jeql Lerror 12024421Smckusick clrb (S) 12124421Smckusick jbr Lret 12224421Smckusick 12324421Smckusick /* 12424421Smckusick * Error return -- null pointer. 12524421Smckusick */ 12624421SmckusickLerror: 12724421Smckusick clrl r0 12824421Smckusick ret 129