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