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