xref: /csrg-svn/lib/libc/vax/stdio.old/fgets.s (revision 24421)
1*24421Smckusick/*
2*24421Smckusick * Copyright (c) 1985 Regents of the University of California.
3*24421Smckusick * All rights reserved.  The Berkeley software License Agreement
4*24421Smckusick * specifies the terms and conditions for redistribution.
5*24421Smckusick */
6*24421Smckusick
7*24421Smckusick#ifndef lint
8*24421Smckusick_sccsid:.asciz	"@(#)fgets.s	5.1 (Berkeley) 08/23/85"
9*24421Smckusick#endif not lint
10*24421Smckusick
11*24421Smckusick/*
12*24421Smckusick * char *fgets(s, n, iptr);
13*24421Smckusick * char *s;
14*24421Smckusick * int n;
15*24421Smckusick * FILE *iptr;
16*24421Smckusick *
17*24421Smckusick * arguments: a target string, a length, and a file pointer.
18*24421Smckusick * side effects: reads up to and including a newline, or up to n-1 bytes,
19*24421Smckusick *	whichever is less, from the file indicated by iptr into the target
20*24421Smckusick *	string and null terminates.
21*24421Smckusick * result: the target string if successful, 0 otherwise.
22*24421Smckusick */
23*24421Smckusick
24*24421Smckusick#include "DEFS.h"
25*24421Smckusick
26*24421Smckusick#define		NL	0xa
27*24421Smckusick
28*24421SmckusickENTRY(fgets, R11|R10|R9)
29*24421Smckusick
30*24421Smckusick#define		OLD_S	4(ap)
31*24421Smckusick#define		S	r11
32*24421Smckusick	movl	OLD_S,S
33*24421Smckusick
34*24421Smckusick#define		N	8(ap)
35*24421Smckusick
36*24421Smckusick#define		IPTR	r10
37*24421Smckusick#define		_CNT
38*24421Smckusick#define		_PTR	4
39*24421Smckusick#define		_BASE	8
40*24421Smckusick	movl	12(ap),IPTR
41*24421Smckusick
42*24421Smckusick#define		COUNT	r9
43*24421Smckusick
44*24421Smckusick	/*
45*24421Smckusick	 * Sanity check -- is the buffer big enough?
46*24421Smckusick	 */
47*24421Smckusick	cmpl	N,$1
48*24421Smckusick	jleq	Lerror
49*24421Smckusick
50*24421Smckusick	subl3	$1,N,COUNT		/* We scan at most COUNT chars */
51*24421Smckusick
52*24421Smckusick	/*
53*24421Smckusick	 * If no characters, call _filbuf() to get some.
54*24421Smckusick	 */
55*24421Smckusick	tstl	_CNT(IPTR)
56*24421Smckusick	jgtr	Lscan
57*24421Smckusick
58*24421SmckusickLloop:
59*24421Smckusick	pushl	IPTR
60*24421Smckusick	calls	$1,__filbuf
61*24421Smckusick	tstl	r0
62*24421Smckusick	jlss	Leof
63*24421Smckusick	movb	r0,(S)+			/* Save the returned character */
64*24421Smckusick	cmpb	r0,$NL			/* If it was a newline, we're done */
65*24421Smckusick	jneq	1f
66*24421Smckusick	clrb	(S)
67*24421Smckusick	jbr	Lret
68*24421Smckusick1:
69*24421Smckusick	tstl	_BASE(IPTR)		/* Is the input buffered? */
70*24421Smckusick	jeql	Lloop			/* If not, loop inefficiently */
71*24421Smckusick
72*24421Smckusick	/*
73*24421Smckusick	 * Look for a newline in the buffer.
74*24421Smckusick	 */
75*24421SmckusickLscan:
76*24421Smckusick	cmpl	_CNT(IPTR),COUNT	/* Is buffer bigger than N-1? */
77*24421Smckusick	jgeq	1f
78*24421Smckusick	movl	_CNT(IPTR),COUNT	/* If not, don't read off the end */
79*24421Smckusick1:
80*24421Smckusick	locc	$NL,COUNT,*_PTR(IPTR)	/* Scan the buffer */
81*24421Smckusick	jeql	Lagain
82*24421Smckusick
83*24421Smckusick	/*
84*24421Smckusick	 * Success -- copy the data and return.
85*24421Smckusick	 */
86*24421Smckusick	decl	r0			/* How many characters did we read? */
87*24421Smckusick	subl2	r0,COUNT
88*24421Smckusick	movc3	COUNT,*_PTR(IPTR),(S)	/* Copy the data */
89*24421Smckusick	clrb	(r3)
90*24421Smckusick	subl2	COUNT,_CNT(IPTR)	/* Fix up the I/O buffer */
91*24421Smckusick	movl	r1,_PTR(IPTR)
92*24421Smckusick
93*24421SmckusickLret:
94*24421Smckusick	movl	OLD_S,r0
95*24421Smckusick	ret
96*24421Smckusick
97*24421Smckusick	/*
98*24421Smckusick	 * If we run out of characters, copy the buffer and loop if needed.
99*24421Smckusick	 */
100*24421SmckusickLagain:
101*24421Smckusick	movc3	COUNT,*_PTR(IPTR),(S)	/* Copy the data */
102*24421Smckusick	subl2	COUNT,_CNT(IPTR)	/* Adjust the buffers and counts */
103*24421Smckusick	movl	r1,_PTR(IPTR)
104*24421Smckusick	subl2	COUNT,N
105*24421Smckusick	movl	r3,S
106*24421Smckusick	subl3	$1,N,COUNT
107*24421Smckusick	jgtr	Lloop
108*24421Smckusick
109*24421Smckusick	/*
110*24421Smckusick	 * End of file?  Check to see if we copied any data.
111*24421Smckusick	 */
112*24421SmckusickLeof:
113*24421Smckusick	cmpl	S,OLD_S
114*24421Smckusick	jeql	Lerror
115*24421Smckusick	clrb	(S)
116*24421Smckusick	jbr	Lret
117*24421Smckusick
118*24421Smckusick	/*
119*24421Smckusick	 * Error return -- null pointer.
120*24421Smckusick	 */
121*24421SmckusickLerror:
122*24421Smckusick	clrl	r0
123*24421Smckusick	ret
124