Commit | Line | Data |
---|---|---|
de0f7d86 PK |
1 | /* Copyright (c) 1979 Regents of the University of California */ |
2 | ||
e804469b | 3 | static char sccsid[] = "@(#)yyget.c 1.3 2/11/82"; |
de0f7d86 PK |
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 | \f | |
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 | \f | |
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 | \f | |
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); | |
897df7f3 ML |
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 | ||
de0f7d86 PK |
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 ); | |
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 | \f | |
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; | |
897df7f3 | 324 | |
de0f7d86 PK |
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; | |
4449c257 ML |
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 | |
de0f7d86 PK |
347 | # ifdef PC |
348 | if ( inclev == 0 ) { | |
349 | stabsource( filename ); | |
350 | } else { | |
351 | stabinclude( filename ); | |
352 | } | |
353 | # endif PC | |
354 | inclev--; | |
355 | return (1); | |
356 | } |