BSD 4_1c_2 release
[unix-history] / usr / src / ucb / pascal / src / yyget.c
CommitLineData
de0f7d86
PK
1/* Copyright (c) 1979 Regents of the University of California */
2
e804469b 3static 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
10int 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 */
20readch()
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
57struct inc {
58 FILE *ibp;
59 char *filename;
60 int Printed;
61 int yyline;
62 int yyLinpt;
63} incs[MAXINC];
64
65extern char *printed;
66
67int 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 */
76char charbuf[CBSIZE] = " program x(output);\n";
77int yycol = 8;
78char *bufp = charbuf;
79
80#endif
81/*
82 * YyLinpt is the seek pointer to the beginning of the
83 * next line in the file.
84 */
85int 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 */
92getline()
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;
105top:
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();
157out:
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 */
169includ()
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
279skipbl(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 */
298uninclud()
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}