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