Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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