Blob
1 #include "rc.h"2 #include "exec.h"3 #include "io.h"4 #include "fns.h"5 int pfmtnest = 0;7 void8 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 }60 void61 pchr(io *b, int c)62 {63 if(b->bufp==b->ebuf)64 fullbuf(b, c);65 else *b->bufp++=c;66 }68 int69 rchr(io *b)70 {71 if(b->bufp==b->ebuf)72 return emptybuf(b);73 return *b->bufp++ & 0xFF;74 }76 void77 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 }87 void88 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 }97 void98 pptr(io *f, void *v)99 {100 int n;101 uintptr p;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]);107 for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);108 }110 void111 pstr(io *f, char *s)112 {113 if(s==0)114 s="(null)";115 while(*s) pchr(f, *s++);116 }118 void119 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 }140 void141 poct(io *f, unsigned n)142 {143 if(n>7)144 poct(f, n>>3);145 pchr(f, (n&7)+'0');146 }148 void149 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 }161 int162 fullbuf(io *f, int c)163 {164 flush(f);165 return *f->bufp++=c;166 }168 void169 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 }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 }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 len217 * characters from buf.218 */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 }232 void233 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 }243 void244 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 }253 int254 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 }