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