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