xref: /csrg-svn/usr.bin/pascal/src/yyget.c (revision 12394)
1785Speter /* Copyright (c) 1979 Regents of the University of California */
2785Speter 
3*12394Speter static	char sccsid[] = "@(#)yyget.c 1.4 05/11/83";
4785Speter 
5785Speter #include "whoami.h"
6785Speter #include "0.h"
7785Speter #include "yy.h"
8785Speter 
9785Speter #ifdef PXP
10785Speter int	yytokcnt;
11785Speter #endif
12785Speter 
13785Speter /*
14785Speter  * Readch returns the next
15785Speter  * character from the current
16785Speter  * input line or -1 on end-of-file.
17785Speter  * It also maintains yycol for use in
18785Speter  * printing error messages.
19785Speter  */
20785Speter readch()
21785Speter {
22785Speter 	register i, c;
23785Speter 
24785Speter 	if (*bufp == '\n' && bufp >= charbuf) {
25785Speter #ifdef PXP
26785Speter 		yytokcnt = 0;
27785Speter #endif
28785Speter 		if (getline() < 0)
29785Speter 			return (-1);
30785Speter 	}
31785Speter 	c = *++bufp;
32785Speter 	if (c == '\t')
33785Speter 		yycol = ((yycol + 8) & ~7);
34785Speter 	else
35785Speter 		yycol++;
36785Speter 	return (c);
37785Speter }
38785Speter 
39785Speter /*
40785Speter  * Definitions of the structures used for the
41785Speter  * include facility.  The variable "ibp" points
42785Speter  * to the getc buffer of the current input file.
43785Speter  * There are "inclev + 1" current include files,
44785Speter  * and information in saved in the incs stack
45785Speter  * whenever a new level of include nesting occurs.
46785Speter  *
47785Speter  * Ibp in the incs structure saves the pointer
48785Speter  * to the previous levels input buffer;
49785Speter  * filename saves the previous file name;
50785Speter  * Printed saves whether the previous file name
51785Speter  * had been printed before this nesting occurred;
52785Speter  * and yyline is the line we were on on the previous file.
53785Speter  */
54785Speter 
55785Speter #define	MAXINC	10
56785Speter 
57785Speter struct inc {
58785Speter 	FILE	*ibp;
59785Speter 	char	*filename;
60785Speter 	int	Printed;
61785Speter 	int	yyline;
62785Speter 	int	yyLinpt;
63785Speter } incs[MAXINC];
64785Speter 
65*12394Speter extern	char printed;
66785Speter 
67785Speter int	inclev	= -1;
68785Speter 
69785Speter #ifdef PXP
70785Speter /*
71785Speter  * These initializations survive only if
72785Speter  * pxp is asked to pretty print one file.
73785Speter  * Otherwise they are destroyed by the initial
74785Speter  * call to getline.
75785Speter  */
76785Speter char	charbuf[CBSIZE]	= " program x(output);\n";
77785Speter int	yycol = 8;
78785Speter char	*bufp = charbuf;
79785Speter 
80785Speter #endif
81785Speter /*
82785Speter  * YyLinpt is the seek pointer to the beginning of the
83785Speter  * next line in the file.
84785Speter  */
85785Speter int	yyLinpt;
86785Speter 
87785Speter /*
88785Speter  * Getline places the next line
89785Speter  * from the input stream in the
90785Speter  * line buffer, returning -1 at YEOF.
91785Speter  */
92785Speter getline()
93785Speter {
94785Speter 	register char *cp;
95785Speter 	register CHAR c;
96785Speter #ifdef PXP
97785Speter 	static char ateof;
98785Speter #endif
99785Speter 	register FILE *ib;
100785Speter 	int i;
101785Speter 
102785Speter 	if (opt('l') && yyprtd == 0)
103785Speter 		yyoutline();
104785Speter 	yyprtd = 0;
105785Speter top:
106785Speter 	yylinpt = yyLinpt;
107785Speter 	yyline++;
108785Speter 	yyseqid++;
109785Speter 	cp = charbuf;
110785Speter 	ib = ibp;
111785Speter 	i = sizeof charbuf - 1;
112785Speter 	for (;;) {
113785Speter 		c = getc(ib);
114785Speter 		if (c == EOF) {
115785Speter 			if (uninclud())
116785Speter 				goto top;
117785Speter #ifdef PXP
118785Speter 			if (ateof == 0 && bracket) {
119785Speter 				strcpy(charbuf, "begin end.\n");
120785Speter 				ateof = 1;
121785Speter 				goto out;
122785Speter 			}
123785Speter #endif
124785Speter 			bufp = "\n";
125785Speter 			yyline--;
126785Speter 			yyseqid--;
127785Speter 			yyprtd = 1;
128785Speter 			return (-1);
129785Speter 		}
130785Speter 		*cp++ = c;
131785Speter 		if (c == '\n')
132785Speter 			break;
133785Speter 		if (--i == 0) {
134785Speter 			line = yyline;
135785Speter 			error("Input line too long - QUIT");
136785Speter 			pexit(DIED);
137785Speter 		}
138785Speter 	}
139785Speter 	*cp = 0;
140785Speter 	yyLinpt = yylinpt + cp - charbuf;
141785Speter 	if (includ())
142785Speter 		goto top;
143785Speter #ifdef PXP
144785Speter 	if (cp == &charbuf[1])
145785Speter 		commnl();
146785Speter 	else if (cp == &charbuf[2])
147785Speter 		switch (charbuf[0]) {
148785Speter 			case ' ':
149785Speter 				commnlbl();
150785Speter 				break;
151785Speter 			case '\f':
152785Speter 				commform();
153785Speter 		}
154785Speter #endif
155785Speter 	if (opt('u'))
156785Speter 		setuflg();
157785Speter out:
158785Speter 	bufp = charbuf - 1;
159785Speter 	yycol = 8;
160785Speter 	return (1);
161785Speter }
162785Speter 
163785Speter /*
164785Speter  * Check an input line to see if it is a "#include" pseudo-statement.
165785Speter  * We allow arbitrary blanks in the line and the file name
166785Speter  * may be delimited by either 's or "s.  A single semicolon
167785Speter  * may be placed after the name, but nothing else is allowed
168785Speter  */
169785Speter includ()
170785Speter {
171785Speter 	register char *cp, *dp;
172785Speter 	char ch;
173785Speter 	register struct inc *ip;
174785Speter 
175785Speter 	cp = charbuf;
176785Speter 	if (*cp++ != '#')
177785Speter 		return (0);
178785Speter 	cp = skipbl(cp);
179785Speter 	for (dp = "include"; *dp; dp++)
180785Speter 		if (*dp != *cp++)
181785Speter 			return (0);
182785Speter 	line = yyline;
183785Speter 	cp = skipbl(cp);
184785Speter 	ch = *cp++;
185785Speter 	if (ch != '\'' && ch != '"') {
186785Speter 		/*
187785Speter 		 * This should be a yerror flagging the place
188785Speter 		 * but its not worth figuring out the column.
189785Speter 		 */
190785Speter 		line = yyline;
191785Speter 		error("Include syntax error - expected ' or \" not found - QUIT");
192785Speter 		pexit(DIED);
193785Speter 	}
194785Speter 	for (dp = cp; *dp != ch; dp++)
195785Speter 		if (*dp == 0) {
196785Speter 			line = yyline;
197785Speter 			error("Missing closing %c for include file name - QUIT", ch);
198785Speter 			pexit(DIED);
199785Speter 		}
200785Speter 	*dp++ = 0;
201785Speter /*
202785Speter  *	if (*dp == ';')
203785Speter  *		dp++;
204785Speter  *	dp = skipbl(dp);
205785Speter  *	if (*dp != '\n') {
206785Speter  *		line = yyline;
207785Speter  *		error("Garbage after filename in include");
208785Speter  *		pexit(DIED);
209785Speter  *	}
210785Speter  */
211*12394Speter 	if (!dotted(cp, 'i') && !dotted(cp, 'h')) {
212785Speter 		line = yyline;
213785Speter 		error("Include filename must end in .i or .h");
214785Speter 	}
215785Speter #ifdef PXP
216785Speter 	commincl(cp, ch);
217785Speter 	if (noinclude)
218785Speter 		return (1);
219785Speter #endif
220785Speter 	inclev++;
221785Speter 	if (inclev > MAXINC) {
222785Speter 		line = yyline;
223785Speter 		error("Absurdly deep include nesting - QUIT");
224785Speter 		pexit(DIED);
225785Speter 	}
226785Speter 	ip = &incs[inclev];
227785Speter 	ip->filename = filename;
228785Speter 	filename = savestr(cp);
2295654Slinton 
2305654Slinton #ifdef OBJ
231785Speter /*
2325654Slinton  * For the debugger pdx, we need to note that we've changed files.
2335654Slinton  */
2345654Slinton 	newfile(filename, 1);
2355654Slinton #endif
2365654Slinton 
2375654Slinton /*
238785Speter  *	left over from before stdio
239785Speter  *
240785Speter  *	cp = malloc(518);
241785Speter  *	if (cp == -1) {
242785Speter  *		error("Ran out of memory (include)");
243785Speter  *		pexit(DIED);
244785Speter  *	}
245785Speter  *
246785Speter  */
247785Speter 	ip->ibp = ibp;
248785Speter 	if ( ( ibp = fopen(filename, "r" ) ) == NULL ) {
249785Speter 		perror(filename);
250785Speter 		pexit(DIED);
251785Speter 	}
252785Speter 	if (inpflist(filename)) {
253785Speter #ifdef PI
254785Speter 		opush('l');
255785Speter #endif
256785Speter #ifdef PXP
257785Speter 		opush('z');
258785Speter #endif
259785Speter 	}
260785Speter 	ip->Printed = printed;
261785Speter 	printed = 0;
262785Speter 	ip->yyline = yyline;
263785Speter 	yyline = 0;
264785Speter 	ip->yyLinpt = yyLinpt;
265785Speter 	yyLinpt = 0;
266785Speter /*
267785Speter  *	left over from before stdio
268785Speter  *
269785Speter  *	ip->ibp = ibp;
270785Speter  *	ibp = cp;
271785Speter  *
272785Speter  */
273785Speter #	ifdef PC
274785Speter 	    stabinclude( filename );
275785Speter #	endif PC
276785Speter 	return (1);
277785Speter }
278785Speter 
279785Speter skipbl(ocp)
280785Speter 	char *ocp;
281785Speter {
282785Speter 	register char *cp;
283785Speter 
284785Speter 	cp = ocp;
285785Speter 	while (*cp == ' ' || *cp == '\t')
286785Speter 		cp++;
287785Speter 	return (cp);
288785Speter }
289785Speter 
290785Speter 
291785Speter /*
292785Speter  * At the end of an include,
293785Speter  * close the file, free the input buffer,
294785Speter  * and restore the environment before
295785Speter  * the "push", including the value of
296785Speter  * the z option for pxp and the l option for pi.
297785Speter  */
298785Speter uninclud()
299785Speter {
300785Speter 	register struct inc *ip;
301785Speter 
302785Speter 	if (inclev < 0)
303785Speter 		return (0);
304785Speter /*
305785Speter  *	left over from before stdio: becomes fclose ( ibp )
306785Speter  *
307785Speter  *	close(ibp[0]);
308785Speter  *	free(ibp);
309785Speter  *
310785Speter  */
311785Speter 	fclose ( ibp );
312785Speter 	ip = &incs[inclev];
313785Speter 	ibp = ip->ibp;
314785Speter 	yyline = ip->yyline;
315785Speter 	if (inpflist(filename)) {
316785Speter #ifdef PI
317785Speter 		opop('l');
318785Speter #endif
319785Speter #ifdef PXP
320785Speter 		opop('z');
321785Speter #endif
322785Speter 	}
323785Speter 	filename = ip->filename;
3245654Slinton 
325785Speter 	yyLinpt = ip->yyLinpt;
326785Speter 	/*
327785Speter 	 * If we printed out the nested name,
328785Speter 	 * then we should print all covered names again.
329785Speter 	 * If we didn't print out the nested name
330785Speter 	 * we print the uncovered name only if it
331785Speter 	 * has not been printed before (unstack).
332785Speter 	 */
333785Speter 	if (printed) {
334785Speter 		printed = 0;
335785Speter 		while (ip >= incs) {
336785Speter 			ip->Printed = 0;
337785Speter 			ip--;
338785Speter 		}
339785Speter 	} else
340785Speter 		printed = ip->Printed;
3415757Slinton #	ifdef OBJ
3425757Slinton 	/*
3435757Slinton 	 * For the debugger pdx, we need to note that we've changed files.
3445757Slinton 	 */
3455757Slinton 	newfile(filename, yyline);
3465757Slinton #endif
347785Speter #	ifdef PC
348785Speter 	    if ( inclev == 0 ) {
349785Speter 		stabsource( filename );
350785Speter 	    } else {
351785Speter 		stabinclude( filename );
352785Speter 	    }
353785Speter #	endif PC
354785Speter 	inclev--;
355785Speter 	return (1);
356785Speter }
357