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 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 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 75 rchr(io *b) 76 { 77 if(b->bufp==b->ebuf) 78 return emptybuf(b); 79 return *b->bufp++; 80 } 81 82 void 83 pquo(io *f, char *s) 84 { 85 pchr(f, '\''); 86 for(;*s;s++) 87 if(*s=='\'') 88 pfmt(f, "''"); 89 else pchr(f, *s); 90 pchr(f, '\''); 91 } 92 93 void 94 pwrd(io *f, char *s) 95 { 96 char *t; 97 for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break; 98 if(t==s || *t) 99 pquo(f, s); 100 else pstr(f, s); 101 } 102 103 void 104 pptr(io *f, void *v) 105 { 106 int n; 107 uintptr p; 108 109 p = (uintptr)v; 110 if(sizeof(uintptr) == sizeof(uvlong) && p>>32) 111 for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); 112 113 for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); 114 } 115 116 void 117 pstr(io *f, char *s) 118 { 119 if(s==0) 120 s="(null)"; 121 while(*s) pchr(f, *s++); 122 } 123 124 void 125 pdec(io *f, int n) 126 { 127 if(n<0){ 128 n=-n; 129 if(n>=0){ 130 pchr(f, '-'); 131 pdec(f, n); 132 return; 133 } 134 /* n is two's complement minimum integer */ 135 n = 1-n; 136 pchr(f, '-'); 137 pdec(f, n/10); 138 pchr(f, n%10+'1'); 139 return; 140 } 141 if(n>9) 142 pdec(f, n/10); 143 pchr(f, n%10+'0'); 144 } 145 146 void 147 poct(io *f, unsigned n) 148 { 149 if(n>7) 150 poct(f, n>>3); 151 pchr(f, (n&7)+'0'); 152 } 153 154 void 155 pval(io *f, word *a) 156 { 157 if(a){ 158 while(a->next && a->next->word){ 159 pwrd(f, (char *)a->word); 160 pchr(f, ' '); 161 a = a->next; 162 } 163 pwrd(f, (char *)a->word); 164 } 165 } 166 167 int 168 fullbuf(io *f, int c) 169 { 170 flush(f); 171 return *f->bufp++=c; 172 } 173 174 void 175 flush(io *f) 176 { 177 int n; 178 179 if(f->strp){ 180 n = f->ebuf - f->strp; 181 f->strp = realloc(f->strp, n+Stralloc+1); 182 if(f->strp==0) 183 panic("Can't realloc %d bytes in flush!", n+Stralloc+1); 184 f->bufp = f->strp + n; 185 f->ebuf = f->bufp + Stralloc; 186 memset(f->bufp, '\0', Stralloc+1); 187 } 188 else{ 189 n = f->bufp-f->buf; 190 if(n && Write(f->fd, f->buf, n) != n){ 191 Write(2, "Write error\n", 12); 192 if(ntrap) 193 dotrap(); 194 } 195 f->bufp = f->buf; 196 f->ebuf = f->buf+NBUF; 197 } 198 } 199 200 io* 201 openfd(int fd) 202 { 203 io *f = new(struct io); 204 f->fd = fd; 205 f->bufp = f->ebuf = f->buf; 206 f->strp = 0; 207 return f; 208 } 209 210 io* 211 openstr(void) 212 { 213 io *f = new(struct io); 214 215 f->fd = -1; 216 f->bufp = f->strp = emalloc(Stralloc+1); 217 f->ebuf = f->bufp + Stralloc; 218 memset(f->bufp, '\0', Stralloc+1); 219 return f; 220 } 221 /* 222 * Open a corebuffer to read. EOF occurs after reading len 223 * characters from buf. 224 */ 225 226 io* 227 opencore(char *s, int len) 228 { 229 io *f = new(struct io); 230 uchar *buf = emalloc(len); 231 232 f->fd = -1 /*open("/dev/null", 0)*/; 233 f->bufp = f->strp = buf; 234 f->ebuf = buf+len; 235 Memcpy(buf, s, len); 236 return f; 237 } 238 239 void 240 rewind(io *io) 241 { 242 if(io->fd==-1) 243 io->bufp = io->strp; 244 else{ 245 io->bufp = io->ebuf = io->buf; 246 Seek(io->fd, 0L, 0); 247 } 248 } 249 250 void 251 closeio(io *io) 252 { 253 if(io->fd>=0) 254 close(io->fd); 255 if(io->strp) 256 efree(io->strp); 257 efree(io); 258 } 259 260 int 261 emptybuf(io *f) 262 { 263 int n; 264 if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF; 265 f->bufp = f->buf; 266 f->ebuf = f->buf + n; 267 return *f->bufp++; 268 } 269