|
|
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.