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