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