xref: /csrg-svn/usr.bin/pascal/src/yyget.c (revision 785)
1*785Speter /* Copyright (c) 1979 Regents of the University of California */
2*785Speter 
3*785Speter static	char sccsid[] = "@(#)yyget.c 1.1 08/27/80";
4*785Speter 
5*785Speter #include "whoami.h"
6*785Speter #include "0.h"
7*785Speter #include "yy.h"
8*785Speter 
9*785Speter #ifdef PXP
10*785Speter int	yytokcnt;
11*785Speter #endif
12*785Speter 
13*785Speter /*
14*785Speter  * Readch returns the next
15*785Speter  * character from the current
16*785Speter  * input line or -1 on end-of-file.
17*785Speter  * It also maintains yycol for use in
18*785Speter  * printing error messages.
19*785Speter  */
20*785Speter readch()
21*785Speter {
22*785Speter 	register i, c;
23*785Speter 
24*785Speter 	if (*bufp == '\n' && bufp >= charbuf) {
25*785Speter #ifdef PXP
26*785Speter 		yytokcnt = 0;
27*785Speter #endif
28*785Speter 		if (getline() < 0)
29*785Speter 			return (-1);
30*785Speter 	}
31*785Speter 	c = *++bufp;
32*785Speter 	if (c == '\t')
33*785Speter 		yycol = ((yycol + 8) & ~7);
34*785Speter 	else
35*785Speter 		yycol++;
36*785Speter 	return (c);
37*785Speter }
38*785Speter 
39*785Speter /*
40*785Speter  * Definitions of the structures used for the
41*785Speter  * include facility.  The variable "ibp" points
42*785Speter  * to the getc buffer of the current input file.
43*785Speter  * There are "inclev + 1" current include files,
44*785Speter  * and information in saved in the incs stack
45*785Speter  * whenever a new level of include nesting occurs.
46*785Speter  *
47*785Speter  * Ibp in the incs structure saves the pointer
48*785Speter  * to the previous levels input buffer;
49*785Speter  * filename saves the previous file name;
50*785Speter  * Printed saves whether the previous file name
51*785Speter  * had been printed before this nesting occurred;
52*785Speter  * and yyline is the line we were on on the previous file.
53*785Speter  */
54*785Speter 
55*785Speter #define	MAXINC	10
56*785Speter 
57*785Speter struct inc {
58*785Speter 	FILE	*ibp;
59*785Speter 	char	*filename;
60*785Speter 	int	Printed;
61*785Speter 	int	yyline;
62*785Speter 	int	yyLinpt;
63*785Speter } incs[MAXINC];
64*785Speter 
65*785Speter extern	char *printed;
66*785Speter 
67*785Speter int	inclev	= -1;
68*785Speter 
69*785Speter #ifdef PXP
70*785Speter /*
71*785Speter  * These initializations survive only if
72*785Speter  * pxp is asked to pretty print one file.
73*785Speter  * Otherwise they are destroyed by the initial
74*785Speter  * call to getline.
75*785Speter  */
76*785Speter char	charbuf[CBSIZE]	= " program x(output);\n";
77*785Speter int	yycol = 8;
78*785Speter char	*bufp = charbuf;
79*785Speter 
80*785Speter #endif
81*785Speter /*
82*785Speter  * YyLinpt is the seek pointer to the beginning of the
83*785Speter  * next line in the file.
84*785Speter  */
85*785Speter int	yyLinpt;
86*785Speter 
87*785Speter /*
88*785Speter  * Getline places the next line
89*785Speter  * from the input stream in the
90*785Speter  * line buffer, returning -1 at YEOF.
91*785Speter  */
92*785Speter getline()
93*785Speter {
94*785Speter 	register char *cp;
95*785Speter 	register CHAR c;
96*785Speter #ifdef PXP
97*785Speter 	static char ateof;
98*785Speter #endif
99*785Speter 	register FILE *ib;
100*785Speter 	int i;
101*785Speter 
102*785Speter 	if (opt('l') && yyprtd == 0)
103*785Speter 		yyoutline();
104*785Speter 	yyprtd = 0;
105*785Speter top:
106*785Speter 	yylinpt = yyLinpt;
107*785Speter 	yyline++;
108*785Speter 	yyseqid++;
109*785Speter 	cp = charbuf;
110*785Speter 	ib = ibp;
111*785Speter 	i = sizeof charbuf - 1;
112*785Speter 	for (;;) {
113*785Speter 		c = getc(ib);
114*785Speter 		if (c == EOF) {
115*785Speter 			if (uninclud())
116*785Speter 				goto top;
117*785Speter #ifdef PXP
118*785Speter 			if (ateof == 0 && bracket) {
119*785Speter 				strcpy(charbuf, "begin end.\n");
120*785Speter 				ateof = 1;
121*785Speter 				goto out;
122*785Speter 			}
123*785Speter #endif
124*785Speter 			bufp = "\n";
125*785Speter 			yyline--;
126*785Speter 			yyseqid--;
127*785Speter 			yyprtd = 1;
128*785Speter 			return (-1);
129*785Speter 		}
130*785Speter 		*cp++ = c;
131*785Speter 		if (c == '\n')
132*785Speter 			break;
133*785Speter 		if (--i == 0) {
134*785Speter 			line = yyline;
135*785Speter 			error("Input line too long - QUIT");
136*785Speter 			pexit(DIED);
137*785Speter 		}
138*785Speter 	}
139*785Speter 	*cp = 0;
140*785Speter 	yyLinpt = yylinpt + cp - charbuf;
141*785Speter 	if (includ())
142*785Speter 		goto top;
143*785Speter #ifdef PXP
144*785Speter 	if (cp == &charbuf[1])
145*785Speter 		commnl();
146*785Speter 	else if (cp == &charbuf[2])
147*785Speter 		switch (charbuf[0]) {
148*785Speter 			case ' ':
149*785Speter 				commnlbl();
150*785Speter 				break;
151*785Speter 			case '\f':
152*785Speter 				commform();
153*785Speter 		}
154*785Speter #endif
155*785Speter 	if (opt('u'))
156*785Speter 		setuflg();
157*785Speter out:
158*785Speter 	bufp = charbuf - 1;
159*785Speter 	yycol = 8;
160*785Speter 	return (1);
161*785Speter }
162*785Speter 
163*785Speter /*
164*785Speter  * Check an input line to see if it is a "#include" pseudo-statement.
165*785Speter  * We allow arbitrary blanks in the line and the file name
166*785Speter  * may be delimited by either 's or "s.  A single semicolon
167*785Speter  * may be placed after the name, but nothing else is allowed
168*785Speter  */
169*785Speter includ()
170*785Speter {
171*785Speter 	register char *cp, *dp;
172*785Speter 	char ch;
173*785Speter 	register struct inc *ip;
174*785Speter 
175*785Speter 	cp = charbuf;
176*785Speter 	if (*cp++ != '#')
177*785Speter 		return (0);
178*785Speter 	cp = skipbl(cp);
179*785Speter 	for (dp = "include"; *dp; dp++)
180*785Speter 		if (*dp != *cp++)
181*785Speter 			return (0);
182*785Speter 	line = yyline;
183*785Speter 	cp = skipbl(cp);
184*785Speter 	ch = *cp++;
185*785Speter 	if (ch != '\'' && ch != '"') {
186*785Speter 		/*
187*785Speter 		 * This should be a yerror flagging the place
188*785Speter 		 * but its not worth figuring out the column.
189*785Speter 		 */
190*785Speter 		line = yyline;
191*785Speter 		error("Include syntax error - expected ' or \" not found - QUIT");
192*785Speter 		pexit(DIED);
193*785Speter 	}
194*785Speter 	for (dp = cp; *dp != ch; dp++)
195*785Speter 		if (*dp == 0) {
196*785Speter 			line = yyline;
197*785Speter 			error("Missing closing %c for include file name - QUIT", ch);
198*785Speter 			pexit(DIED);
199*785Speter 		}
200*785Speter 	*dp++ = 0;
201*785Speter /*
202*785Speter  *	if (*dp == ';')
203*785Speter  *		dp++;
204*785Speter  *	dp = skipbl(dp);
205*785Speter  *	if (*dp != '\n') {
206*785Speter  *		line = yyline;
207*785Speter  *		error("Garbage after filename in include");
208*785Speter  *		pexit(DIED);
209*785Speter  *	}
210*785Speter  */
211*785Speter 	if ((!dotted(cp, 'i')) && (!dotted(cp, 'h'))) {
212*785Speter 		line = yyline;
213*785Speter 		error("Include filename must end in .i or .h");
214*785Speter 	}
215*785Speter #ifdef PXP
216*785Speter 	commincl(cp, ch);
217*785Speter 	if (noinclude)
218*785Speter 		return (1);
219*785Speter #endif
220*785Speter 	inclev++;
221*785Speter 	if (inclev > MAXINC) {
222*785Speter 		line = yyline;
223*785Speter 		error("Absurdly deep include nesting - QUIT");
224*785Speter 		pexit(DIED);
225*785Speter 	}
226*785Speter 	ip = &incs[inclev];
227*785Speter 	ip->filename = filename;
228*785Speter 	filename = savestr(cp);
229*785Speter /*
230*785Speter  *	left over from before stdio
231*785Speter  *
232*785Speter  *	cp = malloc(518);
233*785Speter  *	if (cp == -1) {
234*785Speter  *		error("Ran out of memory (include)");
235*785Speter  *		pexit(DIED);
236*785Speter  *	}
237*785Speter  *
238*785Speter  */
239*785Speter 	ip->ibp = ibp;
240*785Speter 	if ( ( ibp = fopen(filename, "r" ) ) == NULL ) {
241*785Speter 		perror(filename);
242*785Speter 		pexit(DIED);
243*785Speter 	}
244*785Speter 	if (inpflist(filename)) {
245*785Speter #ifdef PI
246*785Speter 		opush('l');
247*785Speter #endif
248*785Speter #ifdef PXP
249*785Speter 		opush('z');
250*785Speter #endif
251*785Speter 	}
252*785Speter 	ip->Printed = printed;
253*785Speter 	printed = 0;
254*785Speter 	ip->yyline = yyline;
255*785Speter 	yyline = 0;
256*785Speter 	ip->yyLinpt = yyLinpt;
257*785Speter 	yyLinpt = 0;
258*785Speter /*
259*785Speter  *	left over from before stdio
260*785Speter  *
261*785Speter  *	ip->ibp = ibp;
262*785Speter  *	ibp = cp;
263*785Speter  *
264*785Speter  */
265*785Speter #	ifdef PC
266*785Speter 	    stabinclude( filename );
267*785Speter #	endif PC
268*785Speter 	return (1);
269*785Speter }
270*785Speter 
271*785Speter skipbl(ocp)
272*785Speter 	char *ocp;
273*785Speter {
274*785Speter 	register char *cp;
275*785Speter 
276*785Speter 	cp = ocp;
277*785Speter 	while (*cp == ' ' || *cp == '\t')
278*785Speter 		cp++;
279*785Speter 	return (cp);
280*785Speter }
281*785Speter 
282*785Speter 
283*785Speter /*
284*785Speter  * At the end of an include,
285*785Speter  * close the file, free the input buffer,
286*785Speter  * and restore the environment before
287*785Speter  * the "push", including the value of
288*785Speter  * the z option for pxp and the l option for pi.
289*785Speter  */
290*785Speter uninclud()
291*785Speter {
292*785Speter 	register struct inc *ip;
293*785Speter 
294*785Speter 	if (inclev < 0)
295*785Speter 		return (0);
296*785Speter /*
297*785Speter  *	left over from before stdio: becomes fclose ( ibp )
298*785Speter  *
299*785Speter  *	close(ibp[0]);
300*785Speter  *	free(ibp);
301*785Speter  *
302*785Speter  */
303*785Speter 	fclose ( ibp );
304*785Speter 	ip = &incs[inclev];
305*785Speter 	ibp = ip->ibp;
306*785Speter 	yyline = ip->yyline;
307*785Speter 	if (inpflist(filename)) {
308*785Speter #ifdef PI
309*785Speter 		opop('l');
310*785Speter #endif
311*785Speter #ifdef PXP
312*785Speter 		opop('z');
313*785Speter #endif
314*785Speter 	}
315*785Speter 	filename = ip->filename;
316*785Speter 	yyLinpt = ip->yyLinpt;
317*785Speter 	/*
318*785Speter 	 * If we printed out the nested name,
319*785Speter 	 * then we should print all covered names again.
320*785Speter 	 * If we didn't print out the nested name
321*785Speter 	 * we print the uncovered name only if it
322*785Speter 	 * has not been printed before (unstack).
323*785Speter 	 */
324*785Speter 	if (printed) {
325*785Speter 		printed = 0;
326*785Speter 		while (ip >= incs) {
327*785Speter 			ip->Printed = 0;
328*785Speter 			ip--;
329*785Speter 		}
330*785Speter 	} else
331*785Speter 		printed = ip->Printed;
332*785Speter #	ifdef PC
333*785Speter 	    if ( inclev == 0 ) {
334*785Speter 		stabsource( filename );
335*785Speter 	    } else {
336*785Speter 		stabinclude( filename );
337*785Speter 	    }
338*785Speter #	endif PC
339*785Speter 	inclev--;
340*785Speter 	return (1);
341*785Speter }
342