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