]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cpp/tokens.c
kbdfs: simplfy
[plan9front.git] / sys / src / cmd / cpp / tokens.c
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 }