xref: /csrg-svn/lib/libc/vax/stdio.old/fgets.s (revision 42637)
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