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