#include "rc.h"#include "exec.h"#include "io.h"#include "fns.h" enum { Stralloc = 100, }; int pfmtnest = 0; voidpfmt(io *f, char *fmt, ...){ va_list ap; char err[ERRMAX]; va_start(ap, fmt); pfmtnest++; for(;*fmt;fmt++) { if(*fmt!='%') { pchr(f, *fmt); continue; } if(*++fmt == '\0') /* "blah%"? */ break; switch(*fmt){ case 'c': pchr(f, va_arg(ap, int)); break; case 'd': pdec(f, va_arg(ap, int)); break; case 'o': poct(f, va_arg(ap, unsigned)); break; case 'p': pptr(f, va_arg(ap, void*)); break; case 'Q': pquo(f, va_arg(ap, char *)); break; case 'q': pwrd(f, va_arg(ap, char *)); break; case 'r': errstr(err, sizeof err); pstr(f, err); break; case 's': pstr(f, va_arg(ap, char *)); break; case 't': pcmd(f, va_arg(ap, struct tree *)); break; case 'v': pval(f, va_arg(ap, struct word *)); break; default: pchr(f, *fmt); break; } } va_end(ap); if(--pfmtnest==0) flush(f);} voidpchr(io *b, int c){ if(b->bufp==b->ebuf) fullbuf(b, c); else *b->bufp++=c;} intrchr(io *b){ if(b->bufp==b->ebuf) return emptybuf(b); return *b->bufp++;} voidpquo(io *f, char *s){ pchr(f, '\''); for(;*s;s++) if(*s=='\'') pfmt(f, "''"); else pchr(f, *s); pchr(f, '\'');} voidpwrd(io *f, char *s){ char *t; for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break; if(t==s || *t) pquo(f, s); else pstr(f, s);} voidpptr(io *f, void *v){ int n; uintptr p; p = (uintptr)v; if(sizeof(uintptr) == sizeof(uvlong) && p>>32) for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);} voidpstr(io *f, char *s){ if(s==0) s="(null)"; while(*s) pchr(f, *s++);} voidpdec(io *f, int n){ if(n<0){ n=-n; if(n>=0){ pchr(f, '-'); pdec(f, n); return; } /* n is two's complement minimum integer */ n = 1-n; pchr(f, '-'); pdec(f, n/10); pchr(f, n%10+'1'); return; } if(n>9) pdec(f, n/10); pchr(f, n%10+'0');} voidpoct(io *f, unsigned n){ if(n>7) poct(f, n>>3); pchr(f, (n&7)+'0');} voidpval(io *f, word *a){ if(a){ while(a->next && a->next->word){ pwrd(f, (char *)a->word); pchr(f, ' '); a = a->next; } pwrd(f, (char *)a->word); }} intfullbuf(io *f, int c){ flush(f); return *f->bufp++=c;} voidflush(io *f){ int n, len; if(f->strp){ n = f->ebuf - f->strp; len = f->bufp - f->strp; f->strp = realloc(f->strp, n+Stralloc+1); if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+Stralloc+1); f->bufp = f->strp + len; f->ebuf = f->strp + n + Stralloc; memset(f->bufp, '\0', f->ebuf-f->bufp); } else{ n = f->bufp-f->buf; if(n && Write(f->fd, f->buf, n) != n){ Write(2, "Write error\n", 12); if(ntrap) dotrap(); } f->bufp = f->buf; f->ebuf = f->buf+NBUF; }} io*openfd(int fd){ io *f = new(struct io); f->fd = fd; f->bufp = f->ebuf = f->buf; f->strp = 0; return f;} io*openstr(void){ io *f = new(struct io); f->fd = -1; f->bufp = f->strp = emalloc(Stralloc+1); f->ebuf = f->bufp + Stralloc; memset(f->bufp, '\0', Stralloc+1); return f;}/* * Open a corebuffer to read. EOF occurs after reading len * characters from buf. */ io*opencore(char *s, int len){ io *f = new(struct io); uchar *buf = emalloc(len); f->fd = -1 /*open("/dev/null", 0)*/; f->bufp = f->strp = buf; f->ebuf = buf+len; Memcpy(buf, s, len); return f;} voidrewind(io *io){ if(io->fd==-1) io->bufp = io->strp; else{ io->bufp = io->ebuf = io->buf; Seek(io->fd, 0L, 0); }} voidcloseio(io *io){ if(io->fd>=0) close(io->fd); if(io->strp) efree(io->strp); efree(io);} intemptybuf(io *f){ int n; if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF; f->bufp = f->buf; f->ebuf = f->buf + n; return *f->bufp++;}
#include "rc.h"
#include "exec.h"
#include "io.h"
#include "fns.h"
enum { Stralloc = 100, };
int pfmtnest = 0;
void
pfmt(io *f, char *fmt, ...)
{
va_list ap;
char err[ERRMAX];
va_start(ap, fmt);
pfmtnest++;
for(;*fmt;fmt++) {
if(*fmt!='%') {
pchr(f, *fmt);
continue;
}
if(*++fmt == '\0') /* "blah%"? */
break;
switch(*fmt){
case 'c':
pchr(f, va_arg(ap, int));
break;
case 'd':
pdec(f, va_arg(ap, int));
break;
case 'o':
poct(f, va_arg(ap, unsigned));
break;
case 'p':
pptr(f, va_arg(ap, void*));
break;
case 'Q':
pquo(f, va_arg(ap, char *));
break;
case 'q':
pwrd(f, va_arg(ap, char *));
break;
case 'r':
errstr(err, sizeof err); pstr(f, err);
break;
case 's':
pstr(f, va_arg(ap, char *));
break;
case 't':
pcmd(f, va_arg(ap, struct tree *));
break;
case 'v':
pval(f, va_arg(ap, struct word *));
break;
default:
pchr(f, *fmt);
break;
}
}
va_end(ap);
if(--pfmtnest==0)
flush(f);
}
void
pchr(io *b, int c)
{
if(b->bufp==b->ebuf)
fullbuf(b, c);
else *b->bufp++=c;
}
int
rchr(io *b)
{
if(b->bufp==b->ebuf)
return emptybuf(b);
return *b->bufp++;
}
void
pquo(io *f, char *s)
{
pchr(f, '\'');
for(;*s;s++)
if(*s=='\'')
pfmt(f, "''");
else pchr(f, *s);
pchr(f, '\'');
}
void
pwrd(io *f, char *s)
{
char *t;
for(t = s;*t;t++) if(*t >= 0 && needsrcquote(*t)) break;
if(t==s || *t)
pquo(f, s);
else pstr(f, s);
}
void
pptr(io *f, void *v)
{
int n;
uintptr p;
p = (uintptr)v;
if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
}
void
pstr(io *f, char *s)
{
if(s==0)
s="(null)";
while(*s) pchr(f, *s++);
}
void
pdec(io *f, int n)
{
if(n<0){
n=-n;
if(n>=0){
pchr(f, '-');
pdec(f, n);
return;
}
/* n is two's complement minimum integer */
n = 1-n;
pchr(f, '-');
pdec(f, n/10);
pchr(f, n%10+'1');
return;
}
if(n>9)
pdec(f, n/10);
pchr(f, n%10+'0');
}
void
poct(io *f, unsigned n)
{
if(n>7)
poct(f, n>>3);
pchr(f, (n&7)+'0');
}
void
pval(io *f, word *a)
{
if(a){
while(a->next && a->next->word){
pwrd(f, (char *)a->word);
pchr(f, ' ');
a = a->next;
}
pwrd(f, (char *)a->word);
}
}
int
fullbuf(io *f, int c)
{
flush(f);
return *f->bufp++=c;
}
void
flush(io *f)
{
int n, len;
if(f->strp){
n = f->ebuf - f->strp;
len = f->bufp - f->strp;
f->strp = realloc(f->strp, n+Stralloc+1);
if(f->strp==0)
panic("Can't realloc %d bytes in flush!", n+Stralloc+1);
f->bufp = f->strp + len;
f->ebuf = f->strp + n + Stralloc;
memset(f->bufp, '\0', f->ebuf-f->bufp);
}
else{
n = f->bufp-f->buf;
if(n && Write(f->fd, f->buf, n) != n){
Write(2, "Write error\n", 12);
if(ntrap)
dotrap();
}
f->bufp = f->buf;
f->ebuf = f->buf+NBUF;
}
}
io*
openfd(int fd)
{
io *f = new(struct io);
f->fd = fd;
f->bufp = f->ebuf = f->buf;
f->strp = 0;
return f;
}
io*
openstr(void)
{
io *f = new(struct io);
f->fd = -1;
f->bufp = f->strp = emalloc(Stralloc+1);
f->ebuf = f->bufp + Stralloc;
memset(f->bufp, '\0', Stralloc+1);
return f;
}
/*
* Open a corebuffer to read. EOF occurs after reading len
* characters from buf.
*/
io*
opencore(char *s, int len)
{
io *f = new(struct io);
uchar *buf = emalloc(len);
f->fd = -1 /*open("/dev/null", 0)*/;
f->bufp = f->strp = buf;
f->ebuf = buf+len;
Memcpy(buf, s, len);
return f;
}
void
rewind(io *io)
{
if(io->fd==-1)
io->bufp = io->strp;
else{
io->bufp = io->ebuf = io->buf;
Seek(io->fd, 0L, 0);
}
}
void
closeio(io *io)
{
if(io->fd>=0)
close(io->fd);
if(io->strp)
efree(io->strp);
efree(io);
}
int
emptybuf(io *f)
{
int n;
if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
f->bufp = f->buf;
f->ebuf = f->buf + n;
return *f->bufp++;
}