#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':
			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++ & 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
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, 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 = 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;
}
