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; 63e12c5d1SDavid du Colombier void pfmt(io *f, char *fmt, ...){ 73e12c5d1SDavid du Colombier va_list ap; 83e12c5d1SDavid du Colombier va_start(ap, fmt); 93e12c5d1SDavid du Colombier pfmtnest++; 103e12c5d1SDavid du Colombier for(;*fmt;fmt++) 113e12c5d1SDavid du Colombier if(*fmt!='%') pchr(f, *fmt); 123e12c5d1SDavid du Colombier else switch(*++fmt){ 133e12c5d1SDavid du Colombier case '\0': va_end(ap); return; 143e12c5d1SDavid du Colombier case 'c': pchr(f, va_arg(ap, int)); break; 153e12c5d1SDavid du Colombier case 'd': pdec(f, va_arg(ap, int)); break; 163e12c5d1SDavid du Colombier case 'o': poct(f, va_arg(ap, unsigned)); break; 173e12c5d1SDavid du Colombier case 'p': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/ 183e12c5d1SDavid du Colombier case 'Q': pquo(f, va_arg(ap, char *)); break; 193e12c5d1SDavid du Colombier case 'q': pwrd(f, va_arg(ap, char *)); break; 203e12c5d1SDavid du Colombier case 's': pstr(f, va_arg(ap, char *)); break; 213e12c5d1SDavid du Colombier case 't': pcmd(f, va_arg(ap, struct tree *)); break; 223e12c5d1SDavid du Colombier case 'v': pval(f, va_arg(ap, struct word *)); break; 233e12c5d1SDavid du Colombier default: pchr(f, *fmt); break; 243e12c5d1SDavid du Colombier } 253e12c5d1SDavid du Colombier va_end(ap); 263e12c5d1SDavid du Colombier if(--pfmtnest==0) flush(f); 273e12c5d1SDavid du Colombier } 28*7dd7cddfSDavid du Colombier void pchr(io *b, int c) 29*7dd7cddfSDavid du Colombier { 30*7dd7cddfSDavid du Colombier if(b->bufp==b->ebuf) fullbuf(b, c); 31*7dd7cddfSDavid du Colombier else *b->bufp++=c; 32*7dd7cddfSDavid du Colombier } 33*7dd7cddfSDavid du Colombier int rchr(io *b) 34*7dd7cddfSDavid du Colombier { 35*7dd7cddfSDavid du Colombier if(b->bufp==b->ebuf) return emptybuf(b); 36*7dd7cddfSDavid du Colombier return *b->bufp++ & 0xFF; 37*7dd7cddfSDavid du Colombier } 383e12c5d1SDavid du Colombier void pquo(io *f, char *s) 393e12c5d1SDavid du Colombier { 403e12c5d1SDavid du Colombier pchr(f, '\''); 413e12c5d1SDavid du Colombier for(;*s;s++) 423e12c5d1SDavid du Colombier if(*s=='\'') pfmt(f, "''"); 433e12c5d1SDavid du Colombier else pchr(f, *s); 443e12c5d1SDavid du Colombier pchr(f, '\''); 453e12c5d1SDavid du Colombier } 463e12c5d1SDavid du Colombier void pwrd(io *f, char *s) 473e12c5d1SDavid du Colombier { 483e12c5d1SDavid du Colombier char *t; 493e12c5d1SDavid du Colombier for(t=s;*t;t++) if(!wordchr(*t)) break; 503e12c5d1SDavid du Colombier if(t==s || *t) pquo(f, s); 513e12c5d1SDavid du Colombier else pstr(f, s); 523e12c5d1SDavid du Colombier } 533e12c5d1SDavid du Colombier void phex(io *f, long p) 543e12c5d1SDavid du Colombier { 553e12c5d1SDavid du Colombier int n; 563e12c5d1SDavid du Colombier for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); 573e12c5d1SDavid du Colombier } 583e12c5d1SDavid du Colombier void pstr(io *f, char *s) 593e12c5d1SDavid du Colombier { 603e12c5d1SDavid du Colombier if(s==0) s="(null)"; 613e12c5d1SDavid du Colombier while(*s) pchr(f, *s++); 623e12c5d1SDavid du Colombier } 633e12c5d1SDavid du Colombier void pdec(io *f, long n) 643e12c5d1SDavid du Colombier { 653e12c5d1SDavid du Colombier if(n<0){ 663e12c5d1SDavid du Colombier n=-n; 673e12c5d1SDavid du Colombier if(n>=0){ 683e12c5d1SDavid du Colombier pchr(f, '-'); 693e12c5d1SDavid du Colombier pdec(f, n); 703e12c5d1SDavid du Colombier return; 713e12c5d1SDavid du Colombier } 723e12c5d1SDavid du Colombier /* n is two's complement minimum integer */ 733e12c5d1SDavid du Colombier n=1-n; 743e12c5d1SDavid du Colombier pchr(f, '-'); 753e12c5d1SDavid du Colombier pdec(f, n/10); 763e12c5d1SDavid du Colombier pchr(f, n%10+'1'); 773e12c5d1SDavid du Colombier return; 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier if(n>9) pdec(f, n/10); 803e12c5d1SDavid du Colombier pchr(f, n%10+'0'); 813e12c5d1SDavid du Colombier } 823e12c5d1SDavid du Colombier void poct(io *f, ulong n) 833e12c5d1SDavid du Colombier { 843e12c5d1SDavid du Colombier if(n>7) poct(f, n>>3); 853e12c5d1SDavid du Colombier pchr(f, (n&7)+'0'); 863e12c5d1SDavid du Colombier } 873e12c5d1SDavid du Colombier void pval(io *f, word *a) 883e12c5d1SDavid du Colombier { 893e12c5d1SDavid du Colombier if(a){ 903e12c5d1SDavid du Colombier while(a->next && a->next->word){ 913e12c5d1SDavid du Colombier pwrd(f, a->word); 923e12c5d1SDavid du Colombier pchr(f, ' '); 933e12c5d1SDavid du Colombier a=a->next; 943e12c5d1SDavid du Colombier } 953e12c5d1SDavid du Colombier pwrd(f, a->word); 963e12c5d1SDavid du Colombier } 973e12c5d1SDavid du Colombier } 983e12c5d1SDavid du Colombier int fullbuf(io *f, int c) 993e12c5d1SDavid du Colombier { 1003e12c5d1SDavid du Colombier flush(f); 1013e12c5d1SDavid du Colombier return *f->bufp++=c; 1023e12c5d1SDavid du Colombier } 1033e12c5d1SDavid du Colombier void flush(io *f) 1043e12c5d1SDavid du Colombier { 1053e12c5d1SDavid du Colombier int n; 1063e12c5d1SDavid du Colombier char *s; 1073e12c5d1SDavid du Colombier if(f->strp){ 1083e12c5d1SDavid du Colombier n=f->ebuf-f->strp; 1093e12c5d1SDavid du Colombier f->strp=realloc(f->strp, n+101); 1103e12c5d1SDavid du Colombier if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101); 1113e12c5d1SDavid du Colombier f->bufp=f->strp+n; 1123e12c5d1SDavid du Colombier f->ebuf=f->bufp+100; 1133e12c5d1SDavid du Colombier for(s=f->bufp;s<=f->ebuf;s++) *s='\0'; 1143e12c5d1SDavid du Colombier } 1153e12c5d1SDavid du Colombier else{ 1163e12c5d1SDavid du Colombier n=f->bufp-f->buf; 1173e12c5d1SDavid du Colombier if(n && Write(f->fd, f->buf, n) < 0){ 1183e12c5d1SDavid du Colombier Write(3, "Write error\n", 12); 1193e12c5d1SDavid du Colombier if(ntrap) dotrap(); 1203e12c5d1SDavid du Colombier } 1213e12c5d1SDavid du Colombier f->bufp=f->buf; 1223e12c5d1SDavid du Colombier f->ebuf=f->buf+NBUF; 1233e12c5d1SDavid du Colombier } 1243e12c5d1SDavid du Colombier } 1253e12c5d1SDavid du Colombier io *openfd(int fd){ 1263e12c5d1SDavid du Colombier io *f=new(struct io); 1273e12c5d1SDavid du Colombier f->fd=fd; 1283e12c5d1SDavid du Colombier f->bufp=f->ebuf=f->buf; 1293e12c5d1SDavid du Colombier f->strp=0; 1303e12c5d1SDavid du Colombier return f; 1313e12c5d1SDavid du Colombier } 1323e12c5d1SDavid du Colombier io *openstr(void){ 1333e12c5d1SDavid du Colombier io *f=new(struct io); 1343e12c5d1SDavid du Colombier char *s; 1353e12c5d1SDavid du Colombier f->fd=-1; 1363e12c5d1SDavid du Colombier f->bufp=f->strp=emalloc(101); 1373e12c5d1SDavid du Colombier f->ebuf=f->bufp+100; 1383e12c5d1SDavid du Colombier for(s=f->bufp;s<=f->ebuf;s++) *s='\0'; 1393e12c5d1SDavid du Colombier return f; 1403e12c5d1SDavid du Colombier } 1413e12c5d1SDavid du Colombier /* 1423e12c5d1SDavid du Colombier * Open a corebuffer to read. EOF occurs after reading len 1433e12c5d1SDavid du Colombier * characters from buf. 1443e12c5d1SDavid du Colombier */ 1453e12c5d1SDavid du Colombier io *opencore(char *s, int len) 1463e12c5d1SDavid du Colombier { 1473e12c5d1SDavid du Colombier io *f=new(struct io); 1483e12c5d1SDavid du Colombier char *buf=emalloc(len); 1493e12c5d1SDavid du Colombier f->fd= -1 /*open("/dev/null", 0)*/; 1503e12c5d1SDavid du Colombier f->bufp=f->strp=buf; 1513e12c5d1SDavid du Colombier f->ebuf=buf+len; 1523e12c5d1SDavid du Colombier Memcpy(buf, s, len); 1533e12c5d1SDavid du Colombier return f; 1543e12c5d1SDavid du Colombier } 155*7dd7cddfSDavid du Colombier void rewind(io *io) 1563e12c5d1SDavid du Colombier { 1573e12c5d1SDavid du Colombier if(io->fd==-1) io->bufp=io->strp; 1583e12c5d1SDavid du Colombier else{ 1593e12c5d1SDavid du Colombier io->bufp=io->ebuf=io->buf; 1603e12c5d1SDavid du Colombier Seek(io->fd, 0L, 0); 1613e12c5d1SDavid du Colombier } 1623e12c5d1SDavid du Colombier } 1633e12c5d1SDavid du Colombier void closeio(io *io) 1643e12c5d1SDavid du Colombier { 1653e12c5d1SDavid du Colombier if(io->fd>=0) close(io->fd); 1663e12c5d1SDavid du Colombier if(io->strp) efree(io->strp); 1673e12c5d1SDavid du Colombier efree((char *)io); 1683e12c5d1SDavid du Colombier } 1693e12c5d1SDavid du Colombier int emptybuf(io *f) 1703e12c5d1SDavid du Colombier { 1713e12c5d1SDavid du Colombier int n; 1723e12c5d1SDavid du Colombier if(f->fd==-1 || (n=Read(f->fd, f->buf, NBUF))<=0) return EOF; 1733e12c5d1SDavid du Colombier f->bufp=f->buf; 1743e12c5d1SDavid du Colombier f->ebuf=f->buf+n; 1753e12c5d1SDavid du Colombier return *f->bufp++&0xff; 1763e12c5d1SDavid du Colombier } 177