#include "rc.h"
#include "exec.h"
#include "io.h"
#include "fns.h"
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);
		else switch(*++fmt){
		case '\0': va_end(ap); return;
		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': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/
		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++ & 0xFF;
}

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(!wordchr(*t)) break;
	if(t==s || *t) pquo(f, s);
	else pstr(f, s);
}
void phex(io *f, long p)
{
	int n;
	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, long 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, ulong 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, a->word);
			pchr(f, ' ');
			a=a->next;
		}
		pwrd(f, a->word);
	}
}
int fullbuf(io *f, int c)
{
	flush(f);
	return *f->bufp++=c;
}
void flush(io *f)
{
	int n;
	char *s;
	if(f->strp){
		n=f->ebuf-f->strp;
		f->strp=realloc(f->strp, n+101);
		if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101);
		f->bufp=f->strp+n;
		f->ebuf=f->bufp+100;
		for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
	}
	else{
		n=f->bufp-f->buf;
		if(n && Write(f->fd, f->buf, n) < 0){
			Write(3, "Write error\n", 12);
			if(ntrap) dotrap();
		}
		f->bufp=f->buf;
		f->ebuf=f->buf+NBUF;
	}
}
io *openfd(int fd){
	io *f;
	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);
	char *s;
	f->fd=-1;
	f->bufp=f->strp=emalloc(101);
	f->ebuf=f->bufp+100;
	for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
	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);
	char *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((char *)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++&0xff;
}
