1 #include "rc.h"
2 #include "exec.h"
3 #include "io.h"
4 #include "fns.h"
5
6 enum { Stralloc = 100, };
7
8 int pfmtnest = 0;
9
10 void
pfmt(io * f,char * fmt,...)11 pfmt(io *f, char *fmt, ...)
12 {
13 va_list ap;
14 char err[ERRMAX];
15
16 va_start(ap, fmt);
17 pfmtnest++;
18 for(;*fmt;fmt++) {
19 if(*fmt!='%') {
20 pchr(f, *fmt);
21 continue;
22 }
23 if(*++fmt == '\0') /* "blah%"? */
24 break;
25 switch(*fmt){
26 case 'c':
27 pchr(f, va_arg(ap, int));
28 break;
29 case 'd':
30 pdec(f, va_arg(ap, int));
31 break;
32 case 'o':
33 poct(f, va_arg(ap, unsigned));
34 break;
35 case 'p':
36 pptr(f, va_arg(ap, void*));
37 break;
38 case 'Q':
39 pquo(f, va_arg(ap, char *));
40 break;
41 case 'q':
42 pwrd(f, va_arg(ap, char *));
43 break;
44 case 'r':
45 errstr(err, sizeof err); pstr(f, err);
46 break;
47 case 's':
48 pstr(f, va_arg(ap, char *));
49 break;
50 case 't':
51 pcmd(f, va_arg(ap, struct tree *));
52 break;
53 case 'v':
54 pval(f, va_arg(ap, struct word *));
55 break;
56 default:
57 pchr(f, *fmt);
58 break;
59 }
60 }
61 va_end(ap);
62 if(--pfmtnest==0)
63 flush(f);
64 }
65
66 void
pchr(io * b,int c)67 pchr(io *b, int c)
68 {
69 if(b->bufp==b->ebuf)
70 fullbuf(b, c);
71 else *b->bufp++=c;
72 }
73
74 int
rchr(io * b)75 rchr(io *b)
76 {
77 if(b->bufp==b->ebuf)
78 return emptybuf(b);
79 return *b->bufp++;
80 }
81
82 int
rutf(io * b,char * buf,Rune * r)83 rutf(io *b, char *buf, Rune *r)
84 {
85 int n, i, c;
86
87 c = rchr(b);
88 if(c == EOF)
89 return EOF;
90 *buf = c;
91 if(c < Runesync){
92 *r = c;
93 return 1;
94 }
95 for(i = 1; (c = rchr(b)) != EOF; ){
96 buf[i++] = c;
97 buf[i] = 0;
98 if(fullrune(buf, i)){
99 n = chartorune(r, buf);
100 b->bufp -= i - n; /* push back unconsumed bytes */
101 assert(b->fd == -1 || b->bufp > b->buf);
102 return n;
103 }
104 }
105 /* at eof */
106 b->bufp -= i - 1; /* consume 1 byte */
107 *r = Runeerror;
108 return runetochar(buf, r);
109 }
110
111 void
pquo(io * f,char * s)112 pquo(io *f, char *s)
113 {
114 pchr(f, '\'');
115 for(;*s;s++)
116 if(*s=='\'')
117 pfmt(f, "''");
118 else pchr(f, *s);
119 pchr(f, '\'');
120 }
121
122 void
pwrd(io * f,char * s)123 pwrd(io *f, char *s)
124 {
125 char *t;
126 for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break;
127 if(t==s || *t)
128 pquo(f, s);
129 else pstr(f, s);
130 }
131
132 void
pptr(io * f,void * v)133 pptr(io *f, void *v)
134 {
135 int n;
136 uintptr p;
137
138 p = (uintptr)v;
139 if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
140 for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
141
142 for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
143 }
144
145 void
pstr(io * f,char * s)146 pstr(io *f, char *s)
147 {
148 if(s==0)
149 s="(null)";
150 while(*s) pchr(f, *s++);
151 }
152
153 void
pdec(io * f,int n)154 pdec(io *f, int n)
155 {
156 if(n<0){
157 n=-n;
158 if(n>=0){
159 pchr(f, '-');
160 pdec(f, n);
161 return;
162 }
163 /* n is two's complement minimum integer */
164 n = 1-n;
165 pchr(f, '-');
166 pdec(f, n/10);
167 pchr(f, n%10+'1');
168 return;
169 }
170 if(n>9)
171 pdec(f, n/10);
172 pchr(f, n%10+'0');
173 }
174
175 void
poct(io * f,unsigned n)176 poct(io *f, unsigned n)
177 {
178 if(n>7)
179 poct(f, n>>3);
180 pchr(f, (n&7)+'0');
181 }
182
183 void
pval(io * f,word * a)184 pval(io *f, word *a)
185 {
186 if(a){
187 while(a->next && a->next->word){
188 pwrd(f, (char *)a->word);
189 pchr(f, ' ');
190 a = a->next;
191 }
192 pwrd(f, (char *)a->word);
193 }
194 }
195
196 int
fullbuf(io * f,int c)197 fullbuf(io *f, int c)
198 {
199 flush(f);
200 return *f->bufp++=c;
201 }
202
203 void
flush(io * f)204 flush(io *f)
205 {
206 int n;
207
208 if(f->strp){
209 n = f->ebuf - f->strp;
210 f->strp = realloc(f->strp, n+Stralloc+1);
211 if(f->strp==0)
212 panic("Can't realloc %d bytes in flush!", n+Stralloc+1);
213 f->bufp = f->strp + n;
214 f->ebuf = f->bufp + Stralloc;
215 memset(f->bufp, '\0', Stralloc+1);
216 }
217 else{
218 n = f->bufp-f->buf;
219 if(n && Write(f->fd, f->buf, n) != n){
220 Write(2, "Write error\n", 12);
221 if(ntrap)
222 dotrap();
223 }
224 f->bufp = f->buf;
225 f->ebuf = f->buf+NBUF;
226 }
227 }
228
229 io*
openfd(int fd)230 openfd(int fd)
231 {
232 io *f = new(struct io);
233 f->fd = fd;
234 f->bufp = f->ebuf = f->buf;
235 f->strp = 0;
236 return f;
237 }
238
239 io*
openstr(void)240 openstr(void)
241 {
242 io *f = new(struct io);
243
244 f->fd = -1;
245 f->bufp = f->strp = emalloc(Stralloc+1);
246 f->ebuf = f->bufp + Stralloc;
247 memset(f->bufp, '\0', Stralloc+1);
248 return f;
249 }
250 /*
251 * Open a corebuffer to read. EOF occurs after reading len
252 * characters from buf.
253 */
254
255 io*
opencore(char * s,int len)256 opencore(char *s, int len)
257 {
258 io *f = new(struct io);
259 uchar *buf = emalloc(len);
260
261 f->fd = -1 /*open("/dev/null", 0)*/;
262 f->bufp = f->strp = buf;
263 f->ebuf = buf+len;
264 Memcpy(buf, s, len);
265 return f;
266 }
267
268 void
rewind(io * io)269 rewind(io *io)
270 {
271 if(io->fd==-1)
272 io->bufp = io->strp;
273 else{
274 io->bufp = io->ebuf = io->buf;
275 Seek(io->fd, 0L, 0);
276 }
277 }
278
279 void
closeio(io * io)280 closeio(io *io)
281 {
282 if(io->fd>=0)
283 close(io->fd);
284 if(io->strp)
285 efree(io->strp);
286 efree(io);
287 }
288
289 int
emptybuf(io * f)290 emptybuf(io *f)
291 {
292 int n;
293 if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
294 f->bufp = f->buf;
295 f->ebuf = f->buf + n;
296 return *f->bufp++;
297 }
298