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