Blob


1 #include <limits.h>
2 #include "rc.h"
3 #include "exec.h"
4 #include "io.h"
5 #include "fns.h"
6 int pfmtnest = 0;
8 void
9 pfmt(io *f, char *fmt, ...)
10 {
11 va_list ap;
12 char err[ERRMAX];
13 va_start(ap, fmt);
14 pfmtnest++;
15 for(;*fmt;fmt++)
16 if(*fmt!='%')
17 pchr(f, *fmt);
18 else switch(*++fmt){
19 case '\0':
20 va_end(ap);
21 return;
22 case 'c':
23 pchr(f, va_arg(ap, int));
24 break;
25 case 'd':
26 pdec(f, va_arg(ap, int));
27 break;
28 case 'o':
29 poct(f, va_arg(ap, unsigned));
30 break;
31 case 'p':
32 pptr(f, va_arg(ap, void*));
33 break;
34 case 'Q':
35 pquo(f, va_arg(ap, char *));
36 break;
37 case 'q':
38 pwrd(f, va_arg(ap, char *));
39 break;
40 case 'r':
41 rerrstr(err, sizeof err); pstr(f, err);
42 break;
43 case 's':
44 pstr(f, va_arg(ap, char *));
45 break;
46 case 't':
47 pcmd(f, va_arg(ap, struct tree *));
48 break;
49 case 'v':
50 pval(f, va_arg(ap, struct word *));
51 break;
52 default:
53 pchr(f, *fmt);
54 break;
55 }
56 va_end(ap);
57 if(--pfmtnest==0)
58 flush(f);
59 }
61 void
62 pchr(io *b, int c)
63 {
64 if(b->bufp==b->ebuf)
65 fullbuf(b, c);
66 else *b->bufp++=c;
67 }
69 int
70 rchr(io *b)
71 {
72 if(b->bufp==b->ebuf)
73 return emptybuf(b);
74 return *b->bufp++ & 0xFF;
75 }
77 void
78 pquo(io *f, char *s)
79 {
80 pchr(f, '\'');
81 for(;*s;s++)
82 if(*s=='\'')
83 pfmt(f, "''");
84 else pchr(f, *s);
85 pchr(f, '\'');
86 }
88 void
89 pwrd(io *f, char *s)
90 {
91 char *t;
92 for(t = s;*t;t++) if(!wordchr(*t)) break;
93 if(t==s || *t)
94 pquo(f, s);
95 else pstr(f, s);
96 }
98 void
99 pptr(io *f, void *v)
101 int n;
102 uintptr p;
104 p = (uintptr)v;
105 if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
106 for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
108 for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
111 void
112 pstr(io *f, char *s)
114 if(s==0)
115 s="(null)";
116 while(*s) pchr(f, *s++);
119 void
120 pdec(io *f, int n)
122 if(n<0){
123 if(n!=INT_MIN){
124 pchr(f, '-');
125 pdec(f, -n);
126 return;
128 /* n is two's complement minimum integer */
129 n = -(INT_MIN+1);
130 pchr(f, '-');
131 pdec(f, n/10);
132 pchr(f, n%10+'1');
133 return;
135 if(n>9)
136 pdec(f, n/10);
137 pchr(f, n%10+'0');
140 void
141 poct(io *f, unsigned n)
143 if(n>7)
144 poct(f, n>>3);
145 pchr(f, (n&7)+'0');
148 void
149 pval(io *f, word *a)
151 if(a){
152 while(a->next && a->next->word){
153 pwrd(f, a->word);
154 pchr(f, ' ');
155 a = a->next;
157 pwrd(f, a->word);
161 int
162 fullbuf(io *f, int c)
164 flush(f);
165 return *f->bufp++=c;
168 void
169 flush(io *f)
171 int n;
172 char *s;
173 if(f->strp){
174 n = f->ebuf-f->strp;
175 f->strp = realloc(f->strp, n+101);
176 if(f->strp==0)
177 panic("Can't realloc %d bytes in flush!", n+101);
178 f->bufp = f->strp+n;
179 f->ebuf = f->bufp+100;
180 for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
182 else{
183 n = f->bufp-f->buf;
184 if(n && Write(f->fd, f->buf, n) < 0){
185 Write(3, "Write error\n", 12);
186 if(ntrap)
187 dotrap();
189 f->bufp = f->buf;
190 f->ebuf = f->buf+NBUF;
194 io*
195 openfd(int fd)
197 io *f = new(struct io);
198 f->fd = fd;
199 f->bufp = f->ebuf = f->buf;
200 f->strp = 0;
201 return f;
204 io*
205 openstr(void)
207 io *f = new(struct io);
208 char *s;
209 f->fd=-1;
210 f->bufp = f->strp = emalloc(101);
211 f->ebuf = f->bufp+100;
212 for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
213 return f;
215 /*
216 * Open a corebuffer to read. EOF occurs after reading len
217 * characters from buf.
218 */
220 io*
221 opencore(char *s, int len)
223 io *f = new(struct io);
224 char *buf = emalloc(len);
225 f->fd= -1 /*open("/dev/null", 0)*/;
226 f->bufp = f->strp = buf;
227 f->ebuf = buf+len;
228 Memcpy(buf, s, len);
229 return f;
232 void
233 iorewind(io *io)
235 if(io->fd==-1)
236 io->bufp = io->strp;
237 else{
238 io->bufp = io->ebuf = io->buf;
239 Seek(io->fd, 0L, 0);
243 void
244 closeio(io *io)
246 if(io->fd>=0)
247 close(io->fd);
248 if(io->strp)
249 efree(io->strp);
250 efree((char *)io);
253 int
254 emptybuf(io *f)
256 int n;
257 if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
258 f->bufp = f->buf;
259 f->ebuf = f->buf+n;
260 return *f->bufp++&0xff;