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