|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)yyget.c 1.5 7/26/83";
4:
5: #include "whoami.h"
6: #include "0.h"
7: #include "yy.h"
8:
9: #ifdef PXP
10: int yytokcnt;
11: #endif
12:
13: /*
14: * Readch returns the next
15: * character from the current
16: * input line or -1 on end-of-file.
17: * It also maintains yycol for use in
18: * printing error messages.
19: */
20: readch()
21: {
22: register i, c;
23:
24: if (*bufp == '\n' && bufp >= charbuf) {
25: #ifdef PXP
26: yytokcnt = 0;
27: #endif
28: if (getline() < 0)
29: return (-1);
30: }
31: c = *++bufp;
32: if (c == '\t')
33: yycol = ((yycol + 8) & ~7);
34: else
35: yycol++;
36: return (c);
37: }
38:
39: /*
40: * Definitions of the structures used for the
41: * include facility. The variable "ibp" points
42: * to the getc buffer of the current input file.
43: * There are "inclev + 1" current include files,
44: * and information in saved in the incs stack
45: * whenever a new level of include nesting occurs.
46: *
47: * Ibp in the incs structure saves the pointer
48: * to the previous levels input buffer;
49: * filename saves the previous file name;
50: * Printed saves whether the previous file name
51: * had been printed before this nesting occurred;
52: * and yyline is the line we were on on the previous file.
53: */
54:
55: #define MAXINC 10
56:
57: struct inc {
58: FILE *ibp;
59: char *filename;
60: int Printed;
61: int yyline;
62: int yyLinpt;
63: } incs[MAXINC];
64:
65: extern char printed;
66:
67: int inclev = -1;
68:
69: #ifdef PXP
70: /*
71: * These initializations survive only if
72: * pxp is asked to pretty print one file.
73: * Otherwise they are destroyed by the initial
74: * call to getline.
75: */
76: char charbuf[CBSIZE] = " program x(output);\n";
77: int yycol = 8;
78: char *bufp = charbuf;
79:
80: #endif
81: /*
82: * YyLinpt is the seek pointer to the beginning of the
83: * next line in the file.
84: */
85: int yyLinpt;
86:
87: /*
88: * Getline places the next line
89: * from the input stream in the
90: * line buffer, returning -1 at YEOF.
91: */
92: getline()
93: {
94: register char *cp;
95: register CHAR c;
96: #ifdef PXP
97: static char ateof;
98: #endif
99: register FILE *ib;
100: int i;
101:
102: if (opt('l') && yyprtd == 0)
103: yyoutline();
104: yyprtd = 0;
105: top:
106: yylinpt = yyLinpt;
107: yyline++;
108: yyseqid++;
109: cp = charbuf;
110: ib = ibp;
111: i = sizeof charbuf - 1;
112: for (;;) {
113: c = getc(ib);
114: if (c == EOF) {
115: if (uninclud())
116: goto top;
117: #ifdef PXP
118: if (ateof == 0 && bracket) {
119: strcpy(charbuf, "begin end.\n");
120: ateof = 1;
121: goto out;
122: }
123: #endif
124: bufp = "\n";
125: yyline--;
126: yyseqid--;
127: yyprtd = 1;
128: return (-1);
129: }
130: *cp++ = c;
131: if (c == '\n')
132: break;
133: if (--i == 0) {
134: line = yyline;
135: error("Input line too long - QUIT");
136: pexit(DIED);
137: }
138: }
139: *cp = 0;
140: yyLinpt = yylinpt + cp - charbuf;
141: if (includ())
142: goto top;
143: #ifdef PXP
144: if (cp == &charbuf[1])
145: commnl();
146: else if (cp == &charbuf[2])
147: switch (charbuf[0]) {
148: case ' ':
149: commnlbl();
150: break;
151: case '\f':
152: commform();
153: }
154: #endif
155: if (opt('u'))
156: setuflg();
157: out:
158: bufp = charbuf - 1;
159: yycol = 8;
160: return (1);
161: }
162:
163: /*
164: * Check an input line to see if it is a "#include" pseudo-statement.
165: * We allow arbitrary blanks in the line and the file name
166: * may be delimited by either 's or "s. A single semicolon
167: * may be placed after the name, but nothing else is allowed
168: */
169: includ()
170: {
171: register char *cp, *dp;
172: char ch;
173: register struct inc *ip;
174:
175: cp = charbuf;
176: if (*cp++ != '#')
177: return (0);
178: cp = skipbl(cp);
179: for (dp = "include"; *dp; dp++)
180: if (*dp != *cp++)
181: return (0);
182: line = yyline;
183: cp = skipbl(cp);
184: ch = *cp++;
185: if (ch != '\'' && ch != '"') {
186: /*
187: * This should be a yerror flagging the place
188: * but its not worth figuring out the column.
189: */
190: line = yyline;
191: error("Include syntax error - expected ' or \" not found - QUIT");
192: pexit(DIED);
193: }
194: for (dp = cp; *dp != ch; dp++)
195: if (*dp == 0) {
196: line = yyline;
197: error("Missing closing %c for include file name - QUIT", ch);
198: pexit(DIED);
199: }
200: *dp++ = 0;
201: /*
202: * if (*dp == ';')
203: * dp++;
204: * dp = skipbl(dp);
205: * if (*dp != '\n') {
206: * line = yyline;
207: * error("Garbage after filename in include");
208: * pexit(DIED);
209: * }
210: */
211: if (!dotted(cp, 'i') && !dotted(cp, 'h')) {
212: line = yyline;
213: error("Include filename must end in .i or .h");
214: }
215: #ifdef PXP
216: commincl(cp, ch);
217: if (noinclude)
218: return (1);
219: #endif
220: inclev++;
221: if (inclev > MAXINC) {
222: line = yyline;
223: error("Absurdly deep include nesting - QUIT");
224: pexit(DIED);
225: }
226: ip = &incs[inclev];
227: ip->filename = filename;
228: filename = savestr(cp);
229:
230: #ifdef OBJ
231: /*
232: * For the debugger pdx, we need to note that we've changed files.
233: */
234: newfile(filename, 1);
235: #endif
236:
237: /*
238: * left over from before stdio
239: *
240: * cp = malloc(518);
241: * if (cp == -1) {
242: * error("Ran out of memory (include)");
243: * pexit(DIED);
244: * }
245: *
246: */
247: ip->ibp = ibp;
248: if ( ( ibp = fopen(filename, "r" ) ) == NULL ) {
249: perror(filename);
250: pexit(DIED);
251: }
252: if (inpflist(filename)) {
253: #ifdef PI
254: opush('l');
255: #endif
256: #ifdef PXP
257: opush('z');
258: #endif
259: }
260: ip->Printed = printed;
261: printed = 0;
262: ip->yyline = yyline;
263: yyline = 0;
264: ip->yyLinpt = yyLinpt;
265: yyLinpt = 0;
266: /*
267: * left over from before stdio
268: *
269: * ip->ibp = ibp;
270: * ibp = cp;
271: *
272: */
273: # ifdef PC
274: stabinclude( filename , TRUE );
275: # endif PC
276: return (1);
277: }
278:
279: skipbl(ocp)
280: char *ocp;
281: {
282: register char *cp;
283:
284: cp = ocp;
285: while (*cp == ' ' || *cp == '\t')
286: cp++;
287: return (cp);
288: }
289:
290:
291: /*
292: * At the end of an include,
293: * close the file, free the input buffer,
294: * and restore the environment before
295: * the "push", including the value of
296: * the z option for pxp and the l option for pi.
297: */
298: uninclud()
299: {
300: register struct inc *ip;
301:
302: if (inclev < 0)
303: return (0);
304: /*
305: * left over from before stdio: becomes fclose ( ibp )
306: *
307: * close(ibp[0]);
308: * free(ibp);
309: *
310: */
311: fclose ( ibp );
312: ip = &incs[inclev];
313: ibp = ip->ibp;
314: yyline = ip->yyline;
315: if (inpflist(filename)) {
316: #ifdef PI
317: opop('l');
318: #endif
319: #ifdef PXP
320: opop('z');
321: #endif
322: }
323: filename = ip->filename;
324:
325: yyLinpt = ip->yyLinpt;
326: /*
327: * If we printed out the nested name,
328: * then we should print all covered names again.
329: * If we didn't print out the nested name
330: * we print the uncovered name only if it
331: * has not been printed before (unstack).
332: */
333: if (printed) {
334: printed = 0;
335: while (ip >= incs) {
336: ip->Printed = 0;
337: ip--;
338: }
339: } else
340: printed = ip->Printed;
341: # ifdef OBJ
342: /*
343: * For the debugger pdx, we need to note that we've changed files.
344: */
345: newfile(filename, yyline);
346: #endif
347: # ifdef PC
348: if ( inclev == 0 ) {
349: stabsource( filename );
350: } else {
351: stabinclude( filename , FALSE );
352: }
353: # endif PC
354: inclev--;
355: return (1);
356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.