plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

io.c (3932B)


      1 #include <limits.h>
      2 #include <errno.h>
      3 #include "rc.h"
      4 #include "exec.h"
      5 #include "io.h"
      6 #include "fns.h"
      7 int pfmtnest = 0;
      8 
      9 void
     10 pfmt(io *f, char *fmt, ...)
     11 {
     12 	va_list ap;
     13 	char err[ERRMAX];
     14 	va_start(ap, fmt);
     15 	pfmtnest++;
     16 	for(;*fmt;fmt++)
     17 		if(*fmt!='%')
     18 			pchr(f, *fmt);
     19 		else switch(*++fmt){
     20 		case '\0':
     21 			va_end(ap);
     22 			return;
     23 		case 'c':
     24 			pchr(f, va_arg(ap, int));
     25 			break;
     26 		case 'd':
     27 			pdec(f, va_arg(ap, int));
     28 			break;
     29 		case 'o':
     30 			poct(f, va_arg(ap, unsigned));
     31 			break;
     32 		case 'p':
     33 			pptr(f, va_arg(ap, void*));
     34 			break;
     35 		case 'Q':
     36 			pquo(f, va_arg(ap, char *));
     37 			break;
     38 		case 'q':
     39 			pwrd(f, va_arg(ap, char *));
     40 			break;
     41 		case 'r':
     42 			rerrstr(err, sizeof err); pstr(f, err);
     43 			break;
     44 		case 's':
     45 			pstr(f, va_arg(ap, char *));
     46 			break;
     47 		case 't':
     48 			pcmd(f, va_arg(ap, tree *));
     49 			break;
     50 		case 'u':
     51 			pcmdu(f, va_arg(ap, tree *));
     52 			break;
     53 		case 'v':
     54 			pval(f, va_arg(ap, struct word *));
     55 			break;
     56 		default:
     57 			pchr(f, *fmt);
     58 			break;
     59 		}
     60 	va_end(ap);
     61 	if(--pfmtnest==0)
     62 		flush(f);
     63 }
     64 
     65 void
     66 pchr(io *b, int c)
     67 {
     68 	if(b->bufp==b->ebuf)
     69 		fullbuf(b, c);
     70 	else *b->bufp++=c;
     71 }
     72 
     73 int
     74 rchr(io *b)
     75 {
     76 	if(b->bufp==b->ebuf)
     77 		return emptybuf(b);
     78 	return *b->bufp++ & 0xFF;
     79 }
     80 
     81 void
     82 pquo(io *f, char *s)
     83 {
     84 	pchr(f, '\'');
     85 	for(;*s;s++)
     86 		if(*s=='\'')
     87 			pfmt(f, "''");
     88 		else pchr(f, *s);
     89 	pchr(f, '\'');
     90 }
     91 
     92 void
     93 pwrd(io *f, char *s)
     94 {
     95 	char *t;
     96 	for(t = s;*t;t++) if(!wordchr(*t)) break;
     97 	if(t==s || *t)
     98 		pquo(f, s);
     99 	else pstr(f, s);
    100 }
    101 
    102 void
    103 pptr(io *f, void *v)
    104 {
    105 	int n;
    106 	uintptr p;
    107 
    108 	p = (uintptr)v;
    109 	if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
    110 		for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
    111 
    112 	for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
    113 }
    114 
    115 void
    116 pstr(io *f, char *s)
    117 {
    118 	if(s==0)
    119 		s="(null)";
    120 	while(*s) pchr(f, *s++);
    121 }
    122 
    123 void
    124 pdec(io *f, int n)
    125 {
    126 	if(n<0){
    127 		if(n!=INT_MIN){
    128 			pchr(f, '-');
    129 			pdec(f, -n);
    130 			return;
    131 		}
    132 		/* n is two's complement minimum integer */
    133 		n = -(INT_MIN+1);
    134 		pchr(f, '-');
    135 		pdec(f, n/10);
    136 		pchr(f, n%10+'1');
    137 		return;
    138 	}
    139 	if(n>9)
    140 		pdec(f, n/10);
    141 	pchr(f, n%10+'0');
    142 }
    143 
    144 void
    145 poct(io *f, unsigned n)
    146 {
    147 	if(n>7)
    148 		poct(f, n>>3);
    149 	pchr(f, (n&7)+'0');
    150 }
    151 
    152 void
    153 pval(io *f, word *a)
    154 {
    155 	if(a){
    156 		while(a->next && a->next->word){
    157 			pwrd(f, a->word);
    158 			pchr(f, ' ');
    159 			a = a->next;
    160 		}
    161 		pwrd(f, a->word);
    162 	}
    163 }
    164 
    165 int
    166 fullbuf(io *f, int c)
    167 {
    168 	flush(f);
    169 	return *f->bufp++=c;
    170 }
    171 
    172 void
    173 flush(io *f)
    174 {
    175 	int n;
    176 	char *s;
    177 	if(f->strp){
    178 		n = f->ebuf-f->strp;
    179 		f->strp = realloc(f->strp, n+101);
    180 		if(f->strp==0)
    181 			panic("Can't realloc %d bytes in flush!", n+101);
    182 		f->bufp = f->strp+n;
    183 		f->ebuf = f->bufp+100;
    184 		for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
    185 	}
    186 	else{
    187 		n = f->bufp-f->buf;
    188 		if(n && Write(f->fd, f->buf, n) < 0){
    189 			Write(3, "Write error\n", 12);
    190 			if(ntrap)
    191 				dotrap();
    192 		}
    193 		f->bufp = f->buf;
    194 		f->ebuf = f->buf+NBUF;
    195 	}
    196 }
    197 
    198 io*
    199 openfd(int fd)
    200 {
    201 	io *f = new(struct io);
    202 	f->fd = fd;
    203 	f->bufp = f->ebuf = f->buf;
    204 	f->strp = 0;
    205 	return f;
    206 }
    207 
    208 io*
    209 openstr(void)
    210 {
    211 	io *f = new(struct io);
    212 	char *s;
    213 	f->fd=-1;
    214 	f->bufp = f->strp = emalloc(101);
    215 	f->ebuf = f->bufp+100;
    216 	for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
    217 	return f;
    218 }
    219 /*
    220  * Open a corebuffer to read.  EOF occurs after reading len
    221  * characters from buf.
    222  */
    223 
    224 io*
    225 opencore(char *s, int len)
    226 {
    227 	io *f = new(struct io);
    228 	char *buf = emalloc(len);
    229 	f->fd= -1 /*open("/dev/null", 0)*/;
    230 	f->bufp = f->strp = buf;
    231 	f->ebuf = buf+len;
    232 	Memcpy(buf, s, len);
    233 	return f;
    234 }
    235 
    236 void
    237 iorewind(io *io)
    238 {
    239 	if(io->fd==-1)
    240 		io->bufp = io->strp;
    241 	else{
    242 		io->bufp = io->ebuf = io->buf;
    243 		Seek(io->fd, 0L, 0);
    244 	}
    245 }
    246 
    247 void
    248 closeio(io *io)
    249 {
    250 	if(io->fd>=0)
    251 		close(io->fd);
    252 	if(io->strp)
    253 		efree(io->strp);
    254 	efree((char *)io);
    255 }
    256 
    257 int
    258 emptybuf(io *f)
    259 {
    260 	int n;
    261 	if(f->fd==-1)
    262 		return EOF;
    263 Loop:
    264 	errno = 0;
    265 	n = Read(f->fd, f->buf, NBUF);
    266 	if(n < 0 && errno == EINTR)
    267 		goto Loop;
    268 	if(n <= 0)
    269 		return EOF;
    270 	f->bufp = f->buf;
    271 	f->ebuf = f->buf+n;
    272 	return *f->bufp++&0xff;
    273 }