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