Commit | Line | Data |
---|---|---|
67c6d82f KM |
1 | /* |
2 | * Copyright (c) 1985 Regents of the University of California. | |
2c817985 KB |
3 | * All rights reserved. |
4 | * | |
019bea33 | 5 | * %sccs.include.redist.c% |
67c6d82f KM |
6 | */ |
7 | ||
4afb9d15 | 8 | #if defined(LIBC_SCCS) && !defined(lint) |
019bea33 | 9 | .asciz "@(#)fputs.s 5.7 (Berkeley) %G%" |
4afb9d15 | 10 | #endif /* LIBC_SCCS and not lint */ |
67c6d82f KM |
11 | |
12 | /* | |
13 | * fputs(s, iop); | |
14 | * char *s; | |
15 | * FILE *iop; | |
16 | * | |
17 | * arguments: a source string and a file pointer. | |
18 | * side effects: writes to the file indicated by iop using the data in | |
19 | * the null-terminated source string. | |
20 | * result: technically void; for compatibility we return 0 for the null | |
21 | * string, non-zero otherwise. We return zero for errors too. | |
22 | */ | |
23 | ||
24 | #include "DEFS.h" | |
25 | ||
26 | #define NBF 04 | |
27 | #define LBF 0200 | |
28 | ||
29 | #define NL 012 | |
30 | ||
31 | ENTRY(fputs, R11|R10|R9) | |
32 | ||
33 | #define S r11 | |
34 | movl 4(ap),S | |
35 | #define IOP r10 | |
36 | #define _CNT | |
37 | #define _PTR 4 | |
38 | #define _BASE 8 | |
39 | #define _BUFSIZ 12 | |
40 | #define _FLAG 16 | |
41 | movl 8(ap),IOP | |
42 | ||
43 | #define UNBUF -4(fp) | |
44 | ||
45 | #define COUNT r9 | |
46 | ||
47 | /* | |
48 | * For compatibility (sigh). | |
49 | */ | |
50 | tstb (S) | |
51 | jeql Lerror | |
52 | ||
53 | /* | |
54 | * For unbuffered I/O, line buffer the output line. | |
55 | * Ugly but fast -- and doesn't CURRENTLY break anything (sigh). | |
56 | */ | |
57 | movab -1028(sp),sp | |
58 | bicw3 $~NBF,_FLAG(IOP),UNBUF | |
59 | jeql 1f | |
60 | ||
61 | bicw2 $NBF,_FLAG(IOP) /* Clear no-buffering flag */ | |
62 | movl sp,_BASE(IOP) /* Create a buffer */ | |
63 | movl sp,_PTR(IOP) | |
64 | cvtwl $1024,_BUFSIZ(IOP) | |
65 | jbr 2f | |
66 | ||
67 | 1: | |
3a8b31bb DS |
68 | tstl _CNT(IOP) /* Has a buffer been allocated? */ |
69 | jgtr 2f | |
67c6d82f KM |
70 | pushl IOP /* Get _flsbuf() to do the work */ |
71 | pushl $0 | |
72 | calls $2,__flsbuf | |
73 | tstl r0 | |
74 | jlss Lerror | |
75 | incl _CNT(IOP) /* Unput the char we sent */ | |
76 | decl _PTR(IOP) | |
77 | 2: | |
78 | ||
79 | /* | |
80 | * Search for the terminating null. | |
81 | * We only need to look at _BUFSIZ bytes or less on each pass. | |
82 | */ | |
83 | Lloop: | |
84 | addl3 _BASE(IOP),_BUFSIZ(IOP),COUNT /* How many bytes? */ | |
85 | subl2 _PTR(IOP),COUNT | |
86 | locc $0,COUNT,(S) /* Look for a null */ | |
87 | jeql Lagain | |
88 | ||
89 | subl2 r0,COUNT /* Copy the data */ | |
90 | movc3 COUNT,(S),*_PTR(IOP) | |
91 | movl r3,_PTR(IOP) /* Fix up IOP */ | |
92 | subl2 COUNT,_CNT(IOP) | |
93 | bitw $LBF,_FLAG(IOP) /* If line buffered... */ | |
94 | jneq 1f | |
38dd0e83 JB |
95 | tstw UNBUF /* or unbuffered... */ |
96 | jneq 1f | |
67c6d82f KM |
97 | tstl _CNT(IOP) /* or a full buffer... */ |
98 | jgtr 2f | |
99 | 1: | |
100 | pushl IOP /* ... flush the buffer */ | |
101 | calls $1,_fflush | |
102 | tstl r0 | |
103 | jlss Lerror | |
104 | 2: | |
105 | ||
106 | /* | |
107 | * Fix up buffering again. | |
108 | */ | |
109 | Lfixup: | |
110 | tstw UNBUF | |
111 | jeql 1f | |
112 | bisw2 $NBF,_FLAG(IOP) /* Reset flag */ | |
113 | clrl _BASE(IOP) /* Clear data structure */ | |
114 | clrl _BUFSIZ(IOP) | |
115 | clrl _CNT(IOP) | |
116 | 1: | |
117 | cvtbl $NL,r0 /* Compatibility hack */ | |
118 | ret | |
119 | ||
120 | /* | |
121 | * We didn't find the null -- loop. | |
122 | */ | |
123 | Lagain: | |
124 | movc3 COUNT,(S),*_PTR(IOP) /* Copy the data */ | |
125 | movl r1,S | |
126 | movl r3,_PTR(IOP) /* Fix up IOP */ | |
127 | subl2 COUNT,_CNT(IOP) | |
128 | pushl IOP /* The buffer is full -- flush it */ | |
129 | calls $1,_fflush | |
130 | tstl r0 | |
131 | jlss Lerror | |
132 | tstb (S) /* More data? */ | |
133 | jneq Lloop | |
134 | jbr Lfixup | |
135 | ||
136 | /* | |
137 | * Bomb out. Return 0 (why not? that's what the old one did). | |
138 | */ | |
139 | Lerror: | |
140 | clrl r0 | |
141 | ret |