Blob


1 #include <limits.h>
2 #include <errno.h>
3 #include "rc.h"
4 #include "exec.h"
5 #include "io.h"
6 #include "fns.h"
7 int pfmtnest = 0;
9 void
10 pfmt(io *f, char *fmt, ...)
11 {
12 va_list ap;
13 char err[ERRMAX];
14 va_start(ap, fmt);
15 pfmtnest++;
16 for(;*fmt;fmt++)
17 if(*fmt!='%')
18 pchr(f, *fmt);
19 else switch(*++fmt){
20 case '\0':
21 va_end(ap);
22 return;
23 case 'c':
24 pchr(f, va_arg(ap, int));
25 break;
26 case 'd':
27 pdec(f, va_arg(ap, int));
28 break;
29 case 'o':
30 poct(f, va_arg(ap, unsigned));
31 break;
32 case 'p':
33 pptr(f, va_arg(ap, void*));
34 break;
35 case 'Q':
36 pquo(f, va_arg(ap, char *));
37 break;
38 case 'q':
39 pwrd(f, va_arg(ap, char *));
40 break;
41 case 'r':
42 rerrstr(err, sizeof err); pstr(f, err);
43 break;
44 case 's':
45 pstr(f, va_arg(ap, char *));
46 break;
47 case 't':
48 pcmd(f, va_arg(ap, tree *));
49 break;
50 case 'u':
51 pcmdu(f, va_arg(ap, 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 va_end(ap);
61 if(--pfmtnest==0)
62 flush(f);
63 }
65 void
66 pchr(io *b, int c)
67 {
68 if(b->bufp==b->ebuf)
69 fullbuf(b, c);
70 else *b->bufp++=c;
71 }
73 int
74 rchr(io *b)
75 {
76 if(b->bufp==b->ebuf)
77 return emptybuf(b);
78 return *b->bufp++ & 0xFF;
79 }
81 void
82 pquo(io *f, char *s)
83 {
84 pchr(f, '\'');
85 for(;*s;s++)
86 if(*s=='\'')
87 pfmt(f, "''");
88 else pchr(f, *s);
89 pchr(f, '\'');
90 }
92 void
93 pwrd(io *f, char *s)
94 {
95 char *t;
96 for(t = s;*t;t++) if(!wordchr(*t)) break;
97 if(t==s || *t)
98 pquo(f, s);
99 else pstr(f, s);
102 void
103 pptr(io *f, void *v)
105 int n;
106 uintptr p;
108 p = (uintptr)v;
109 if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
110 for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
112 for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
115 void
116 pstr(io *f, char *s)
118 if(s==0)
119 s="(null)";
120 while(*s) pchr(f, *s++);
123 void
124 pdec(io *f, int n)
126 if(n<0){
127 if(n!=INT_MIN){
128 pchr(f, '-');
129 pdec(f, -n);
130 return;
132 /* n is two's complement minimum integer */
133 n = -(INT_MIN+1);
134 pchr(f, '-');
135 pdec(f, n/10);
136 pchr(f, n%10+'1');
137 return;
139 if(n>9)
140 pdec(f, n/10);
141 pchr(f, n%10+'0');
144 void
145 poct(io *f, unsigned n)
147 if(n>7)
148 poct(f, n>>3);
149 pchr(f, (n&7)+'0');
152 void
153 pval(io *f, word *a)
155 if(a){
156 while(a->next && a->next->word){
157 pwrd(f, a->word);
158 pchr(f, ' ');
159 a = a->next;
161 pwrd(f, a->word);
165 int
166 fullbuf(io *f, int c)
168 flush(f);
169 return *f->bufp++=c;
172 void
173 flush(io *f)
175 int n;
176 char *s;
177 if(f->strp){
178 n = f->ebuf-f->strp;
179 f->strp = realloc(f->strp, n+101);
180 if(f->strp==0)
181 panic("Can't realloc %d bytes in flush!", n+101);
182 f->bufp = f->strp+n;
183 f->ebuf = f->bufp+100;
184 for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
186 else{
187 n = f->bufp-f->buf;
188 if(n && Write(f->fd, f->buf, n) < 0){
189 Write(3, "Write error\n", 12);
190 if(ntrap)
191 dotrap();
193 f->bufp = f->buf;
194 f->ebuf = f->buf+NBUF;
198 io*
199 openfd(int fd)
201 io *f = new(struct io);
202 f->fd = fd;
203 f->bufp = f->ebuf = f->buf;
204 f->strp = 0;
205 return f;
208 io*
209 openstr(void)
211 io *f = new(struct io);
212 char *s;
213 f->fd=-1;
214 f->bufp = f->strp = emalloc(101);
215 f->ebuf = f->bufp+100;
216 for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
217 return f;
219 /*
220 * Open a corebuffer to read. EOF occurs after reading len
221 * characters from buf.
222 */
224 io*
225 opencore(char *s, int len)
227 io *f = new(struct io);
228 char *buf = emalloc(len);
229 f->fd= -1 /*open("/dev/null", 0)*/;
230 f->bufp = f->strp = buf;
231 f->ebuf = buf+len;
232 Memcpy(buf, s, len);
233 return f;
236 void
237 iorewind(io *io)
239 if(io->fd==-1)
240 io->bufp = io->strp;
241 else{
242 io->bufp = io->ebuf = io->buf;
243 Seek(io->fd, 0L, 0);
247 void
248 closeio(io *io)
250 if(io->fd>=0)
251 close(io->fd);
252 if(io->strp)
253 efree(io->strp);
254 efree((char *)io);
257 int
258 emptybuf(io *f)
260 int n;
261 if(f->fd==-1)
262 return EOF;
263 Loop:
264 errno = 0;
265 n = Read(f->fd, f->buf, NBUF);
266 if(n < 0 && errno == EINTR)
267 goto Loop;
268 if(n <= 0)
269 return EOF;
270 f->bufp = f->buf;
271 f->ebuf = f->buf+n;
272 return *f->bufp++&0xff;