|
|
1.1 ! root 1: /* ! 2: * C preprocessor. ! 3: * This version of cpp runs as a module of cc0. ! 4: */ ! 5: #ifdef vax ! 6: #include "INC$LIB:cc0.h" ! 7: #else ! 8: #include "cc0.h" ! 9: #endif ! 10: ! 11: /* ! 12: * Define a macro. ! 13: */ ! 14: define() ! 15: { ! 16: register int c, narg; ! 17: register CPPSYM *sp; ! 18: register TOK *tp; ! 19: TOK *targ[NARGS]; ! 20: ! 21: c = getnb(); ! 22: if (c < 0 || ct[c] != ID) ! 23: goto bad; ! 24: getid(c); ! 25: tp = idp; ! 26: if ((sp = tp->t_sym) != NULL && sp->s_slevel == SL_CPP) ! 27: ; ! 28: else ! 29: sp = NULL; ! 30: /* ! 31: * Gather up the arguments. ! 32: */ ! 33: narg = -1; ! 34: if ((c = get()) == '(') { ! 35: ++narg; ! 36: do { ! 37: if ((c = getnb()) == ')') ! 38: break; ! 39: if (c<0 || ct[c]!=ID) ! 40: goto bad; ! 41: getid(c); ! 42: if (narg < NARGS) ! 43: targ[narg] = idp; ! 44: ++narg; ! 45: c = getnb(); ! 46: } while (c == ','); ! 47: if (c != ')') ! 48: goto bad; ! 49: c = getnb(); ! 50: } else if (c == ' ' || c == '\t') ! 51: c = getnb(); ! 52: /* ! 53: * Gather macro body. ! 54: */ ! 55: unget(c); ! 56: while ((c = get()) >= 0) { ! 57: switch (ct[c]) { ! 58: case QUOTE: ! 59: case STRING: ! 60: dputstr(c); ! 61: continue; ! 62: case SKIP: ! 63: unget(c = getnb()); ! 64: dputc(' '); ! 65: continue; ! 66: case SHARP: ! 67: if (nextis(c)) { ! 68: if (dputp > dbuf && dputp[-1] == ' ') ! 69: --dputp; ! 70: if (dputp == dbuf) { ! 71: cerror("## at beginning of macro"); ! 72: continue; ! 73: } ! 74: c = getnb(); ! 75: if (c < 0) { ! 76: cerror("## at end of macro"); ! 77: continue; ! 78: } ! 79: unget(c); ! 80: dputc('#'); ! 81: dputc('#'); ! 82: continue; ! 83: } ! 84: c = getnb(); ! 85: if (ct[c] != ID) { ! 86: unget(c); ! 87: c = narg; ! 88: } else { ! 89: getid(c); ! 90: for (c = 0; c < narg; c += 1) ! 91: if (idp == targ[c]) ! 92: break; ! 93: } ! 94: if (c >= narg) ! 95: cerror("parameter must follow #"); ! 96: else { ! 97: dputc('#'); ! 98: dputc(ARG0+c); ! 99: } ! 100: continue; ! 101: case CON: ! 102: case DOT: ! 103: dputnum(c); ! 104: continue; ! 105: case ID: ! 106: getid(c); ! 107: for (c = 0; c < narg; c += 1) ! 108: if (idp == targ[c]) ! 109: break; ! 110: if (c >= narg) ! 111: dputs(id); ! 112: else ! 113: dputc(ARG0+c); ! 114: continue; ! 115: default: ! 116: dputc(c); ! 117: continue; ! 118: } ! 119: } ! 120: if (dputp > dbuf && dputp[-1] == ' ') ! 121: --dputp; ! 122: dputc(0); ! 123: if (sp != NULL) { ! 124: if (sp->s_value > XUSERA ! 125: || strcmp(dbuf, sp->s_body) != 0 ! 126: || sp->s_narg != narg) ! 127: cerror("\"%s\" redefined", tp->t_id); ! 128: #if ANSI_STUPID ! 129: else ! 130: for (c = 0; c < narg; c += 1) ! 131: if (targ[c] != sp->s_targ[c]) ! 132: cerror("\"%s\" redefined", tp->t_id); ! 133: #endif ! 134: } else { ! 135: if (narg > NARGS) { ! 136: cerror("\"%s\" has too many arguments", tp->t_id); ! 137: narg = NARGS; ! 138: } ! 139: sp = newcpp(narg, dbuf, dputp-dbuf); ! 140: sp->s_sp = tp->t_sym; ! 141: tp->t_sym = sp; ! 142: #if ANSI_STUPID ! 143: if (narg > 0) { ! 144: sp->s_targ = new(narg * sizeof(TOK *)); ! 145: for (c = 0; c < sp->s_narg; c += 1) ! 146: sp->s_targ[c] = targ[c]; ! 147: } ! 148: #endif ! 149: } ! 150: dputp = dbuf; ! 151: return; ! 152: ! 153: bad: ! 154: cerror("error in #define syntax"); ! 155: while (c >= 0) ! 156: c = get(); ! 157: dputp = dbuf; ! 158: } ! 159: ! 160: /* ! 161: * Read a file name for #include or #line ! 162: * into dbuf. ! 163: * Return quote character on success, ! 164: * 0 for any kind of error. ! 165: */ ! 166: getfname() ! 167: { ! 168: register int c, d; ! 169: register char *spshp, *p; ! 170: ! 171: d = 0; ! 172: spshp = dpshp; ! 173: while ((c = getnb()) >= 0 && ct[c] == ID) ! 174: if ( ! expand(c)) ! 175: goto done; ! 176: if (c == '<') ! 177: d = '>'; ! 178: else if (c == '"') ! 179: d = c; ! 180: else ! 181: goto done; ! 182: instring = d; ! 183: while ((c=get()) >= 0 && c != d) ! 184: dpshc(c); ! 185: instring = 0; ! 186: if (c != d) ! 187: d = 0; ! 188: done: while (c >= 0) ! 189: c = get(); ! 190: for (p = spshp; --p >= dpshp; ) ! 191: dputc(*p); ! 192: dputc(0); ! 193: dpshp = spshp; ! 194: return d; ! 195: } ! 196: ! 197: /* ! 198: * File inclusion. ! 199: * incdirs[0] is always "". ! 200: */ ! 201: include() ! 202: { ! 203: register int c, d; ! 204: char *fbuf; ! 205: FILE *fp; ! 206: ! 207: if (istackp == istack) ! 208: cfatal("include stack overflow"); ! 209: if ((d = getfname()) == 0) { ! 210: dputp = dbuf; ! 211: cerror("error in #include syntax"); ! 212: return; ! 213: } ! 214: fp = NULL; ! 215: fbuf = dputp; ! 216: dputp = dbuf; ! 217: for (c = (d != '"'); c < ndirs; c += 1) { ! 218: strcpy(fbuf, incdirs[c]); ! 219: #ifdef COHERENT ! 220: if (fbuf[0] != '\0') ! 221: strcat(fbuf, "/"); ! 222: #endif ! 223: #if GEMDOS || MSDOS ! 224: if (fbuf[0] != 0 && fbuf[strlen(fbuf)-1] != '\\') ! 225: strcat(fbuf, "\\"); ! 226: #endif ! 227: strcat(fbuf, dbuf); ! 228: if ((fp=fopen(fbuf, "r")) != NULL) ! 229: break; ! 230: } ! 231: if (fp == NULL) ! 232: return cfatal("cannot open include file \"%s\"", dbuf); ! 233: --istackp; ! 234: istackp->i_fp = ifp; ! 235: istackp->i_file = tfile; ! 236: istackp->i_line = line; ! 237: istackp->i_cstackp = cstackp; ! 238: ifp = fp; ! 239: line = 1; ! 240: notskip = 0; ! 241: setid(fbuf); ! 242: setfname(); ! 243: emptyfilep(); ! 244: return; ! 245: } ! 246: ! 247: /* ! 248: * Undefine the name in 'id'. ! 249: */ ! 250: undefine() ! 251: { ! 252: register CPPSYM *sp; ! 253: ! 254: if ((sp = idp->t_sym) != NULL ! 255: && sp->s_slevel == SL_CPP ! 256: && sp->s_value <= XUSERA) { ! 257: idp->t_sym = sp->s_sp; ! 258: #if ANSI_STUPID ! 259: if (sp->s_narg > 0) ! 260: free(sp->s_targ); ! 261: #endif ! 262: free(sp); ! 263: } ! 264: } ! 265: ! 266: /* ! 267: * Read a constant expression in cpp. ! 268: * As it turns out, this will accept ! 269: * sizeof() and casts if the terms are ! 270: * defined at the time of the reference. ! 271: */ ! 272: cppexpr() ! 273: { ! 274: TREE *stp; ! 275: register TREE *tp; ! 276: register int con; ! 277: ! 278: ++incpp; ! 279: stp = talloc(); ! 280: lex(); ! 281: tp = expr(); ! 282: if (tp->t_op == ICON) ! 283: con = tp->t_ival == 0; ! 284: else if (tp->t_op == LCON) ! 285: con = tp->t_lval == 0; ! 286: else if (tp->t_op == ZCON) ! 287: con = tp->t_zval == 0; ! 288: else ! 289: cerror("constant expression required"); ! 290: treset(stp); ! 291: --incpp; ! 292: return con; ! 293: } ! 294: ! 295: /* ! 296: * Entry to process a control line ! 297: * after # has been read. ! 298: * Called from within get(). ! 299: */ ! 300: control() ! 301: { ! 302: register int c; ! 303: register SYM *sp; ! 304: register int true; ! 305: register char *p; ! 306: TOK *tp; ! 307: ! 308: unget(c = getnb()); ! 309: if (c < 0) ! 310: return; ! 311: getid('#'); ! 312: tp = idp; ! 313: if ((sp = idp->t_sym) == NULL || sp->s_slevel != SL_CPP) ! 314: goto bad; ! 315: if (cstate == 0 || sp->s_value >= XIF) ! 316: switch (sp->s_value) { ! 317: ! 318: case XDEFINE: ! 319: define(); ! 320: break; ! 321: ! 322: case XINCLUDE: ! 323: include(); ! 324: return; ! 325: ! 326: case XASSERT: ! 327: if (cppexpr()) ! 328: cerror("#assert failure"); ! 329: break; ! 330: ! 331: case XERROR: ! 332: p = dputp; ! 333: while ((c = get()) > 0) ! 334: dputc(c); ! 335: dputc(0); ! 336: cfatal("#error: %s", p); ! 337: break; ! 338: ! 339: case XPRAGMA: ! 340: break; ! 341: ! 342: case XIFDEF: ! 343: case XIFNDEF: ! 344: c = getnb(); ! 345: if (ct[c] != ID) ! 346: goto bad; ! 347: getid(c); ! 348: if (sp->s_value == XIFDEF) ! 349: true = ! ((sp = idp->t_sym) != NULL && sp->s_slevel == SL_CPP); ! 350: else ! 351: true = ((sp = idp->t_sym) != NULL && sp->s_slevel == SL_CPP); ! 352: goto new_if; ! 353: ! 354: case XIF: ! 355: /* 0 indicates a true section */ ! 356: /* 1 indicates a false section */ ! 357: /* 2 indicates a section which was true already */ ! 358: true = cstate!=0 ? 1 : cppexpr(); ! 359: new_if: ! 360: if (cstackp == cstack) ! 361: cfatal("conditional stack overflow"); ! 362: --cstackp; ! 363: cstackp->c_op = XIF; ! 364: cstackp->c_state = cstate; ! 365: cstate = cstate!=0 ? 2 : true; ! 366: break; ! 367: ! 368: case XELSE: ! 369: if (cstackp == cstack+NLEV) ! 370: cerror("#else used without #if or #ifdef"); ! 371: else if (cstackp->c_op == XELSE) ! 372: cerror("multiple #else's"); ! 373: else { ! 374: cstackp->c_op = XELSE; ! 375: cstate = cstate==1 ? 0 : 2; ! 376: } ! 377: break; ! 378: ! 379: case XELIF: ! 380: if (cstackp == cstack+NLEV) ! 381: cerror("#elif used without #if or #ifdef"); ! 382: else if (cstackp->c_op == XELSE) ! 383: cerror("#elif used after #else"); ! 384: else { ! 385: cstackp->c_op = XELIF; ! 386: cstate = cstate==1 ? cppexpr() : 2; ! 387: } ! 388: break; ! 389: ! 390: case XENDIF: ! 391: if (cstackp == cstack+NLEV) ! 392: cerror("#endif used without #if or #ifdef"); ! 393: else { ! 394: cstate = cstackp->c_state; ! 395: ++cstackp; ! 396: } ! 397: break; ! 398: ! 399: case XUNDEF: ! 400: if ((c = getnb()) < 0 || ct[c] != ID) ! 401: goto bad; ! 402: getid(c); ! 403: undefine(); ! 404: break; ! 405: ! 406: case XLINE: ! 407: while ((c = getnb()) >= 0 && ct[c] == ID) ! 408: if ( ! expand(c)) ! 409: goto bad; ! 410: if (c < 0 || ct[c] != CON) ! 411: goto bad; ! 412: getnum(c, 0); ! 413: line = ival; ! 414: c = getfname(); ! 415: dputp = dbuf; ! 416: if (c != 0) { ! 417: setid(dbuf); ! 418: setfname(); ! 419: } ! 420: break; ! 421: ! 422: default: ! 423: bad: cerror("illegal control line"); ! 424: } ! 425: while ((c = get()) >= 0) /* incpp, new line follows EOF */ ! 426: ; ! 427: } ! 428:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.