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