|
|
1.1 root 1: /*
2: * n0/cpp.c
3: * C preprocessor.
4: * This version of cpp runs as a module of cc0.
5: */
6:
7: #ifdef vax
8: #include "INC$LIB:cc0.h"
9: #else
10: #include "cc0.h"
11: #endif
12:
13: /*
14: * Low-level functions and macros.
15: */
16:
17: /*
18: * Stash characters into the 'dbuf'
19: * where most things are being accumulated.
20: */
21:
22: dputc(c) int c;
23: {
24: if (dputp < dpshp)
25: *dputp++ = c;
26: else
27: dfull("dput");
28: }
29: dpshc(c) int c;
30: {
31: if (--dpshp > dputp)
32: *dpshp = c;
33: else
34: dfull("dpsh");
35: }
36: dspush(t, p) int t; char *p;
37: {
38: if (--dstackp > dlistp) {
39: dstackp->ds_type = t;
40: dstackp->ds_char = 0;
41: dstackp->ds_ptr = p;
42: } else
43: dfull("dspush");
44: }
45: dspushc(t, c) int t, c;
46: {
47: if (--dstackp > dlistp) {
48: dstackp->ds_type = t;
49: dstackp->ds_char = c;
50: dstackp->ds_ptr = 0;
51: } else
52: dfull("dspushc");
53: }
54: dslist(t, p) int t; char *p;
55: {
56: if (dlistp < dstackp) {
57: dlistp->ds_type = t;
58: dlistp->ds_char = 0;
59: (dlistp++)->ds_ptr = p;
60: } else
61: dfull("dslist");
62: }
63: dslistc(t, c) int t, c;
64: {
65: if (dlistp < dstackp) {
66: dlistp->ds_type = t;
67: dlistp->ds_char = c;
68: (dlistp++)->ds_ptr = 0;
69: } else
70: dfull("dslistc");
71: }
72:
73: dfull(where) char *where;
74: {
75: cfatal("macro expansion buffer overflow in %s", where);
76: }
77:
78: dputs(p) register char *p;
79: {
80: register int c;
81:
82: while (c = *p++) dputc(c);
83: }
84:
85: dpshs(p) register char *p;
86: {
87: register int c;
88:
89: while (c = *p++) dpshc(c);
90: }
91:
92: dputstr(d) register int d;
93: {
94: register int c;
95: instring = c = d;
96: for (;;) {
97: dputc(c);
98: if ((c = get()) < 0 || c == '\n' || c == d)
99: break;
100: if (c == '\\') {
101: dputc(c);
102: if ((c = get()) < 0 || c == '\n') {
103: dputc(' ');
104: break;
105: }
106: }
107: }
108: dputc(d);
109: instring = 0;
110: return c;
111: }
112:
113: dpshstr(d) register int d;
114: {
115: register int c;
116: instring = c = d;
117: for (;;) {
118: dpshc(c);
119: if ((c = get()) < 0 || c == '\n' || c == d)
120: break;
121: if (c == '\\') {
122: dpshc(c);
123: if ((c = get()) < 0 || c == '\n') {
124: dpshc(' ');
125: break;
126: }
127: }
128: }
129: dpshc(d);
130: instring = 0;
131: return c;
132: }
133:
134: dputnum(c) register int c;
135: {
136: ++incpp;
137: if (c == '.') {
138: unget(c = get());
139: if (c < 0 || ct[c] != CON) {
140: dputc('.');
141: --incpp;
142: return;
143: }
144: getnum(get(), 1);
145: } else
146: getnum(c, 0);
147: dputs(id);
148: --incpp;
149: }
150:
151: dpshnum(c) register int c;
152: {
153: ++incpp;
154: if (c == '.') {
155: unget(c = get());
156: if (c < 0 || ct[c] != CON) {
157: dpshc('.');
158: --incpp;
159: return;
160: }
161: getnum(get(), 1);
162: } else
163: getnum(c, 0);
164: dpshs(id);
165: --incpp;
166: }
167:
168: /*
169: * Hide set handling.
170: */
171:
172: #if OVERLAID
173: /* For the OVERLAID compiler, keep a list of malloc'ed HIDESETs to free. */
174: typedef struct hidelist {
175: struct hidelist *h_hlp;
176: HIDESET *h_hsp;
177: } HIDELIST;
178: static HIDELIST *hidelist;
179:
180: /*
181: * Release hide sets.
182: * More bother than it's worth, but tidy.
183: */
184: freehide()
185: {
186: register HIDELIST *hp;
187:
188: while ((hp = hidelist) != NULL) {
189: hidelist = hp->h_hlp;
190: free(hp->h_hsp);
191: free(hp);
192: }
193: hidefree = hidesets = NULL;
194: }
195:
196: #endif
197:
198: /* Allocate a new hide set element */
199: HIDESET *newhide()
200: {
201: register HIDESET *hp;
202: register HIDEMEM *mp;
203: register int n;
204: #if OVERLAID
205: register HIDELIST *hlp;
206: #endif
207:
208: if ((hp = hidefree) == NULL) {
209: n = 8;
210: hidefree = hp = new(n*sizeof(HIDESET));
211: #if OVERLAID
212: hlp = (HIDELIST *)new(sizeof(HIDELIST));
213: hlp->h_hlp = hidelist;
214: hlp->h_hsp = hp;
215: hidelist = hlp;
216: #endif
217: while (--n > 0) {
218: hp->h_next_set = hp+1;
219: hp->h_this_set = NULL;
220: hp += 1;
221: }
222: hp->h_next_set = NULL;
223: hp->h_this_set = NULL;
224: hp = hidefree;
225: }
226: if ((mp = hp->h_this_set) == NULL) {
227: hidefree = hp->h_next_set;
228: hp->h_next_set = NULL;
229: return hp;
230: }
231: hp->h_this_set = mp->h_next_mem;
232: mp->h_this_mem = NULL;
233: mp->h_next_mem = NULL;
234: return mp;
235: }
236:
237: /* return the HIDESET corresponding to index x */
238: HIDEMEM *hideget(x) register int x;
239: {
240: register HIDESET *hp;
241:
242: if ((x -= SET0) == 0)
243: return NULL;
244: for (hp = hidesets; --x > 0; hp = hp->h_next_set)
245: if (hp == NULL)
246: cbotch("impossible hide set");
247: return hp->h_this_set;
248: }
249:
250: /* Compare hidesets for equality */
251: hideeq(mp1, mp2) register HIDEMEM *mp1, *mp2;
252: {
253: for (;;) {
254: if (mp1 == NULL)
255: if (mp2 == NULL)
256: return 1;
257: else
258: return 0;
259: else if (mp2 == NULL)
260: return 0;
261: else if (mp1->h_this_mem != mp2->h_this_mem)
262: return 0;
263: mp1 = mp1->h_next_mem;
264: mp2 = mp2->h_next_mem;
265: }
266: }
267:
268: /* Enter a hideset into the universe and return its index */
269: hideent(mp) HIDEMEM *mp;
270: {
271: register HIDESET **hpp, *hp;
272: register int x;
273: HIDESET *tp;
274:
275: tp = hp = newhide();
276: hp->h_this_set = mp;
277: x = SET0;
278: hpp = &hidesets;
279: while ((hp = *hpp) != NULL) {
280: ++x;
281: if (hideeq(hp->h_this_set, mp)) {
282: hp = tp;
283: hp->h_next_set = hidefree;
284: hidefree = hp;
285: return x;
286: }
287: hpp = &hp->h_next_set;
288: }
289: ++x;
290: *hpp = tp;
291: return x;
292: }
293:
294: HIDEMEM *hideapp(mp1, tp) HIDEMEM *mp1; TOK *tp;
295: {
296: register HIDEMEM **mp;
297: for (mp = &mp1; *mp != NULL; mp = &((*mp)->h_next_mem))
298: ;
299: *mp = newhide();
300: (*mp)->h_this_mem = tp;
301: return mp1;
302: }
303:
304: /* Return true if the current id[] is hidden */
305: hidden()
306: {
307: register HIDEMEM *mp;
308:
309: for (mp = hideget(idhide); mp != NULL; mp = mp->h_next_mem)
310: if (idp == mp->h_this_mem)
311: return 1;
312: return 0;
313: }
314:
315: /* Return the intersection of s1 and s2 */
316: hideint(s1, s2) int s1, s2;
317: {
318: register HIDEMEM *mp1, *mp2, *mp3;
319: if (s1 == SET0)
320: return s1;
321: if (s2 == SET0)
322: return s2;
323: if (s1 == -1) {
324: return s2;
325: }
326: if (s2 == -1)
327: return s1;
328: if (s1 == s2)
329: return s1;
330: mp1 = hideget(s1);
331: mp2 = hideget(s2);
332: mp3 = NULL;
333: while (mp1 != NULL && mp2 != NULL) {
334: if (mp1->h_this_mem == mp2->h_this_mem) {
335: mp3 = hideapp(mp3, mp1->h_this_mem);
336: mp1 = mp1->h_next_mem;
337: mp2 = mp2->h_next_mem;
338: continue;
339: }
340: if (mp1->h_this_mem < mp2->h_this_mem) {
341: mp1 = mp1->h_next_mem;
342: continue;
343: }
344: if (mp2->h_this_mem < mp1->h_this_mem) {
345: mp2 = mp2->h_next_mem;
346: continue;
347: }
348: }
349: return hideent(mp3);
350: }
351:
352: /* Return the union of s1 and s2 */
353: hideaug(s1, s2) int s1, s2;
354: {
355: register HIDEMEM *mp1, *mp2, *mp3;
356: if (s1 == SET0)
357: return s2;
358: if (s2 == SET0)
359: return s1;
360: mp1 = hideget(s1);
361: mp2 = hideget(s2);
362: mp3 = NULL;
363: while (mp1 != NULL || mp2 != NULL) {
364: if (mp1 == NULL) {
365: mp3 = hideapp(mp3, mp2->h_this_mem);
366: mp2 = mp2->h_next_mem;
367: continue;
368: }
369: if (mp2 == NULL) {
370: mp3 = hideapp(mp3, mp1->h_this_mem);
371: mp1 = mp1->h_next_mem;
372: continue;
373: }
374: if (mp1->h_this_mem == mp2->h_this_mem) {
375: mp3 = hideapp(mp3, mp1->h_this_mem);
376: mp1 = mp1->h_next_mem;
377: mp2 = mp2->h_next_mem;
378: continue;
379: }
380: if (mp1->h_this_mem < mp2->h_this_mem) {
381: mp3 = hideapp(mp3, mp1->h_this_mem);
382: mp1 = mp1->h_next_mem;
383: continue;
384: }
385: if (mp2->h_this_mem < mp1->h_this_mem) {
386: mp3 = hideapp(mp3, mp2->h_this_mem);
387: mp2 = mp2->h_next_mem;
388: continue;
389: }
390: }
391: return hideent(mp3);
392: }
393:
394: /* Return the hide set for tp */
395: hideset(tp) register TOK *tp;
396: {
397: /* Determine if we are at source file level */
398: {
399: register DSTACK *dsp;
400: for (dsp = dstackp; dsp < dstack+NDLEV; dsp += 1)
401: if (dsp->ds_type == DS_NAME)
402: goto part2;
403: }
404: /* Release the previous hide set universe */
405: if (hidesets != NULL) {
406: register HIDESET **pp, *hp;
407: for (pp = &hidesets; (hp = *pp) != NULL; pp = &hp->h_next_set)
408: ;
409: *pp = hidefree;
410: hidefree = hidesets;
411: hidesets = NULL;
412: }
413: part2: return hideent(hideapp(NULL, tp));
414: }
415:
416: /*
417: * The following four functions are called from cc0 main().
418: */
419:
420: /*
421: * Install a new symbol with given value.
422: * -Dname=value
423: */
424: cppd(name, value) char *name, *value;
425: {
426: register CPPSYM *sp;
427:
428: setid(name);
429: sp = newcpp(-1, value, strlen(value)+1);
430: sp->s_sp = idp->t_sym;
431: idp->t_sym = sp;
432: }
433:
434: /*
435: * Undefine a cpp symbol.
436: * -Uname
437: */
438: cppu(name) char *name;
439: {
440: setid(name);
441: undefine();
442: }
443:
444: /*
445: * Add a directory to the list to be searched for include files.
446: * -Ipath
447: */
448: cppi(path) char *path;
449: {
450: if (ndirs >= NDIRS)
451: cfatal("too many directories in include list");
452: incdirs[ndirs++] = path;
453: }
454:
455: /*
456: * cpp loop for generating
457: * preprocessed text files.
458: * isvariant(VCPP) != 0
459: */
460: cppwork()
461: {
462: register int c, d;
463: register char *p;
464: register int myline;
465: register char *myfile;
466:
467: myfile = file;
468: myline = line;
469: while ((c = get()) >= 0) {
470: switch (ct[c]) {
471:
472: case DIV:
473: putc(c, ofp);
474: if (notvariant(VCPPC))
475: continue;
476: /*
477: * Watch out for comments in cpp -C mode,
478: * single and double quotes otherwise cause problems.
479: */
480: if ((c = get()) >= 0
481: && (c == '*' || isvariant(VCPLUS) && c == '/')) {
482: putc(c, ofp);
483: if (c == '*') {
484: /* Copy normal C-style comment. */
485: while ((c = getc(ifp)) >= 0) {
486: putc(c, ofp);
487: if (c != '*')
488: continue;
489: if ((c = getc(ifp)) >= 0) {
490: putc(c, ofp);
491: if (c != '/')
492: continue;
493: break;
494: }
495: }
496: } else {
497: /* Copy //-delimited C++ online comment. */
498: while ((c = getc(ifp)) >= 0 && c != '\n')
499: putc(c, ofp);
500: if (c == '\n')
501: ungetc(c, ifp);
502: }
503: } else
504: ungetc(c, ifp);
505: continue;
506:
507: case ID:
508: if (expand(c))
509: continue;
510: for (p = id; c = *p++; putc(c, ofp));
511: continue;
512:
513: case QUOTE:
514: case STRING:
515: putc(c, ofp);
516: instring = c;
517: while ((d = get()) >= 0 && d != c) {
518: putc(d, ofp);
519: if (d == '\\')
520: putc(get(), ofp);
521: }
522: instring = 0;
523: if (d < 0)
524: cerror("EOF in string");
525: else
526: putc(d, ofp);
527: continue;
528:
529: default:
530: putc(c, ofp);
531: if (c != '\n')
532: continue;
533: if (myfile != file) {
534: myfile = file;
535: myline = line;
536: continue;
537: }
538: if (++myline == line)
539: continue;
540: myline = line;
541: if (notvariant(VCPPE))
542: fprintf(ofp, "#line %d\n", line);
543: continue;
544: }
545: }
546: }
547:
548: /* end of n0/cpp.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.