1 #include "rc.h" 2 #include "exec.h" 3 #include "io.h" 4 #include "fns.h" 5 int pfmtnest=0; 6 void pfmt(io *f, char *fmt, ...){ 7 va_list ap; 8 char err[ERRMAX]; 9 va_start(ap, fmt); 10 pfmtnest++; 11 for(;*fmt;fmt++) 12 if(*fmt!='%') pchr(f, *fmt); 13 else switch(*++fmt){ 14 case '\0': va_end(ap); return; 15 case 'c': pchr(f, va_arg(ap, int)); break; 16 case 'd': pdec(f, va_arg(ap, int)); break; 17 case 'o': poct(f, va_arg(ap, unsigned)); break; 18 case 'p': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/ 19 case 'Q': pquo(f, va_arg(ap, char *)); break; 20 case 'q': pwrd(f, va_arg(ap, char *)); break; 21 case 'r': errstr(err, sizeof err); pstr(f, err); break; 22 case 's': pstr(f, va_arg(ap, char *)); break; 23 case 't': pcmd(f, va_arg(ap, struct tree *)); break; 24 case 'v': pval(f, va_arg(ap, struct word *)); break; 25 default: pchr(f, *fmt); break; 26 } 27 va_end(ap); 28 if(--pfmtnest==0) flush(f); 29 } 30 void pchr(io *b, int c) 31 { 32 if(b->bufp==b->ebuf) fullbuf(b, c); 33 else *b->bufp++=c; 34 } 35 int rchr(io *b) 36 { 37 if(b->bufp==b->ebuf) return emptybuf(b); 38 return *b->bufp++ & 0xFF; 39 } 40 void pquo(io *f, char *s) 41 { 42 pchr(f, '\''); 43 for(;*s;s++) 44 if(*s=='\'') pfmt(f, "''"); 45 else pchr(f, *s); 46 pchr(f, '\''); 47 } 48 void pwrd(io *f, char *s) 49 { 50 char *t; 51 for(t=s;*t;t++) if(!wordchr(*t)) break; 52 if(t==s || *t) pquo(f, s); 53 else pstr(f, s); 54 } 55 void phex(io *f, long p) 56 { 57 int n; 58 for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); 59 } 60 void pstr(io *f, char *s) 61 { 62 if(s==0) s="(null)"; 63 while(*s) pchr(f, *s++); 64 } 65 void pdec(io *f, long n) 66 { 67 if(n<0){ 68 n=-n; 69 if(n>=0){ 70 pchr(f, '-'); 71 pdec(f, n); 72 return; 73 } 74 /* n is two's complement minimum integer */ 75 n=1-n; 76 pchr(f, '-'); 77 pdec(f, n/10); 78 pchr(f, n%10+'1'); 79 return; 80 } 81 if(n>9) pdec(f, n/10); 82 pchr(f, n%10+'0'); 83 } 84 void poct(io *f, ulong n) 85 { 86 if(n>7) poct(f, n>>3); 87 pchr(f, (n&7)+'0'); 88 } 89 void pval(io *f, word *a) 90 { 91 if(a){ 92 while(a->next && a->next->word){ 93 pwrd(f, a->word); 94 pchr(f, ' '); 95 a=a->next; 96 } 97 pwrd(f, a->word); 98 } 99 } 100 int fullbuf(io *f, int c) 101 { 102 flush(f); 103 return *f->bufp++=c; 104 } 105 void flush(io *f) 106 { 107 int n; 108 char *s; 109 if(f->strp){ 110 n=f->ebuf-f->strp; 111 f->strp=realloc(f->strp, n+101); 112 if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101); 113 f->bufp=f->strp+n; 114 f->ebuf=f->bufp+100; 115 for(s=f->bufp;s<=f->ebuf;s++) *s='\0'; 116 } 117 else{ 118 n=f->bufp-f->buf; 119 if(n && Write(f->fd, f->buf, n) < 0){ 120 Write(3, "Write error\n", 12); 121 if(ntrap) dotrap(); 122 } 123 f->bufp=f->buf; 124 f->ebuf=f->buf+NBUF; 125 } 126 } 127 io *openfd(int fd){ 128 io *f=new(struct io); 129 f->fd=fd; 130 f->bufp=f->ebuf=f->buf; 131 f->strp=0; 132 return f; 133 } 134 io *openstr(void){ 135 io *f=new(struct io); 136 char *s; 137 f->fd=-1; 138 f->bufp=f->strp=emalloc(101); 139 f->ebuf=f->bufp+100; 140 for(s=f->bufp;s<=f->ebuf;s++) *s='\0'; 141 return f; 142 } 143 /* 144 * Open a corebuffer to read. EOF occurs after reading len 145 * characters from buf. 146 */ 147 io *opencore(char *s, int len) 148 { 149 io *f=new(struct io); 150 char *buf=emalloc(len); 151 f->fd= -1 /*open("/dev/null", 0)*/; 152 f->bufp=f->strp=buf; 153 f->ebuf=buf+len; 154 Memcpy(buf, s, len); 155 return f; 156 } 157 void rewind(io *io) 158 { 159 if(io->fd==-1) io->bufp=io->strp; 160 else{ 161 io->bufp=io->ebuf=io->buf; 162 Seek(io->fd, 0L, 0); 163 } 164 } 165 void closeio(io *io) 166 { 167 if(io->fd>=0) close(io->fd); 168 if(io->strp) efree(io->strp); 169 efree((char *)io); 170 } 171 int emptybuf(io *f) 172 { 173 int n; 174 if(f->fd==-1 || (n=Read(f->fd, f->buf, NBUF))<=0) return EOF; 175 f->bufp=f->buf; 176 f->ebuf=f->buf+n; 177 return *f->bufp++&0xff; 178 } 179