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