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 <u.h>
2
#include <libc.h>
3
#include <stdio.h>
4
#include "cpp.h"
5
 
6
static char wbuf[2*OBS];
7
static char *wbp = wbuf;
8
 
9
/*
10
 * 1 for tokens that don't need whitespace when they get inserted
11
 * by macro expansion
12
 */
13
static char wstab[] = {
14
	0,	/* END */
15
	0,	/* UNCLASS */
16
	0,	/* NAME */
17
	0,	/* NUMBER */
18
	0,	/* STRING */
19
	0,	/* CCON */
20
	1,	/* NL */
21
	0,	/* WS */
22
	0,	/* DSHARP */
23
	0,	/* EQ */
24
	0,	/* NEQ */
25
	0,	/* LEQ */
26
	0,	/* GEQ */
27
	0,	/* LSH */
28
	0,	/* RSH */
29
	0,	/* LAND */
30
	0,	/* LOR */
31
	0,	/* PPLUS */
32
	0,	/* MMINUS */
33
	0,	/* ARROW */
34
	1,	/* SBRA */
35
	1,	/* SKET */
36
	1,	/* LP */
37
	1,	/* RP */
38
	0,	/* DOT */
39
	0,	/* AND */
40
	0,	/* STAR */
41
	0,	/* PLUS */
42
	0,	/* MINUS */
43
	0,	/* TILDE */
44
	0,	/* NOT */
45
	0,	/* SLASH */
46
	0,	/* PCT */
47
	0,	/* LT */
48
	0,	/* GT */
49
	0,	/* CIRC */
50
	0,	/* OR */
51
	0,	/* QUEST */
52
	0,	/* COLON */
53
	0,	/* ASGN */
54
	1,	/* COMMA */
55
	0,	/* SHARP */
56
	1,	/* SEMIC */
57
	1,	/* CBRA */
58
	1,	/* CKET */
59
	0,	/* ASPLUS */
60
 	0,	/* ASMINUS */
61
 	0,	/* ASSTAR */
62
 	0,	/* ASSLASH */
63
 	0,	/* ASPCT */
64
 	0,	/* ASCIRC */
65
 	0,	/* ASLSH */
66
	0,	/* ASRSH */
67
 	0,	/* ASOR */
68
 	0,	/* ASAND */
69
	0,	/* ELLIPS */
70
	0,	/* DSHARP1 */
71
	0,	/* NAME1 */
72
	0,	/* DEFINED */
73
	0,	/* UMINUS */
74
};
75
 
76
void
77
maketokenrow(int size, Tokenrow *trp)
78
{
79
	trp->max = size;
80
	if (size>0)
81
		trp->bp = (Token *)domalloc(size*sizeof(Token));
82
	else
83
		trp->bp = NULL;
84
	trp->tp = trp->bp;
85
	trp->lp = trp->bp;
86
}
87
 
88
Token *
89
growtokenrow(Tokenrow *trp)
90
{
91
	int ncur = trp->tp - trp->bp;
92
	int nlast = trp->lp - trp->bp;
93
 
94
	trp->max = 3*trp->max/2 + 1;
95
	trp->bp = (Token *)realloc(trp->bp, trp->max*sizeof(Token));
96
	trp->lp = &trp->bp[nlast];
97
	trp->tp = &trp->bp[ncur];
98
	return trp->lp;
99
}
100
 
101
/*
102
 * Compare a row of tokens, ignoring the content of WS; return !=0 if different
103
 */
104
int
105
comparetokens(Tokenrow *tr1, Tokenrow *tr2)
106
{
107
	Token *tp1, *tp2;
108
 
109
	tp1 = tr1->tp;
110
	tp2 = tr2->tp;
111
	if (tr1->lp-tp1 != tr2->lp-tp2)
112
		return 1;
113
	for (; tp1<tr1->lp ; tp1++, tp2++) {
114
		if (tp1->type != tp2->type
115
		 || (tp1->wslen==0) != (tp2->wslen==0)
116
		 || tp1->len != tp2->len
117
		 || strncmp((char*)tp1->t, (char*)tp2->t, tp1->len)!=0)
118
			return 1;
119
	}
120
	return 0;
121
}
122
 
123
/*
124
 * replace ntok tokens starting at dtr->tp with the contents of str.
125
 * tp ends up pointing just beyond the replacement.
126
 * Canonical whitespace is assured on each side.
127
 */
128
void
129
insertrow(Tokenrow *dtr, int ntok, Tokenrow *str)
130
{
131
	int nrtok = rowlen(str);
132
 
133
	dtr->tp += ntok;
134
	adjustrow(dtr, nrtok-ntok);
135
	dtr->tp -= ntok;
136
	movetokenrow(dtr, str);
137
	makespace(dtr);
138
	dtr->tp += nrtok;
139
	makespace(dtr);
140
}
141
 
142
/*
143
 * make sure there is WS before trp->tp, if tokens might merge in the output
144
 */
145
void
146
makespace(Tokenrow *trp)
147
{
148
	uchar *tt;
149
	Token *tp = trp->tp;
150
 
151
	if (tp >= trp->lp)
152
		return;
153
	if (tp->wslen) {
154
		if (tp->flag&XPWS
155
		 && (wstab[tp->type] || trp->tp>trp->bp && wstab[(tp-1)->type])) {
156
			tp->wslen = 0;
157
			return;
158
		}
159
		tp->t[-1] = ' ';
160
		return;
161
	}
162
	if (wstab[tp->type] || trp->tp>trp->bp && wstab[(tp-1)->type])
163
		return;
164
	tt = newstring(tp->t, tp->len, 1);
165
	*tt++ = ' ';
166
	tp->t = tt;
167
	tp->wslen = 1;
168
	tp->flag |= XPWS;
169
}
170
 
171
/*
172
 * Copy an entire tokenrow into another, at tp.
173
 * It is assumed that there is enough space.
174
 *  Not strictly conforming.
175
 */
176
void
177
movetokenrow(Tokenrow *dtr, Tokenrow *str)
178
{
179
	int nby;
180
 
181
	/* nby = sizeof(Token) * (str->lp - str->bp); */
182
	nby = (char *)str->lp - (char *)str->bp;
183
	memmove(dtr->tp, str->bp, nby);
184
}
185
 
186
/*
187
 * Move the tokens in a row, starting at tr->tp, rightward by nt tokens;
188
 * nt may be negative (left move).
189
 * The row may need to be grown.
190
 * Non-strictly conforming because of the (char *), but easily fixed
191
 */
192
void
193
adjustrow(Tokenrow *trp, int nt)
194
{
195
	int nby, size;
196
 
197
	if (nt==0)
198
		return;
199
	size = (trp->lp - trp->bp) + nt;
200
	while (size > trp->max)
201
		growtokenrow(trp);
202
	/* nby = sizeof(Token) * (trp->lp - trp->tp); */
203
	nby = (char *)trp->lp - (char *)trp->tp;
204
	if (nby)
205
		memmove(trp->tp+nt, trp->tp, nby);
206
	trp->lp += nt;
207
}
208
 
209
/*
210
 * Copy a row of tokens into the destination holder, allocating
211
 * the space for the contents.  Return the destination.
212
 */
213
Tokenrow *
214
copytokenrow(Tokenrow *dtr, Tokenrow *str)
215
{
216
	int len = rowlen(str);
217
 
218
	maketokenrow(len, dtr);
219
	movetokenrow(dtr, str);
220
	dtr->lp += len;
221
	return dtr;
222
}
223
 
224
/*
225
 * Produce a copy of a row of tokens.  Start at trp->tp.
226
 * The value strings are copied as well.  The first token
227
 * has WS available.
228
 */
229
Tokenrow *
230
normtokenrow(Tokenrow *trp)
231
{
232
	Token *tp;
233
	Tokenrow *ntrp = new(Tokenrow);
234
	int len;
235
 
236
	len = trp->lp - trp->tp;
237
	if (len<=0)
238
		len = 1;
239
	maketokenrow(len, ntrp);
240
	for (tp=trp->tp; tp < trp->lp; tp++) {
241
		*ntrp->lp = *tp;
242
		if (tp->len) {
243
			ntrp->lp->t = newstring(tp->t, tp->len, 1);
244
			*ntrp->lp->t++ = ' ';
245
			if (tp->wslen)
246
				ntrp->lp->wslen = 1;
247
		}
248
		ntrp->lp++;
249
	}
250
	if (ntrp->lp > ntrp->bp)
251
		ntrp->bp->wslen = 0;
252
	return ntrp;
253
}
254
 
255
/*
256
 * Debugging
257
 */
258
void
259
peektokens(Tokenrow *trp, char *str)
260
{
261
	Token *tp;
262
	int c;
263
 
264
	tp = trp->tp;
265
	flushout();
266
	if (str)
267
		fprintf(stderr, "%s ", str);
268
	if (tp<trp->bp || tp>trp->lp)
269
		fprintf(stderr, "(tp offset %d) ", tp-trp->bp);
270
	for (tp=trp->bp; tp<trp->lp && tp<trp->bp+32; tp++) {
271
		if (tp->type!=NL) {
272
			c = tp->t[tp->len];
273
			tp->t[tp->len] = 0;
274
			fprintf(stderr, "%s", tp->t, tp->len);
275
			tp->t[tp->len] = c;
276
		}
277
		if (tp->type==NAME) {
278
			fprintf(stderr, tp==trp->tp?"{*":"{");
279
			prhideset(tp->hideset);
280
			fprintf(stderr, "} ");
281
		} else
282
			fprintf(stderr, tp==trp->tp?"{%x*} ":"{%x} ", tp->type);
283
	}
284
	fprintf(stderr, "\n");
285
	fflush(stderr);
286
}
287
 
288
void
289
puttokens(Tokenrow *trp)
290
{
291
	Token *tp;
292
	int len;
293
	uchar *p;
294
 
295
	if (verbose)
296
		peektokens(trp, "");
297
	tp = trp->bp;
298
	for (; tp<trp->lp; tp++) {
299
		len = tp->len+tp->wslen;
300
		p = tp->t-tp->wslen;
301
		while (tp<trp->lp-1 && p+len == (tp+1)->t - (tp+1)->wslen) {
302
			tp++;
303
			len += tp->wslen+tp->len;
304
		}
305
		if (Mflag==0) {
306
			if (len>OBS/2) {		/* handle giant token */
307
				if (wbp > wbuf)
308
					write(1, wbuf, wbp-wbuf);
309
				write(1, p, len);
310
				wbp = wbuf;
311
			} else {	
312
				memcpy(wbp, p, len);
313
				wbp += len;
314
			}
315
		}
316
		if (wbp >= &wbuf[OBS]) {
317
			write(1, wbuf, OBS);
318
			if (wbp > &wbuf[OBS])
319
				memcpy(wbuf, wbuf+OBS, wbp - &wbuf[OBS]);
320
			wbp -= OBS;
321
		}
322
	}
323
	trp->tp = tp;
324
	if (cursource->fd==0)
325
		flushout();
326
}
327
 
328
void
329
flushout(void)
330
{
331
	if (wbp>wbuf) {
332
		write(1, wbuf, wbp-wbuf);
333
		wbp = wbuf;
334
	}
335
}
336
 
337
/*
338
 * turn a row into just a newline
339
 */
340
void
341
setempty(Tokenrow *trp)
342
{
343
	trp->tp = trp->bp;
344
	trp->lp = trp->bp+1;
345
	*trp->bp = nltoken;
346
}
347
 
348
/*
349
 * generate a number
350
 */
351
char *
352
outnum(char *p, int n)
353
{
354
	if (n>=10)
355
		p = outnum(p, n/10);
356
	*p++ = n%10 + '0';
357
	return p;
358
}
359
 
360
/*
361
 * allocate and initialize a new string from s, of length l, at offset o
362
 * Null terminated.
363
 */
364
uchar *
365
newstring(uchar *s, int l, int o)
366
{
367
	uchar *ns = (uchar *)domalloc(l+o+1);
368
 
369
	ns[l+o] = '\0';
370
	return (uchar*)strncpy((char*)ns+o, (char*)s, l) - o;
371
}