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