13e12c5d1SDavid du Colombier #include "rc.h" 23e12c5d1SDavid du Colombier #include "exec.h" 33e12c5d1SDavid du Colombier #include "io.h" 43e12c5d1SDavid du Colombier #include "fns.h" 53e12c5d1SDavid du Colombier int pfmtnest = 0; 6dc5a79c1SDavid du Colombier 7dc5a79c1SDavid du Colombier void 8dc5a79c1SDavid du Colombier pfmt(io *f, char *fmt, ...) 9dc5a79c1SDavid du Colombier { 103e12c5d1SDavid du Colombier va_list ap; 119a747e4fSDavid du Colombier char err[ERRMAX]; 123e12c5d1SDavid du Colombier va_start(ap, fmt); 133e12c5d1SDavid du Colombier pfmtnest++; 143e12c5d1SDavid du Colombier for(;*fmt;fmt++) 15dc5a79c1SDavid du Colombier if(*fmt!='%') 16dc5a79c1SDavid du Colombier pchr(f, *fmt); 173e12c5d1SDavid du Colombier else switch(*++fmt){ 18dc5a79c1SDavid du Colombier case '\0': 19dc5a79c1SDavid du Colombier va_end(ap); 20dc5a79c1SDavid du Colombier return; 21dc5a79c1SDavid du Colombier case 'c': 22dc5a79c1SDavid du Colombier pchr(f, va_arg(ap, int)); 23dc5a79c1SDavid du Colombier break; 24dc5a79c1SDavid du Colombier case 'd': 25dc5a79c1SDavid du Colombier pdec(f, va_arg(ap, int)); 26dc5a79c1SDavid du Colombier break; 27dc5a79c1SDavid du Colombier case 'o': 28dc5a79c1SDavid du Colombier poct(f, va_arg(ap, unsigned)); 29dc5a79c1SDavid du Colombier break; 30dc5a79c1SDavid du Colombier case 'p': 31*73e742d7SDavid du Colombier pptr(f, va_arg(ap, void*)); 32*73e742d7SDavid du Colombier break; 33dc5a79c1SDavid du Colombier case 'Q': 34dc5a79c1SDavid du Colombier pquo(f, va_arg(ap, char *)); 35dc5a79c1SDavid du Colombier break; 36dc5a79c1SDavid du Colombier case 'q': 37dc5a79c1SDavid du Colombier pwrd(f, va_arg(ap, char *)); 38dc5a79c1SDavid du Colombier break; 39dc5a79c1SDavid du Colombier case 'r': 40dc5a79c1SDavid du Colombier errstr(err, sizeof err); pstr(f, err); 41dc5a79c1SDavid du Colombier break; 42dc5a79c1SDavid du Colombier case 's': 43dc5a79c1SDavid du Colombier pstr(f, va_arg(ap, char *)); 44dc5a79c1SDavid du Colombier break; 45dc5a79c1SDavid du Colombier case 't': 46dc5a79c1SDavid du Colombier pcmd(f, va_arg(ap, struct tree *)); 47dc5a79c1SDavid du Colombier break; 48dc5a79c1SDavid du Colombier case 'v': 49dc5a79c1SDavid du Colombier pval(f, va_arg(ap, struct word *)); 50dc5a79c1SDavid du Colombier break; 51dc5a79c1SDavid du Colombier default: 52dc5a79c1SDavid du Colombier pchr(f, *fmt); 53dc5a79c1SDavid du Colombier break; 543e12c5d1SDavid du Colombier } 553e12c5d1SDavid du Colombier va_end(ap); 56dc5a79c1SDavid du Colombier if(--pfmtnest==0) 57dc5a79c1SDavid du Colombier flush(f); 583e12c5d1SDavid du Colombier } 59dc5a79c1SDavid du Colombier 60dc5a79c1SDavid du Colombier void 61dc5a79c1SDavid du Colombier pchr(io *b, int c) 627dd7cddfSDavid du Colombier { 63dc5a79c1SDavid du Colombier if(b->bufp==b->ebuf) 64dc5a79c1SDavid du Colombier fullbuf(b, c); 657dd7cddfSDavid du Colombier else *b->bufp++=c; 667dd7cddfSDavid du Colombier } 67dc5a79c1SDavid du Colombier 68dc5a79c1SDavid du Colombier int 69dc5a79c1SDavid du Colombier rchr(io *b) 707dd7cddfSDavid du Colombier { 71dc5a79c1SDavid du Colombier if(b->bufp==b->ebuf) 72dc5a79c1SDavid du Colombier return emptybuf(b); 737dd7cddfSDavid du Colombier return *b->bufp++ & 0xFF; 747dd7cddfSDavid du Colombier } 75dc5a79c1SDavid du Colombier 76dc5a79c1SDavid du Colombier void 77dc5a79c1SDavid du Colombier pquo(io *f, char *s) 783e12c5d1SDavid du Colombier { 793e12c5d1SDavid du Colombier pchr(f, '\''); 803e12c5d1SDavid du Colombier for(;*s;s++) 81dc5a79c1SDavid du Colombier if(*s=='\'') 82dc5a79c1SDavid du Colombier pfmt(f, "''"); 833e12c5d1SDavid du Colombier else pchr(f, *s); 843e12c5d1SDavid du Colombier pchr(f, '\''); 853e12c5d1SDavid du Colombier } 86dc5a79c1SDavid du Colombier 87dc5a79c1SDavid du Colombier void 88dc5a79c1SDavid du Colombier pwrd(io *f, char *s) 893e12c5d1SDavid du Colombier { 903e12c5d1SDavid du Colombier char *t; 913e12c5d1SDavid du Colombier for(t = s;*t;t++) if(!wordchr(*t)) break; 92dc5a79c1SDavid du Colombier if(t==s || *t) 93dc5a79c1SDavid du Colombier pquo(f, s); 943e12c5d1SDavid du Colombier else pstr(f, s); 953e12c5d1SDavid du Colombier } 96dc5a79c1SDavid du Colombier 97dc5a79c1SDavid du Colombier void 98*73e742d7SDavid du Colombier pptr(io *f, void *v) 993e12c5d1SDavid du Colombier { 1003e12c5d1SDavid du Colombier int n; 101*73e742d7SDavid du Colombier uintptr p; 102*73e742d7SDavid du Colombier 103*73e742d7SDavid du Colombier p = (uintptr)v; 104*73e742d7SDavid du Colombier if(sizeof(uintptr) == sizeof(uvlong) && p>>32) 105*73e742d7SDavid du Colombier for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); 106*73e742d7SDavid du Colombier 1073e12c5d1SDavid du Colombier for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); 1083e12c5d1SDavid du Colombier } 109dc5a79c1SDavid du Colombier 110dc5a79c1SDavid du Colombier void 111dc5a79c1SDavid du Colombier pstr(io *f, char *s) 1123e12c5d1SDavid du Colombier { 113dc5a79c1SDavid du Colombier if(s==0) 114dc5a79c1SDavid du Colombier s="(null)"; 1153e12c5d1SDavid du Colombier while(*s) pchr(f, *s++); 1163e12c5d1SDavid du Colombier } 117dc5a79c1SDavid du Colombier 118dc5a79c1SDavid du Colombier void 119*73e742d7SDavid du Colombier pdec(io *f, int n) 1203e12c5d1SDavid du Colombier { 1213e12c5d1SDavid du Colombier if(n<0){ 1223e12c5d1SDavid du Colombier n=-n; 1233e12c5d1SDavid du Colombier if(n>=0){ 1243e12c5d1SDavid du Colombier pchr(f, '-'); 1253e12c5d1SDavid du Colombier pdec(f, n); 1263e12c5d1SDavid du Colombier return; 1273e12c5d1SDavid du Colombier } 1283e12c5d1SDavid du Colombier /* n is two's complement minimum integer */ 1293e12c5d1SDavid du Colombier n = 1-n; 1303e12c5d1SDavid du Colombier pchr(f, '-'); 1313e12c5d1SDavid du Colombier pdec(f, n/10); 1323e12c5d1SDavid du Colombier pchr(f, n%10+'1'); 1333e12c5d1SDavid du Colombier return; 1343e12c5d1SDavid du Colombier } 135dc5a79c1SDavid du Colombier if(n>9) 136dc5a79c1SDavid du Colombier pdec(f, n/10); 1373e12c5d1SDavid du Colombier pchr(f, n%10+'0'); 1383e12c5d1SDavid du Colombier } 139dc5a79c1SDavid du Colombier 140dc5a79c1SDavid du Colombier void 141*73e742d7SDavid du Colombier poct(io *f, unsigned n) 1423e12c5d1SDavid du Colombier { 143dc5a79c1SDavid du Colombier if(n>7) 144dc5a79c1SDavid du Colombier poct(f, n>>3); 1453e12c5d1SDavid du Colombier pchr(f, (n&7)+'0'); 1463e12c5d1SDavid du Colombier } 147dc5a79c1SDavid du Colombier 148dc5a79c1SDavid du Colombier void 149dc5a79c1SDavid du Colombier pval(io *f, word *a) 1503e12c5d1SDavid du Colombier { 1513e12c5d1SDavid du Colombier if(a){ 1523e12c5d1SDavid du Colombier while(a->next && a->next->word){ 1533e12c5d1SDavid du Colombier pwrd(f, a->word); 1543e12c5d1SDavid du Colombier pchr(f, ' '); 1553e12c5d1SDavid du Colombier a = a->next; 1563e12c5d1SDavid du Colombier } 1573e12c5d1SDavid du Colombier pwrd(f, a->word); 1583e12c5d1SDavid du Colombier } 1593e12c5d1SDavid du Colombier } 160dc5a79c1SDavid du Colombier 161dc5a79c1SDavid du Colombier int 162dc5a79c1SDavid du Colombier fullbuf(io *f, int c) 1633e12c5d1SDavid du Colombier { 1643e12c5d1SDavid du Colombier flush(f); 1653e12c5d1SDavid du Colombier return *f->bufp++=c; 1663e12c5d1SDavid du Colombier } 167dc5a79c1SDavid du Colombier 168dc5a79c1SDavid du Colombier void 169dc5a79c1SDavid du Colombier flush(io *f) 1703e12c5d1SDavid du Colombier { 1713e12c5d1SDavid du Colombier int n; 1723e12c5d1SDavid du Colombier char *s; 1733e12c5d1SDavid du Colombier if(f->strp){ 1743e12c5d1SDavid du Colombier n = f->ebuf-f->strp; 1753e12c5d1SDavid du Colombier f->strp = realloc(f->strp, n+101); 176dc5a79c1SDavid du Colombier if(f->strp==0) 177dc5a79c1SDavid du Colombier panic("Can't realloc %d bytes in flush!", n+101); 1783e12c5d1SDavid du Colombier f->bufp = f->strp+n; 1793e12c5d1SDavid du Colombier f->ebuf = f->bufp+100; 1803e12c5d1SDavid du Colombier for(s = f->bufp;s<=f->ebuf;s++) *s='\0'; 1813e12c5d1SDavid du Colombier } 1823e12c5d1SDavid du Colombier else{ 1833e12c5d1SDavid du Colombier n = f->bufp-f->buf; 1843e12c5d1SDavid du Colombier if(n && Write(f->fd, f->buf, n) < 0){ 1853e12c5d1SDavid du Colombier Write(3, "Write error\n", 12); 186dc5a79c1SDavid du Colombier if(ntrap) 187dc5a79c1SDavid du Colombier dotrap(); 1883e12c5d1SDavid du Colombier } 1893e12c5d1SDavid du Colombier f->bufp = f->buf; 1903e12c5d1SDavid du Colombier f->ebuf = f->buf+NBUF; 1913e12c5d1SDavid du Colombier } 1923e12c5d1SDavid du Colombier } 193dc5a79c1SDavid du Colombier 194dc5a79c1SDavid du Colombier io* 195dc5a79c1SDavid du Colombier openfd(int fd) 196dc5a79c1SDavid du Colombier { 1973e12c5d1SDavid du Colombier io *f = new(struct io); 1983e12c5d1SDavid du Colombier f->fd = fd; 1993e12c5d1SDavid du Colombier f->bufp = f->ebuf = f->buf; 2003e12c5d1SDavid du Colombier f->strp = 0; 2013e12c5d1SDavid du Colombier return f; 2023e12c5d1SDavid du Colombier } 203dc5a79c1SDavid du Colombier 204dc5a79c1SDavid du Colombier io* 205dc5a79c1SDavid du Colombier openstr(void) 206dc5a79c1SDavid du Colombier { 2073e12c5d1SDavid du Colombier io *f = new(struct io); 2083e12c5d1SDavid du Colombier char *s; 2093e12c5d1SDavid du Colombier f->fd=-1; 2103e12c5d1SDavid du Colombier f->bufp = f->strp = emalloc(101); 2113e12c5d1SDavid du Colombier f->ebuf = f->bufp+100; 2123e12c5d1SDavid du Colombier for(s = f->bufp;s<=f->ebuf;s++) *s='\0'; 2133e12c5d1SDavid du Colombier return f; 2143e12c5d1SDavid du Colombier } 2153e12c5d1SDavid du Colombier /* 2163e12c5d1SDavid du Colombier * Open a corebuffer to read. EOF occurs after reading len 2173e12c5d1SDavid du Colombier * characters from buf. 2183e12c5d1SDavid du Colombier */ 219dc5a79c1SDavid du Colombier 220dc5a79c1SDavid du Colombier io* 221dc5a79c1SDavid du Colombier opencore(char *s, int len) 2223e12c5d1SDavid du Colombier { 2233e12c5d1SDavid du Colombier io *f = new(struct io); 2243e12c5d1SDavid du Colombier char *buf = emalloc(len); 2253e12c5d1SDavid du Colombier f->fd= -1 /*open("/dev/null", 0)*/; 2263e12c5d1SDavid du Colombier f->bufp = f->strp = buf; 2273e12c5d1SDavid du Colombier f->ebuf = buf+len; 2283e12c5d1SDavid du Colombier Memcpy(buf, s, len); 2293e12c5d1SDavid du Colombier return f; 2303e12c5d1SDavid du Colombier } 231dc5a79c1SDavid du Colombier 232dc5a79c1SDavid du Colombier void 233dc5a79c1SDavid du Colombier rewind(io *io) 2343e12c5d1SDavid du Colombier { 235dc5a79c1SDavid du Colombier if(io->fd==-1) 236dc5a79c1SDavid du Colombier io->bufp = io->strp; 2373e12c5d1SDavid du Colombier else{ 2383e12c5d1SDavid du Colombier io->bufp = io->ebuf = io->buf; 2393e12c5d1SDavid du Colombier Seek(io->fd, 0L, 0); 2403e12c5d1SDavid du Colombier } 2413e12c5d1SDavid du Colombier } 242dc5a79c1SDavid du Colombier 243dc5a79c1SDavid du Colombier void 244dc5a79c1SDavid du Colombier closeio(io *io) 2453e12c5d1SDavid du Colombier { 246dc5a79c1SDavid du Colombier if(io->fd>=0) 247dc5a79c1SDavid du Colombier close(io->fd); 248dc5a79c1SDavid du Colombier if(io->strp) 249dc5a79c1SDavid du Colombier efree(io->strp); 2503e12c5d1SDavid du Colombier efree((char *)io); 2513e12c5d1SDavid du Colombier } 252dc5a79c1SDavid du Colombier 253dc5a79c1SDavid du Colombier int 254dc5a79c1SDavid du Colombier emptybuf(io *f) 2553e12c5d1SDavid du Colombier { 2563e12c5d1SDavid du Colombier int n; 2573e12c5d1SDavid du Colombier if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF; 2583e12c5d1SDavid du Colombier f->bufp = f->buf; 2593e12c5d1SDavid du Colombier f->ebuf = f->buf+n; 2603e12c5d1SDavid du Colombier return *f->bufp++&0xff; 2613e12c5d1SDavid du Colombier } 262