|
|
1.1 root 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: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #if defined(LIBC_SCCS) && !defined(lint)
21: .asciz "@(#)fgets.s 5.6 (Berkeley) 6/1/90"
22: #endif /* LIBC_SCCS and not lint */
23:
24: /*
25: * char *fgets(s, n, iptr);
26: * char *s;
27: * int n;
28: * FILE *iptr;
29: *
30: * arguments: a target string, a length, and a file pointer.
31: * side effects: reads up to and including a newline, or up to n-1 bytes,
32: * whichever is less, from the file indicated by iptr into the target
33: * string and null terminates.
34: * result: the target string if successful, 0 otherwise.
35: */
36:
37: #include "DEFS.h"
38:
39: #define NL 0xa
40:
41: ENTRY(fgets, R11|R10|R9)
42:
43: #define OLD_S 4(ap)
44: #define S r11
45: movl OLD_S,S
46:
47: #define N 8(ap)
48:
49: #define IPTR r10
50: #define _CNT
51: #define _PTR 4
52: #define _BASE 8
53: movl 12(ap),IPTR
54:
55: #define COUNT r9
56:
57: /*
58: * Sanity check -- is the buffer big enough?
59: */
60: cmpl N,$1
61: jleq Lerror
62:
63: subl3 $1,N,COUNT /* We scan at most COUNT chars */
64:
65: /*
66: * If no characters, call _filbuf() to get some.
67: */
68: tstl _CNT(IPTR)
69: jgtr Lscan
70:
71: Lloop:
72: pushl IPTR
73: calls $1,__filbuf
74: tstl r0
75: jlss Leof
76: movb r0,(S)+ /* Save the returned character */
77: decl N
78: decl COUNT
79: jleq 1f
80: cmpb r0,$NL /* If it was a newline, we're done */
81: jneq 2f
82: 1:
83: clrb (S)
84: jbr Lret
85: 2:
86: tstl _BASE(IPTR) /* Is the input buffered? */
87: jeql Lloop /* If not, loop inefficiently */
88:
89: /*
90: * Look for a newline in the buffer.
91: */
92: Lscan:
93: cmpl _CNT(IPTR),COUNT /* Is buffer bigger than N-1? */
94: jgeq 1f
95: movl _CNT(IPTR),COUNT /* If not, don't read off the end */
96: 1:
97: locc $NL,COUNT,*_PTR(IPTR) /* Scan the buffer */
98: jeql Lagain
99:
100: /*
101: * Success -- copy the data and return.
102: */
103: decl r0 /* How many characters did we read? */
104: subl2 r0,COUNT
105: movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */
106: clrb (r3)
107: subl2 COUNT,_CNT(IPTR) /* Fix up the I/O buffer */
108: movl r1,_PTR(IPTR)
109:
110: Lret:
111: movl OLD_S,r0
112: ret
113:
114: /*
115: * If we run out of characters, copy the buffer and loop if needed.
116: */
117: Lagain:
118: movc3 COUNT,*_PTR(IPTR),(S) /* Copy the data */
119: subl2 COUNT,_CNT(IPTR) /* Adjust the buffers and counts */
120: movl r1,_PTR(IPTR)
121: subl2 COUNT,N
122: movl r3,S
123: subl3 $1,N,COUNT
124: jgtr Lloop
125:
126: /*
127: * End of file? Check to see if we copied any data.
128: */
129: Leof:
130: cmpl S,OLD_S
131: jeql Lerror
132: clrb (S)
133: jbr Lret
134:
135: /*
136: * Error return -- null pointer.
137: */
138: Lerror:
139: clrl r0
140: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.