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