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