13e12c5d1SDavid du Colombier #include "rc.h" 23e12c5d1SDavid du Colombier #include "exec.h" 33e12c5d1SDavid du Colombier #include "io.h" 43e12c5d1SDavid du Colombier #include "fns.h" 5276e7d6dSDavid du Colombier 6276e7d6dSDavid du Colombier enum { Stralloc = 100, }; 7276e7d6dSDavid du Colombier 83e12c5d1SDavid du Colombier int pfmtnest = 0; 9dc5a79c1SDavid du Colombier 10dc5a79c1SDavid du Colombier void 11dc5a79c1SDavid du Colombier pfmt(io *f, char *fmt, ...) 12dc5a79c1SDavid du Colombier { 133e12c5d1SDavid du Colombier va_list ap; 149a747e4fSDavid du Colombier char err[ERRMAX]; 15*fbd2c77cSDavid du Colombier 163e12c5d1SDavid du Colombier va_start(ap, fmt); 173e12c5d1SDavid du Colombier pfmtnest++; 18*fbd2c77cSDavid du Colombier for(;*fmt;fmt++) { 19*fbd2c77cSDavid du Colombier if(*fmt!='%') { 20dc5a79c1SDavid du Colombier pchr(f, *fmt); 21*fbd2c77cSDavid du Colombier continue; 22*fbd2c77cSDavid du Colombier } 23*fbd2c77cSDavid du Colombier if(*++fmt == '\0') /* "blah%"? */ 24*fbd2c77cSDavid du Colombier break; 25*fbd2c77cSDavid du Colombier switch(*fmt){ 26dc5a79c1SDavid du Colombier case 'c': 27dc5a79c1SDavid du Colombier pchr(f, va_arg(ap, int)); 28dc5a79c1SDavid du Colombier break; 29dc5a79c1SDavid du Colombier case 'd': 30dc5a79c1SDavid du Colombier pdec(f, va_arg(ap, int)); 31dc5a79c1SDavid du Colombier break; 32dc5a79c1SDavid du Colombier case 'o': 33dc5a79c1SDavid du Colombier poct(f, va_arg(ap, unsigned)); 34dc5a79c1SDavid du Colombier break; 35dc5a79c1SDavid du Colombier case 'p': 3673e742d7SDavid du Colombier pptr(f, va_arg(ap, void*)); 3773e742d7SDavid du Colombier break; 38dc5a79c1SDavid du Colombier case 'Q': 39dc5a79c1SDavid du Colombier pquo(f, va_arg(ap, char *)); 40dc5a79c1SDavid du Colombier break; 41dc5a79c1SDavid du Colombier case 'q': 42dc5a79c1SDavid du Colombier pwrd(f, va_arg(ap, char *)); 43dc5a79c1SDavid du Colombier break; 44dc5a79c1SDavid du Colombier case 'r': 45dc5a79c1SDavid du Colombier errstr(err, sizeof err); pstr(f, err); 46dc5a79c1SDavid du Colombier break; 47dc5a79c1SDavid du Colombier case 's': 48dc5a79c1SDavid du Colombier pstr(f, va_arg(ap, char *)); 49dc5a79c1SDavid du Colombier break; 50dc5a79c1SDavid du Colombier case 't': 51dc5a79c1SDavid du Colombier pcmd(f, va_arg(ap, struct tree *)); 52dc5a79c1SDavid du Colombier break; 53dc5a79c1SDavid du Colombier case 'v': 54dc5a79c1SDavid du Colombier pval(f, va_arg(ap, struct word *)); 55dc5a79c1SDavid du Colombier break; 56dc5a79c1SDavid du Colombier default: 57dc5a79c1SDavid du Colombier pchr(f, *fmt); 58dc5a79c1SDavid du Colombier break; 593e12c5d1SDavid du Colombier } 60*fbd2c77cSDavid du Colombier } 613e12c5d1SDavid du Colombier va_end(ap); 62dc5a79c1SDavid du Colombier if(--pfmtnest==0) 63dc5a79c1SDavid du Colombier flush(f); 643e12c5d1SDavid du Colombier } 65dc5a79c1SDavid du Colombier 66dc5a79c1SDavid du Colombier void 67dc5a79c1SDavid du Colombier pchr(io *b, int c) 687dd7cddfSDavid du Colombier { 69dc5a79c1SDavid du Colombier if(b->bufp==b->ebuf) 70dc5a79c1SDavid du Colombier fullbuf(b, c); 7199eb86a7SDavid du Colombier else *b->bufp++=c; 727dd7cddfSDavid du Colombier } 73dc5a79c1SDavid du Colombier 74dc5a79c1SDavid du Colombier int 75dc5a79c1SDavid du Colombier rchr(io *b) 767dd7cddfSDavid du Colombier { 77dc5a79c1SDavid du Colombier if(b->bufp==b->ebuf) 78dc5a79c1SDavid du Colombier return emptybuf(b); 79276e7d6dSDavid du Colombier return *b->bufp++; 807dd7cddfSDavid du Colombier } 81dc5a79c1SDavid du Colombier 82dc5a79c1SDavid du Colombier void 83dc5a79c1SDavid du Colombier pquo(io *f, char *s) 843e12c5d1SDavid du Colombier { 853e12c5d1SDavid du Colombier pchr(f, '\''); 863e12c5d1SDavid du Colombier for(;*s;s++) 87dc5a79c1SDavid du Colombier if(*s=='\'') 88dc5a79c1SDavid du Colombier pfmt(f, "''"); 8999eb86a7SDavid du Colombier else pchr(f, *s); 903e12c5d1SDavid du Colombier pchr(f, '\''); 913e12c5d1SDavid du Colombier } 92dc5a79c1SDavid du Colombier 93dc5a79c1SDavid du Colombier void 94dc5a79c1SDavid du Colombier pwrd(io *f, char *s) 953e12c5d1SDavid du Colombier { 963e12c5d1SDavid du Colombier char *t; 97fed0fa9eSDavid du Colombier for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break; 98dc5a79c1SDavid du Colombier if(t==s || *t) 99dc5a79c1SDavid du Colombier pquo(f, s); 10099eb86a7SDavid du Colombier else pstr(f, s); 1013e12c5d1SDavid du Colombier } 102dc5a79c1SDavid du Colombier 103dc5a79c1SDavid du Colombier void 10473e742d7SDavid du Colombier pptr(io *f, void *v) 1053e12c5d1SDavid du Colombier { 1063e12c5d1SDavid du Colombier int n; 10773e742d7SDavid du Colombier uintptr p; 10873e742d7SDavid du Colombier 10973e742d7SDavid du Colombier p = (uintptr)v; 11073e742d7SDavid du Colombier if(sizeof(uintptr) == sizeof(uvlong) && p>>32) 11199eb86a7SDavid du Colombier for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); 11273e742d7SDavid du Colombier 11399eb86a7SDavid du Colombier for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); 1143e12c5d1SDavid du Colombier } 115dc5a79c1SDavid du Colombier 116dc5a79c1SDavid du Colombier void 117dc5a79c1SDavid du Colombier pstr(io *f, char *s) 1183e12c5d1SDavid du Colombier { 119dc5a79c1SDavid du Colombier if(s==0) 120dc5a79c1SDavid du Colombier s="(null)"; 12199eb86a7SDavid du Colombier while(*s) pchr(f, *s++); 1223e12c5d1SDavid du Colombier } 123dc5a79c1SDavid du Colombier 124dc5a79c1SDavid du Colombier void 12573e742d7SDavid du Colombier pdec(io *f, int n) 1263e12c5d1SDavid du Colombier { 1273e12c5d1SDavid du Colombier if(n<0){ 1283e12c5d1SDavid du Colombier n=-n; 1293e12c5d1SDavid du Colombier if(n>=0){ 1303e12c5d1SDavid du Colombier pchr(f, '-'); 1313e12c5d1SDavid du Colombier pdec(f, n); 1323e12c5d1SDavid du Colombier return; 1333e12c5d1SDavid du Colombier } 1343e12c5d1SDavid du Colombier /* n is two's complement minimum integer */ 1353e12c5d1SDavid du Colombier n = 1-n; 1363e12c5d1SDavid du Colombier pchr(f, '-'); 1373e12c5d1SDavid du Colombier pdec(f, n/10); 1383e12c5d1SDavid du Colombier pchr(f, n%10+'1'); 1393e12c5d1SDavid du Colombier return; 1403e12c5d1SDavid du Colombier } 141dc5a79c1SDavid du Colombier if(n>9) 142dc5a79c1SDavid du Colombier pdec(f, n/10); 1433e12c5d1SDavid du Colombier pchr(f, n%10+'0'); 1443e12c5d1SDavid du Colombier } 145dc5a79c1SDavid du Colombier 146dc5a79c1SDavid du Colombier void 14773e742d7SDavid du Colombier poct(io *f, unsigned n) 1483e12c5d1SDavid du Colombier { 149dc5a79c1SDavid du Colombier if(n>7) 150dc5a79c1SDavid du Colombier poct(f, n>>3); 1513e12c5d1SDavid du Colombier pchr(f, (n&7)+'0'); 1523e12c5d1SDavid du Colombier } 153dc5a79c1SDavid du Colombier 154dc5a79c1SDavid du Colombier void 155dc5a79c1SDavid du Colombier pval(io *f, word *a) 1563e12c5d1SDavid du Colombier { 1573e12c5d1SDavid du Colombier if(a){ 1583e12c5d1SDavid du Colombier while(a->next && a->next->word){ 159276e7d6dSDavid du Colombier pwrd(f, (char *)a->word); 1603e12c5d1SDavid du Colombier pchr(f, ' '); 1613e12c5d1SDavid du Colombier a = a->next; 1623e12c5d1SDavid du Colombier } 163276e7d6dSDavid du Colombier pwrd(f, (char *)a->word); 1643e12c5d1SDavid du Colombier } 1653e12c5d1SDavid du Colombier } 166dc5a79c1SDavid du Colombier 167dc5a79c1SDavid du Colombier int 168dc5a79c1SDavid du Colombier fullbuf(io *f, int c) 1693e12c5d1SDavid du Colombier { 1703e12c5d1SDavid du Colombier flush(f); 1713e12c5d1SDavid du Colombier return *f->bufp++=c; 1723e12c5d1SDavid du Colombier } 173dc5a79c1SDavid du Colombier 174dc5a79c1SDavid du Colombier void 175dc5a79c1SDavid du Colombier flush(io *f) 1763e12c5d1SDavid du Colombier { 1773e12c5d1SDavid du Colombier int n; 178276e7d6dSDavid du Colombier 1793e12c5d1SDavid du Colombier if(f->strp){ 1803e12c5d1SDavid du Colombier n = f->ebuf - f->strp; 181276e7d6dSDavid du Colombier f->strp = realloc(f->strp, n+Stralloc+1); 182dc5a79c1SDavid du Colombier if(f->strp==0) 183276e7d6dSDavid du Colombier panic("Can't realloc %d bytes in flush!", n+Stralloc+1); 1843e12c5d1SDavid du Colombier f->bufp = f->strp + n; 185276e7d6dSDavid du Colombier f->ebuf = f->bufp + Stralloc; 186276e7d6dSDavid du Colombier memset(f->bufp, '\0', Stralloc+1); 1873e12c5d1SDavid du Colombier } 1883e12c5d1SDavid du Colombier else{ 1893e12c5d1SDavid du Colombier n = f->bufp-f->buf; 190276e7d6dSDavid du Colombier if(n && Write(f->fd, f->buf, n) != n){ 191276e7d6dSDavid du Colombier Write(2, "Write error\n", 12); 192dc5a79c1SDavid du Colombier if(ntrap) 193dc5a79c1SDavid du Colombier dotrap(); 1943e12c5d1SDavid du Colombier } 1953e12c5d1SDavid du Colombier f->bufp = f->buf; 1963e12c5d1SDavid du Colombier f->ebuf = f->buf+NBUF; 1973e12c5d1SDavid du Colombier } 1983e12c5d1SDavid du Colombier } 199dc5a79c1SDavid du Colombier 200dc5a79c1SDavid du Colombier io* 201dc5a79c1SDavid du Colombier openfd(int fd) 202dc5a79c1SDavid du Colombier { 2033e12c5d1SDavid du Colombier io *f = new(struct io); 2043e12c5d1SDavid du Colombier f->fd = fd; 2053e12c5d1SDavid du Colombier f->bufp = f->ebuf = f->buf; 2063e12c5d1SDavid du Colombier f->strp = 0; 2073e12c5d1SDavid du Colombier return f; 2083e12c5d1SDavid du Colombier } 209dc5a79c1SDavid du Colombier 210dc5a79c1SDavid du Colombier io* 211dc5a79c1SDavid du Colombier openstr(void) 212dc5a79c1SDavid du Colombier { 2133e12c5d1SDavid du Colombier io *f = new(struct io); 214276e7d6dSDavid du Colombier 2153e12c5d1SDavid du Colombier f->fd = -1; 216276e7d6dSDavid du Colombier f->bufp = f->strp = emalloc(Stralloc+1); 217276e7d6dSDavid du Colombier f->ebuf = f->bufp + Stralloc; 218276e7d6dSDavid du Colombier memset(f->bufp, '\0', Stralloc+1); 2193e12c5d1SDavid du Colombier return f; 2203e12c5d1SDavid du Colombier } 2213e12c5d1SDavid du Colombier /* 2223e12c5d1SDavid du Colombier * Open a corebuffer to read. EOF occurs after reading len 2233e12c5d1SDavid du Colombier * characters from buf. 2243e12c5d1SDavid du Colombier */ 225dc5a79c1SDavid du Colombier 226dc5a79c1SDavid du Colombier io* 227dc5a79c1SDavid du Colombier opencore(char *s, int len) 2283e12c5d1SDavid du Colombier { 2293e12c5d1SDavid du Colombier io *f = new(struct io); 230276e7d6dSDavid du Colombier uchar *buf = emalloc(len); 231276e7d6dSDavid du Colombier 2323e12c5d1SDavid du Colombier f->fd = -1 /*open("/dev/null", 0)*/; 2333e12c5d1SDavid du Colombier f->bufp = f->strp = buf; 2343e12c5d1SDavid du Colombier f->ebuf = buf+len; 2353e12c5d1SDavid du Colombier Memcpy(buf, s, len); 2363e12c5d1SDavid du Colombier return f; 2373e12c5d1SDavid du Colombier } 238dc5a79c1SDavid du Colombier 239dc5a79c1SDavid du Colombier void 240dc5a79c1SDavid du Colombier rewind(io *io) 2413e12c5d1SDavid du Colombier { 242dc5a79c1SDavid du Colombier if(io->fd==-1) 243dc5a79c1SDavid du Colombier io->bufp = io->strp; 2443e12c5d1SDavid du Colombier else{ 2453e12c5d1SDavid du Colombier io->bufp = io->ebuf = io->buf; 24699eb86a7SDavid du Colombier Seek(io->fd, 0L, 0); 2473e12c5d1SDavid du Colombier } 2483e12c5d1SDavid du Colombier } 249dc5a79c1SDavid du Colombier 250dc5a79c1SDavid du Colombier void 251dc5a79c1SDavid du Colombier closeio(io *io) 2523e12c5d1SDavid du Colombier { 253dc5a79c1SDavid du Colombier if(io->fd>=0) 254dc5a79c1SDavid du Colombier close(io->fd); 255dc5a79c1SDavid du Colombier if(io->strp) 256dc5a79c1SDavid du Colombier efree(io->strp); 257276e7d6dSDavid du Colombier efree(io); 2583e12c5d1SDavid du Colombier } 259dc5a79c1SDavid du Colombier 260dc5a79c1SDavid du Colombier int 261dc5a79c1SDavid du Colombier emptybuf(io *f) 2623e12c5d1SDavid du Colombier { 2633e12c5d1SDavid du Colombier int n; 26499eb86a7SDavid du Colombier if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF; 2653e12c5d1SDavid du Colombier f->bufp = f->buf; 2663e12c5d1SDavid du Colombier f->ebuf = f->buf + n; 267276e7d6dSDavid du Colombier return *f->bufp++; 2683e12c5d1SDavid du Colombier } 269