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