xref: /plan9/sys/src/cmd/rc/io.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include "rc.h"
23e12c5d1SDavid du Colombier #include "exec.h"
33e12c5d1SDavid du Colombier #include "io.h"
43e12c5d1SDavid du Colombier #include "fns.h"
53e12c5d1SDavid du Colombier int pfmtnest=0;
63e12c5d1SDavid du Colombier void pfmt(io *f, char *fmt, ...){
73e12c5d1SDavid du Colombier 	va_list ap;
83e12c5d1SDavid du Colombier 	va_start(ap, fmt);
93e12c5d1SDavid du Colombier 	pfmtnest++;
103e12c5d1SDavid du Colombier 	for(;*fmt;fmt++)
113e12c5d1SDavid du Colombier 		if(*fmt!='%') pchr(f, *fmt);
123e12c5d1SDavid du Colombier 		else switch(*++fmt){
133e12c5d1SDavid du Colombier 		case '\0': va_end(ap); return;
143e12c5d1SDavid du Colombier 		case 'c': pchr(f, va_arg(ap, int)); break;
153e12c5d1SDavid du Colombier 		case 'd': pdec(f, va_arg(ap, int)); break;
163e12c5d1SDavid du Colombier 		case 'o': poct(f, va_arg(ap, unsigned)); break;
173e12c5d1SDavid du Colombier 		case 'p': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/
183e12c5d1SDavid du Colombier 		case 'Q': pquo(f, va_arg(ap, char *)); break;
193e12c5d1SDavid du Colombier 		case 'q': pwrd(f, va_arg(ap, char *)); break;
203e12c5d1SDavid du Colombier 		case 's': pstr(f, va_arg(ap, char *)); break;
213e12c5d1SDavid du Colombier 		case 't': pcmd(f, va_arg(ap, struct tree *)); break;
223e12c5d1SDavid du Colombier 		case 'v': pval(f, va_arg(ap, struct word *)); break;
233e12c5d1SDavid du Colombier 		default: pchr(f, *fmt); break;
243e12c5d1SDavid du Colombier 		}
253e12c5d1SDavid du Colombier 	va_end(ap);
263e12c5d1SDavid du Colombier 	if(--pfmtnest==0) flush(f);
273e12c5d1SDavid du Colombier }
28*7dd7cddfSDavid du Colombier void pchr(io *b, int c)
29*7dd7cddfSDavid du Colombier {
30*7dd7cddfSDavid du Colombier 	if(b->bufp==b->ebuf) fullbuf(b, c);
31*7dd7cddfSDavid du Colombier 	else *b->bufp++=c;
32*7dd7cddfSDavid du Colombier }
33*7dd7cddfSDavid du Colombier int rchr(io *b)
34*7dd7cddfSDavid du Colombier {
35*7dd7cddfSDavid du Colombier 	if(b->bufp==b->ebuf) return emptybuf(b);
36*7dd7cddfSDavid du Colombier 	return *b->bufp++ & 0xFF;
37*7dd7cddfSDavid du Colombier }
383e12c5d1SDavid du Colombier void pquo(io *f, char *s)
393e12c5d1SDavid du Colombier {
403e12c5d1SDavid du Colombier 	pchr(f, '\'');
413e12c5d1SDavid du Colombier 	for(;*s;s++)
423e12c5d1SDavid du Colombier 		if(*s=='\'') pfmt(f, "''");
433e12c5d1SDavid du Colombier 		else pchr(f, *s);
443e12c5d1SDavid du Colombier 	pchr(f, '\'');
453e12c5d1SDavid du Colombier }
463e12c5d1SDavid du Colombier void pwrd(io *f, char *s)
473e12c5d1SDavid du Colombier {
483e12c5d1SDavid du Colombier 	char *t;
493e12c5d1SDavid du Colombier 	for(t=s;*t;t++) if(!wordchr(*t)) break;
503e12c5d1SDavid du Colombier 	if(t==s || *t) pquo(f, s);
513e12c5d1SDavid du Colombier 	else pstr(f, s);
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier void phex(io *f, long p)
543e12c5d1SDavid du Colombier {
553e12c5d1SDavid du Colombier 	int n;
563e12c5d1SDavid du Colombier 	for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
573e12c5d1SDavid du Colombier }
583e12c5d1SDavid du Colombier void pstr(io *f, char *s)
593e12c5d1SDavid du Colombier {
603e12c5d1SDavid du Colombier 	if(s==0) s="(null)";
613e12c5d1SDavid du Colombier 	while(*s) pchr(f, *s++);
623e12c5d1SDavid du Colombier }
633e12c5d1SDavid du Colombier void pdec(io *f, long n)
643e12c5d1SDavid du Colombier {
653e12c5d1SDavid du Colombier 	if(n<0){
663e12c5d1SDavid du Colombier 		n=-n;
673e12c5d1SDavid du Colombier 		if(n>=0){
683e12c5d1SDavid du Colombier 			pchr(f, '-');
693e12c5d1SDavid du Colombier 			pdec(f, n);
703e12c5d1SDavid du Colombier 			return;
713e12c5d1SDavid du Colombier 		}
723e12c5d1SDavid du Colombier 		/* n is two's complement minimum integer */
733e12c5d1SDavid du Colombier 		n=1-n;
743e12c5d1SDavid du Colombier 		pchr(f, '-');
753e12c5d1SDavid du Colombier 		pdec(f, n/10);
763e12c5d1SDavid du Colombier 		pchr(f, n%10+'1');
773e12c5d1SDavid du Colombier 		return;
783e12c5d1SDavid du Colombier 	}
793e12c5d1SDavid du Colombier 	if(n>9) pdec(f, n/10);
803e12c5d1SDavid du Colombier 	pchr(f, n%10+'0');
813e12c5d1SDavid du Colombier }
823e12c5d1SDavid du Colombier void poct(io *f, ulong n)
833e12c5d1SDavid du Colombier {
843e12c5d1SDavid du Colombier 	if(n>7) poct(f, n>>3);
853e12c5d1SDavid du Colombier 	pchr(f, (n&7)+'0');
863e12c5d1SDavid du Colombier }
873e12c5d1SDavid du Colombier void pval(io *f, word *a)
883e12c5d1SDavid du Colombier {
893e12c5d1SDavid du Colombier 	if(a){
903e12c5d1SDavid du Colombier 		while(a->next && a->next->word){
913e12c5d1SDavid du Colombier 			pwrd(f, a->word);
923e12c5d1SDavid du Colombier 			pchr(f, ' ');
933e12c5d1SDavid du Colombier 			a=a->next;
943e12c5d1SDavid du Colombier 		}
953e12c5d1SDavid du Colombier 		pwrd(f, a->word);
963e12c5d1SDavid du Colombier 	}
973e12c5d1SDavid du Colombier }
983e12c5d1SDavid du Colombier int fullbuf(io *f, int c)
993e12c5d1SDavid du Colombier {
1003e12c5d1SDavid du Colombier 	flush(f);
1013e12c5d1SDavid du Colombier 	return *f->bufp++=c;
1023e12c5d1SDavid du Colombier }
1033e12c5d1SDavid du Colombier void flush(io *f)
1043e12c5d1SDavid du Colombier {
1053e12c5d1SDavid du Colombier 	int n;
1063e12c5d1SDavid du Colombier 	char *s;
1073e12c5d1SDavid du Colombier 	if(f->strp){
1083e12c5d1SDavid du Colombier 		n=f->ebuf-f->strp;
1093e12c5d1SDavid du Colombier 		f->strp=realloc(f->strp, n+101);
1103e12c5d1SDavid du Colombier 		if(f->strp==0) panic("Can't realloc %d bytes in flush!", n+101);
1113e12c5d1SDavid du Colombier 		f->bufp=f->strp+n;
1123e12c5d1SDavid du Colombier 		f->ebuf=f->bufp+100;
1133e12c5d1SDavid du Colombier 		for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
1143e12c5d1SDavid du Colombier 	}
1153e12c5d1SDavid du Colombier 	else{
1163e12c5d1SDavid du Colombier 		n=f->bufp-f->buf;
1173e12c5d1SDavid du Colombier 		if(n && Write(f->fd, f->buf, n) < 0){
1183e12c5d1SDavid du Colombier 			Write(3, "Write error\n", 12);
1193e12c5d1SDavid du Colombier 			if(ntrap) dotrap();
1203e12c5d1SDavid du Colombier 		}
1213e12c5d1SDavid du Colombier 		f->bufp=f->buf;
1223e12c5d1SDavid du Colombier 		f->ebuf=f->buf+NBUF;
1233e12c5d1SDavid du Colombier 	}
1243e12c5d1SDavid du Colombier }
1253e12c5d1SDavid du Colombier io *openfd(int fd){
1263e12c5d1SDavid du Colombier 	io *f=new(struct io);
1273e12c5d1SDavid du Colombier 	f->fd=fd;
1283e12c5d1SDavid du Colombier 	f->bufp=f->ebuf=f->buf;
1293e12c5d1SDavid du Colombier 	f->strp=0;
1303e12c5d1SDavid du Colombier 	return f;
1313e12c5d1SDavid du Colombier }
1323e12c5d1SDavid du Colombier io *openstr(void){
1333e12c5d1SDavid du Colombier 	io *f=new(struct io);
1343e12c5d1SDavid du Colombier 	char *s;
1353e12c5d1SDavid du Colombier 	f->fd=-1;
1363e12c5d1SDavid du Colombier 	f->bufp=f->strp=emalloc(101);
1373e12c5d1SDavid du Colombier 	f->ebuf=f->bufp+100;
1383e12c5d1SDavid du Colombier 	for(s=f->bufp;s<=f->ebuf;s++) *s='\0';
1393e12c5d1SDavid du Colombier 	return f;
1403e12c5d1SDavid du Colombier }
1413e12c5d1SDavid du Colombier /*
1423e12c5d1SDavid du Colombier  * Open a corebuffer to read.  EOF occurs after reading len
1433e12c5d1SDavid du Colombier  * characters from buf.
1443e12c5d1SDavid du Colombier  */
1453e12c5d1SDavid du Colombier io *opencore(char *s, int len)
1463e12c5d1SDavid du Colombier {
1473e12c5d1SDavid du Colombier 	io *f=new(struct io);
1483e12c5d1SDavid du Colombier 	char *buf=emalloc(len);
1493e12c5d1SDavid du Colombier 	f->fd= -1 /*open("/dev/null", 0)*/;
1503e12c5d1SDavid du Colombier 	f->bufp=f->strp=buf;
1513e12c5d1SDavid du Colombier 	f->ebuf=buf+len;
1523e12c5d1SDavid du Colombier 	Memcpy(buf, s, len);
1533e12c5d1SDavid du Colombier 	return f;
1543e12c5d1SDavid du Colombier }
155*7dd7cddfSDavid du Colombier void rewind(io *io)
1563e12c5d1SDavid du Colombier {
1573e12c5d1SDavid du Colombier 	if(io->fd==-1) io->bufp=io->strp;
1583e12c5d1SDavid du Colombier 	else{
1593e12c5d1SDavid du Colombier 		io->bufp=io->ebuf=io->buf;
1603e12c5d1SDavid du Colombier 		Seek(io->fd, 0L, 0);
1613e12c5d1SDavid du Colombier 	}
1623e12c5d1SDavid du Colombier }
1633e12c5d1SDavid du Colombier void closeio(io *io)
1643e12c5d1SDavid du Colombier {
1653e12c5d1SDavid du Colombier 	if(io->fd>=0) close(io->fd);
1663e12c5d1SDavid du Colombier 	if(io->strp) efree(io->strp);
1673e12c5d1SDavid du Colombier 	efree((char *)io);
1683e12c5d1SDavid du Colombier }
1693e12c5d1SDavid du Colombier int emptybuf(io *f)
1703e12c5d1SDavid du Colombier {
1713e12c5d1SDavid du Colombier 	int n;
1723e12c5d1SDavid du Colombier 	if(f->fd==-1 || (n=Read(f->fd, f->buf, NBUF))<=0) return EOF;
1733e12c5d1SDavid du Colombier 	f->bufp=f->buf;
1743e12c5d1SDavid du Colombier 	f->ebuf=f->buf+n;
1753e12c5d1SDavid du Colombier 	return *f->bufp++&0xff;
1763e12c5d1SDavid du Colombier }
177