124421Smckusick/* 224421Smckusick * Copyright (c) 1985 Regents of the University of California. 3*34435Sbostic * All rights reserved. 4*34435Sbostic * 5*34435Sbostic * Redistribution and use in source and binary forms are permitted 6*34435Sbostic * provided that this notice is preserved and that due credit is given 7*34435Sbostic * to the University of California at Berkeley. The name of the University 8*34435Sbostic * may not be used to endorse or promote products derived from this 9*34435Sbostic * software without specific written prior permission. This software 10*34435Sbostic * is provided ``as is'' without express or implied warranty. 1124421Smckusick */ 1224421Smckusick 1326695Sdonn#ifdef LIBC_SCCS 14*34435Sbostic_sccsid:.asciz "@(#)fgets.s 5.4 (Berkeley) 05/23/88" 15*34435Sbostic#endif /* LIBC_SCCS */ 1624421Smckusick 1724421Smckusick/* 1824421Smckusick * char *fgets(s, n, iptr); 1924421Smckusick * char *s; 2024421Smckusick * int n; 2124421Smckusick * FILE *iptr; 2224421Smckusick * 2324421Smckusick * arguments: a target string, a length, and a file pointer. 2424421Smckusick * side effects: reads up to and including a newline, or up to n-1 bytes, 2524421Smckusick * whichever is less, from the file indicated by iptr into the target 2624421Smckusick * string and null terminates. 2724421Smckusick * result: the target string if successful, 0 otherwise. 2824421Smckusick */ 2924421Smckusick 3024421Smckusick#include "DEFS.h" 3124421Smckusick 3224421Smckusick#define NL 0xa 3324421Smckusick 3424421SmckusickENTRY(fgets, R11|R10|R9) 3524421Smckusick 3624421Smckusick#define OLD_S 4(ap) 3724421Smckusick#define S r11 3824421Smckusick movl OLD_S,S 3924421Smckusick 4024421Smckusick#define N 8(ap) 4124421Smckusick 4224421Smckusick#define IPTR r10 4324421Smckusick#define _CNT 4424421Smckusick#define _PTR 4 4524421Smckusick#define _BASE 8 4624421Smckusick movl 12(ap),IPTR 4724421Smckusick 4824421Smckusick#define COUNT r9 4924421Smckusick 5024421Smckusick /* 5124421Smckusick * Sanity check -- is the buffer big enough? 5224421Smckusick */ 5324421Smckusick cmpl N,$1 5424421Smckusick jleq Lerror 5524421Smckusick 5624421Smckusick subl3 $1,N,COUNT /* We scan at most COUNT chars */ 5724421Smckusick 5824421Smckusick /* 5924421Smckusick * If no characters, call _filbuf() to get some. 6024421Smckusick */ 6124421Smckusick tstl _CNT(IPTR) 6224421Smckusick jgtr Lscan 6324421Smckusick 6424421SmckusickLloop: 6524421Smckusick pushl IPTR 6624421Smckusick calls $1,__filbuf 6724421Smckusick tstl r0 6824421Smckusick jlss Leof 6924421Smckusick movb r0,(S)+ /* Save the returned character */ 7025339Smckusick decl N 7125339Smckusick decl COUNT 7225339Smckusick jleq 1f 7324421Smckusick cmpb r0,$NL /* If it was a newline, we're done */ 7425339Smckusick jneq 2f 7525339Smckusick1: 7624421Smckusick clrb (S) 7724421Smckusick jbr Lret 7825339Smckusick2: 7924421Smckusick tstl _BASE(IPTR) /* Is the input buffered? */ 8024421Smckusick jeql Lloop /* If not, loop inefficiently */ 8124421Smckusick 8224421Smckusick /* 8324421Smckusick * Look for a newline in the buffer. 8424421Smckusick */ 8524421SmckusickLscan: 8624421Smckusick cmpl _CNT(IPTR),COUNT /* Is buffer bigger than N-1? */ 8724421Smckusick jgeq 1f 8824421Smckusick movl _CNT(IPTR),COUNT /* If not, don't read off the end */ 8924421Smckusick1: 9024421Smckusick locc $NL,COUNT,*_PTR(IPTR) /* Scan the buffer */ 9124421Smckusick jeql Lagain 9224421Smckusick 9324421Smckusick /* 9424421Smckusick * Success -- copy the data and return. 9524421Smckusick */ 9624421Smckusick decl r0 /* How many characters did we read? */ 9724421Smckusick subl2 r0,COUNT 9824421Smckusick movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ 9924421Smckusick clrb (r3) 10024421Smckusick subl2 COUNT,_CNT(IPTR) /* Fix up the I/O buffer */ 10124421Smckusick movl r1,_PTR(IPTR) 10224421Smckusick 10324421SmckusickLret: 10424421Smckusick movl OLD_S,r0 10524421Smckusick ret 10624421Smckusick 10724421Smckusick /* 10824421Smckusick * If we run out of characters, copy the buffer and loop if needed. 10924421Smckusick */ 11024421SmckusickLagain: 11124421Smckusick movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */ 11224421Smckusick subl2 COUNT,_CNT(IPTR) /* Adjust the buffers and counts */ 11324421Smckusick movl r1,_PTR(IPTR) 11424421Smckusick subl2 COUNT,N 11524421Smckusick movl r3,S 11624421Smckusick subl3 $1,N,COUNT 11724421Smckusick jgtr Lloop 11824421Smckusick 11924421Smckusick /* 12024421Smckusick * End of file? Check to see if we copied any data. 12124421Smckusick */ 12224421SmckusickLeof: 12324421Smckusick cmpl S,OLD_S 12424421Smckusick jeql Lerror 12524421Smckusick clrb (S) 12624421Smckusick jbr Lret 12724421Smckusick 12824421Smckusick /* 12924421Smckusick * Error return -- null pointer. 13024421Smckusick */ 13124421SmckusickLerror: 13224421Smckusick clrl r0 13324421Smckusick ret 134