|
|
1.1 ! root 1: /* ! 2: * C preprocessor. ! 3: * Read next character. ! 4: */ ! 5: #include <time.h> ! 6: #ifdef vax ! 7: #include "INC$LIB:cc0.h" ! 8: #else ! 9: #include "cc0.h" ! 10: #endif ! 11: ! 12: /* ! 13: * Look ahead for '#' or '(', ! 14: * and restore the stream if you fail. ! 15: * This gets reentered looking for '#' ! 16: * when the search for a '(' passes newline. ! 17: */ ! 18: skipto(d) int d; ! 19: { ! 20: register char *p, *sp; ! 21: register int c; ! 22: sp = dpshp; ! 23: while ((c = get()) >= 0 && ct[c] == SKIP) ! 24: dpshc(c); ! 25: if (c >= 0) ! 26: dpshc(c); ! 27: if (c != d) { ! 28: for (p = dpshp; p < sp; ++p) ! 29: unget(*p); ! 30: dpshp = sp; ! 31: return 0; ! 32: } ! 33: dpshp = sp; ! 34: return 1; ! 35: } ! 36: ! 37: /* ! 38: * Look at a newly opened file. ! 39: */ ! 40: emptyfilep() ! 41: { ! 42: int c; ! 43: c = getc(ifp); ! 44: if (c == EOF) { ! 45: c = '\n'; ! 46: } ! 47: ungetc(c, ifp); ! 48: } ! 49: ! 50: /* ! 51: * Get a character. ! 52: * This function returns the next character, ! 53: * and implements one character pushback, ! 54: * as well as the expanded macro stack. ! 55: */ ! 56: get() ! 57: { ! 58: register int c; ! 59: ! 60: for (;;) { ! 61: switch (dstackp->ds_type) { ! 62: ! 63: case DS_FUNGET: /* Ungotten character from file */ ! 64: c = (dstackp++)->ds_char & 0377; ! 65: goto file_char; ! 66: ! 67: case DS_FILE: /* Read next character from source file */ ! 68: while ((c = getc(ifp)) < 0) { /* Pop include stack */ ! 69: eof: fclose(ifp); ! 70: if (lastchar != '\n' && lastchar != EOF) ! 71: eof_in_line: cfatal("EOF in midline"); ! 72: if (istackp < istack+NLEV) { ! 73: if (cstackp != istackp->i_cstackp) ! 74: cerror("missing #endif"); ! 75: cstackp = istackp->i_cstackp; ! 76: line = istackp->i_line; ! 77: if (notvariant(VCPP)) { ! 78: bput(LINE); ! 79: iput((ival_t)line); ! 80: } ! 81: idp = istackp->i_file; ! 82: setfname(); ! 83: ifp = istackp->i_fp; ! 84: ++istackp; ! 85: continue; ! 86: } ! 87: if (cstackp < cstack+NLEV) ! 88: cerror("missing #endif"); ! 89: cstackp = cstack + NLEV; ! 90: lastchar = c; ! 91: return c; /* ie, EOF */ ! 92: } ! 93: file_char: lastchar = c; ! 94: switch (ct[c]) { ! 95: ! 96: case SKIP: /* New line? */ ! 97: #if GEMDOS || MSDOS /* Assuming use of bingetc() */ ! 98: if (c == '\r') ! 99: continue; ! 100: #endif ! 101: if (c == '\n') { ! 102: if (incpp) { ! 103: ungetc(c, ifp); ! 104: return EOF; ! 105: } ! 106: if (instring) { ! 107: cerror("new line in %s literal", ! 108: instring=='"' ? "string" : "character"); ! 109: ++line; ! 110: c = ' '; ! 111: } else ! 112: notskip = 0; ! 113: } ! 114: notskip -= 1; ! 115: break; ! 116: ! 117: case QUEST: /* Trigraph? */ ! 118: if (notvariant(V3GRAPH)) ! 119: break; ! 120: if ((c = getc(ifp)) < 0) ! 121: goto eof_in_line; ! 122: if (c != '?') { ! 123: ungetc(c, ifp); ! 124: c = '?'; ! 125: break; ! 126: } ! 127: if ((c = getc(ifp)) < 0) ! 128: goto eof_in_line; ! 129: switch (c) { ! 130: case '=': ungetc('#', ifp); continue; ! 131: case '(': ungetc('[', ifp); continue; ! 132: case '/': ungetc('\\', ifp); continue; ! 133: case ')': ungetc(']', ifp); continue; ! 134: case '\'': ungetc('^', ifp); continue; ! 135: case '<': ungetc('{', ifp); continue; ! 136: case '!': ungetc('|', ifp); continue; ! 137: case '>': ungetc('}', ifp); continue; ! 138: case '-': ungetc('~', ifp); continue; ! 139: default: ! 140: ungetc(c, ifp); ! 141: dspushc(DS_FUNGET, '?'); ! 142: c = '?'; ! 143: } ! 144: break; ! 145: ! 146: case DIV: /* Comment? */ ! 147: if (instring) ! 148: break; ! 149: if ((c = getc(ifp))< 0) ! 150: goto eof_in_line; ! 151: if (c != '*') { ! 152: ungetc(c, ifp); ! 153: c = '/'; ! 154: break; ! 155: } ! 156: for (;;) { ! 157: if ((c = getc(ifp)) < 0) ! 158: eof_in_comment: cfatal("EOF in comment"); ! 159: if (c == '*') { ! 160: if ((c = getc(ifp)) < 0) ! 161: goto eof_in_comment; ! 162: if (c == '/') ! 163: break; ! 164: ungetc(c, ifp); ! 165: } else if (c == '/') { ! 166: if ((c = getc(ifp)) < 0) ! 167: goto eof_in_comment; ! 168: if (c == '*') ! 169: cwarn("nested comments"); ! 170: ungetc(c, ifp); ! 171: } else if (c == '\n') ! 172: ++line; ! 173: } ! 174: c = ' '; ! 175: break; ! 176: ! 177: case BACKDIV: /* Splice? */ ! 178: try_again: if ((c = getc(ifp)) < 0) ! 179: goto eof_in_line; ! 180: if (c != '\n') { ! 181: #if GEMDOS || MSDOS /* Assuming use of bingetc() */ ! 182: if (c == '\r') ! 183: goto try_again; ! 184: #endif ! 185: ungetc(c, ifp); ! 186: c = '\\'; ! 187: break; ! 188: } ! 189: ++line; ! 190: continue; ! 191: ! 192: case HIGH0: ! 193: case HIGH1: ! 194: case HIGH2: ! 195: case HIGH3: ! 196: case JUNK: ! 197: #if GEMDOS || MSDOS /* Assuming use of bingetc() */ ! 198: if (c == 26) /* ^Z */ ! 199: goto eof; ! 200: #endif ! 201: if (instring || (c > ' ' && c < 0177)) ! 202: break; ! 203: cerror("illegal cpp character (%d decimal)", c); ! 204: continue; ! 205: ! 206: case SHARP: ! 207: if (notskip != 0) ! 208: break; ! 209: ++incpp; ! 210: control(); ! 211: --incpp; ! 212: continue; ! 213: } ! 214: notskip += 1; ! 215: break; ! 216: ! 217: case DS_UNGET: /* Read ungotten character */ ! 218: c = (dstackp++)->ds_char & 0377; ! 219: break; ! 220: ! 221: case DS_STRNG: ! 222: if ((c = *dstackp->ds_ptr++ & 0377) == 0) { ! 223: ++dstackp; ! 224: continue; ! 225: } ! 226: break; ! 227: ! 228: case DS_UFILE: /* Convert file name into string */ ! 229: if ((c = *dstackp->ds_ptr++ & 0377) == 0) { ! 230: ++dstackp; ! 231: continue; ! 232: } ! 233: if (c == '\\' || c == '"') { ! 234: unget(c); ! 235: c = '\\'; ! 236: } ! 237: break; ! 238: ! 239: case DS_SHARP: /* Read and stringize */ ! 240: if ((c = *dstackp->ds_ptr++ & 0377) == 0) { ! 241: ++dstackp; ! 242: continue; ! 243: } ! 244: if (dstackp->ds_char) { ! 245: if (c == dstackp->ds_char) { ! 246: dstackp->ds_char = 0; ! 247: if (c == '"') { ! 248: unget(c); ! 249: c = '\\'; ! 250: } ! 251: } else if (c == '\\') { ! 252: c = *dstackp->ds_ptr++; ! 253: unget(c); ! 254: if (c == '"') ! 255: unget('\\'); ! 256: unget('\\'); ! 257: c = '\\'; ! 258: } ! 259: } else if (c == '"') { ! 260: dstackp->ds_char = c; ! 261: unget(c); ! 262: c = '\\'; ! 263: } else if (c == '\'') ! 264: dstackp->ds_char = c; ! 265: else if (c >= SET0) ! 266: continue; ! 267: break; ! 268: ! 269: case DS_DPUTP: ! 270: dputp = (dstackp++)->ds_ptr; ! 271: continue; ! 272: ! 273: case DS_NAME: ! 274: ++dstackp; ! 275: continue; ! 276: ! 277: case DS_IEOF: ! 278: c = EOF; ! 279: break; ! 280: ! 281: default: ! 282: cbotch("bad ds_type %d", dstackp->ds_type); ! 283: } ! 284: if (c == '\n') ++line; ! 285: if (cstate != 0 && incpp == 0) ! 286: continue; ! 287: return c; ! 288: } ! 289: } ! 290: ! 291: /* ! 292: * One character pushback ! 293: * for the callers of get(). ! 294: */ ! 295: unget(c) int c; ! 296: { ! 297: if (c < 0) ! 298: return; ! 299: dspushc(DS_UNGET, c); ! 300: if (c == '\n') ! 301: --line; ! 302: } ! 303:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.