rminnichmerge57758a716 years agoHistory
269 lines · 3.8 KB · C
RawDownload
#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++;}