Blob
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;9 void10 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 }65 void66 pchr(io *b, int c)67 {68 if(b->bufp==b->ebuf)69 fullbuf(b, c);70 else *b->bufp++=c;71 }73 int74 rchr(io *b)75 {76 if(b->bufp==b->ebuf)77 return emptybuf(b);78 return *b->bufp++ & 0xFF;79 }81 void82 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 }92 void93 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 }102 void103 pptr(io *f, void *v)104 {105 int n;106 uintptr p;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]);112 for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);113 }115 void116 pstr(io *f, char *s)117 {118 if(s==0)119 s="(null)";120 while(*s) pchr(f, *s++);121 }123 void124 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 }144 void145 poct(io *f, unsigned n)146 {147 if(n>7)148 poct(f, n>>3);149 pchr(f, (n&7)+'0');150 }152 void153 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 }165 int166 fullbuf(io *f, int c)167 {168 flush(f);169 return *f->bufp++=c;170 }172 void173 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 }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 }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 len221 * characters from buf.222 */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 }236 void237 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 }247 void248 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 }257 int258 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 }