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