xref: /csrg-svn/usr.bin/pascal/pxp/yyget.c (revision 62195)
148112Sbostic /*-
2*62195Sbostic  * Copyright (c) 1980, 1993
3*62195Sbostic  *	The Regents of the University of California.  All rights reserved.
448112Sbostic  *
548112Sbostic  * %sccs.include.redist.c%
648111Sbostic  */
748111Sbostic 
848111Sbostic #ifndef lint
9*62195Sbostic static char sccsid[] = "@(#)yyget.c	8.1 (Berkeley) 06/06/93";
1048112Sbostic #endif /* not lint */
1148111Sbostic 
1248111Sbostic #include "whoami.h"
1348111Sbostic #include <0.h>
1448111Sbostic #include "tree_ty.h"	/* must be included for yy.h */
1548111Sbostic #include "yy.h"
1648111Sbostic 
1748111Sbostic #ifdef PXP
1848111Sbostic int	yytokcnt;
1948111Sbostic #endif
2048111Sbostic 
2148111Sbostic /*
2248111Sbostic  * Readch returns the next
2348111Sbostic  * character from the current
2448111Sbostic  * input line or -1 on end-of-file.
2548111Sbostic  * It also maintains yycol for use in
2648111Sbostic  * printing error messages.
2748111Sbostic  */
readch()2848111Sbostic readch()
2948111Sbostic {
3048111Sbostic 	register c;
3148111Sbostic 
3248111Sbostic 	if (*bufp == '\n' && bufp >= charbuf) {
3348111Sbostic #ifdef PXP
3448111Sbostic 		yytokcnt = 0;
3548111Sbostic #endif
3648111Sbostic 		if (getline() < 0)
3748111Sbostic 			return (-1);
3848111Sbostic 	}
3948111Sbostic 	c = *++bufp;
4048111Sbostic 	if (c == '\t')
4148111Sbostic 		yycol = ((yycol + 8) & ~7);
4248111Sbostic 	else
4348111Sbostic 		yycol++;
4448111Sbostic 	return (c);
4548111Sbostic }
4648111Sbostic 
4748111Sbostic /*
4848111Sbostic  * Definitions of the structures used for the
4948111Sbostic  * include facility.  The variable "ibp" points
5048111Sbostic  * to the getc buffer of the current input file.
5148111Sbostic  * There are "inclev + 1" current include files,
5248111Sbostic  * and information in saved in the incs stack
5348111Sbostic  * whenever a new level of include nesting occurs.
5448111Sbostic  *
5548111Sbostic  * Ibp in the incs structure saves the pointer
5648111Sbostic  * to the previous levels input buffer;
5748111Sbostic  * filename saves the previous file name;
5848111Sbostic  * Printed saves whether the previous file name
5948111Sbostic  * had been printed before this nesting occurred;
6048111Sbostic  * and yyline is the line we were on on the previous file.
6148111Sbostic  */
6248111Sbostic 
6348111Sbostic #define	MAXINC	10
6448111Sbostic 
6548111Sbostic struct inc {
6648111Sbostic 	FILE	*ibp;
6748111Sbostic 	char	*filename;
6848111Sbostic 	int	Printed;
6948111Sbostic 	int	yyline;
7048111Sbostic 	int	yyLinpt;
7148111Sbostic } incs[MAXINC];
7248111Sbostic 
7348111Sbostic extern	char printed;
7448111Sbostic 
7548111Sbostic int	inclev	= -1;
7648111Sbostic 
7748111Sbostic #ifdef PXP
7848111Sbostic /*
7948111Sbostic  * These initializations survive only if
8048111Sbostic  * pxp is asked to pretty print one file.
8148111Sbostic  * Otherwise they are destroyed by the initial
8248111Sbostic  * call to getline.
8348111Sbostic  */
8448111Sbostic char	charbuf[CBSIZE]	= " program x(output);\n";
8548111Sbostic int	yycol = 8;
8648111Sbostic char	*bufp = charbuf;
8748111Sbostic 
8848111Sbostic #endif
8948111Sbostic /*
9048111Sbostic  * YyLinpt is the seek pointer to the beginning of the
9148111Sbostic  * next line in the file.
9248111Sbostic  */
9348111Sbostic int	yyLinpt;
9448111Sbostic 
9548111Sbostic /*
9648111Sbostic  * Getline places the next line
9748111Sbostic  * from the input stream in the
9848111Sbostic  * line buffer, returning -1 at YEOF.
9948111Sbostic  */
getline()10048111Sbostic getline()
10148111Sbostic {
10248111Sbostic 	register char *cp;
10348111Sbostic 	register CHAR c;
10448111Sbostic #ifdef PXP
10548111Sbostic 	static char ateof;
10648111Sbostic #endif
10748111Sbostic 	register FILE *ib;
10848111Sbostic 	int i;
10948111Sbostic 
11048111Sbostic 	if (opt('l') && yyprtd == 0)
11148111Sbostic 		yyoutline();
11248111Sbostic 	yyprtd = 0;
11348111Sbostic top:
11448111Sbostic 	yylinpt = yyLinpt;
11548111Sbostic 	yyline++;
11648111Sbostic 	yyseqid++;
11748111Sbostic 	cp = charbuf;
11848111Sbostic 	ib = ibp;
11948111Sbostic 	i = sizeof charbuf - 1;
12048111Sbostic 	for (;;) {
12148111Sbostic 		c = getc(ib);
12248111Sbostic 		if (c == EOF) {
12348111Sbostic 			if (uninclud())
12448111Sbostic 				goto top;
12548111Sbostic #ifdef PXP
12648111Sbostic 			if (ateof == 0 && bracket) {
12748111Sbostic 				(void) pstrcpy(charbuf, "begin end.\n");
12848111Sbostic 				ateof = 1;
12948111Sbostic 				goto out;
13048111Sbostic 			}
13148111Sbostic #endif
13248111Sbostic 			bufp = "\n";
13348111Sbostic 			yyline--;
13448111Sbostic 			yyseqid--;
13548111Sbostic 			yyprtd = 1;
13648111Sbostic 			return (-1);
13748111Sbostic 		}
13848111Sbostic 		*cp++ = c;
13948111Sbostic 		if (c == '\n')
14048111Sbostic 			break;
14148111Sbostic 		if (--i == 0) {
14248111Sbostic 			line = yyline;
14348111Sbostic 			error("Input line too long - QUIT");
14448111Sbostic 			pexit(DIED);
14548111Sbostic 		}
14648111Sbostic 	}
14748111Sbostic 	*cp = 0;
14848111Sbostic 	yyLinpt = yylinpt + cp - charbuf;
14948111Sbostic 	if (includ())
15048111Sbostic 		goto top;
15148111Sbostic #ifdef PXP
15248111Sbostic 	if (cp == &charbuf[1])
15348111Sbostic 		commnl();
15448111Sbostic 	else if (cp == &charbuf[2])
15548111Sbostic 		switch (charbuf[0]) {
15648111Sbostic 			case ' ':
15748111Sbostic 				commnlbl();
15848111Sbostic 				break;
15948111Sbostic 			case '\f':
16048111Sbostic 				commform();
16148111Sbostic 		}
16248111Sbostic #endif
16348111Sbostic 	if (opt('u'))
16448111Sbostic 		setuflg();
16548111Sbostic #ifdef PXP
16648111Sbostic out:
16748111Sbostic #endif
16848111Sbostic 	bufp = charbuf - 1;
16948111Sbostic 	yycol = 8;
17048111Sbostic 	return (1);
17148111Sbostic }
17248111Sbostic 
17348111Sbostic /*
17448111Sbostic  * Check an input line to see if it is a "#include" pseudo-statement.
17548111Sbostic  * We allow arbitrary blanks in the line and the file name
17648111Sbostic  * may be delimited by either 's or "s.  A single semicolon
17748111Sbostic  * may be placed after the name, but nothing else is allowed
17848111Sbostic  */
includ()17948111Sbostic includ()
18048111Sbostic {
18148111Sbostic 	register char *cp, *dp;
18248111Sbostic 	char ch;
18348111Sbostic 	register struct inc *ip;
18448111Sbostic 
18548111Sbostic 	cp = charbuf;
18648111Sbostic 	if (*cp++ != '#')
18748111Sbostic 		return (0);
18848111Sbostic 	cp = skipbl(cp);
18948111Sbostic 	for (dp = "include"; *dp; dp++)
19048111Sbostic 		if (*dp != *cp++)
19148111Sbostic 			return (0);
19248111Sbostic 	line = yyline;
19348111Sbostic 	cp = skipbl(cp);
19448111Sbostic 	ch = *cp++;
19548111Sbostic 	if (ch != '\'' && ch != '"') {
19648111Sbostic 		/*
19748111Sbostic 		 * This should be a yerror flagging the place
19848111Sbostic 		 * but its not worth figuring out the column.
19948111Sbostic 		 */
20048111Sbostic 		line = yyline;
20148111Sbostic 		error("Include syntax error - expected ' or \" not found - QUIT");
20248111Sbostic 		pexit(DIED);
20348111Sbostic 	}
20448111Sbostic 	for (dp = cp; *dp != ch; dp++)
20548111Sbostic 		if (*dp == 0) {
20648111Sbostic 			line = yyline;
20748111Sbostic 			error("Missing closing %c for include file name - QUIT", (char *) ch);
20848111Sbostic 			pexit(DIED);
20948111Sbostic 		}
21048111Sbostic 	*dp++ = 0;
21148111Sbostic /*
21248111Sbostic  *	if (*dp == ';')
21348111Sbostic  *		dp++;
21448111Sbostic  *	dp = skipbl(dp);
21548111Sbostic  *	if (*dp != '\n') {
21648111Sbostic  *		line = yyline;
21748111Sbostic  *		error("Garbage after filename in include");
21848111Sbostic  *		pexit(DIED);
21948111Sbostic  *	}
22048111Sbostic  */
22148111Sbostic 	if (!dotted(cp, 'i') && !dotted(cp, 'h')) {
22248111Sbostic 		line = yyline;
22348111Sbostic 		error("Include filename must end in .i or .h");
22448111Sbostic 	}
22548111Sbostic #ifdef PXP
22648111Sbostic 	commincl(cp, ch);
22748111Sbostic 	if (noinclude)
22848111Sbostic 		return (1);
22948111Sbostic #endif
23048111Sbostic 	inclev++;
23148111Sbostic 	if (inclev > MAXINC) {
23248111Sbostic 		line = yyline;
23348111Sbostic 		error("Absurdly deep include nesting - QUIT");
23448111Sbostic 		pexit(DIED);
23548111Sbostic 	}
23648111Sbostic 	ip = &incs[inclev];
23748111Sbostic 	ip->filename = filename;
23848111Sbostic 	filename = savestr(cp);
23948111Sbostic 
24048111Sbostic #ifdef OBJ
24148111Sbostic /*
24248111Sbostic  * For the debugger pdx, we need to note that we've changed files.
24348111Sbostic  */
24448111Sbostic 	newfile(filename, 1);
24548111Sbostic #endif
24648111Sbostic 
24748111Sbostic /*
24848111Sbostic  *	left over from before stdio
24948111Sbostic  *
25048111Sbostic  *	cp = malloc(518);
25148111Sbostic  *	if (cp == -1) {
25248111Sbostic  *		error("Ran out of memory (include)");
25348111Sbostic  *		pexit(DIED);
25448111Sbostic  *	}
25548111Sbostic  *
25648111Sbostic  */
25748111Sbostic 	ip->ibp = ibp;
25848111Sbostic 	if ( ( ibp = fopen(filename, "r" ) ) == NULL ) {
25948111Sbostic 		perror(filename);
26048111Sbostic 		pexit(DIED);
26148111Sbostic 	}
26248111Sbostic 	if (inpflist(filename)) {
26348111Sbostic #ifdef PI
26448111Sbostic 		opush('l');
26548111Sbostic #endif
26648111Sbostic #ifdef PXP
26748111Sbostic 		opush('z');
26848111Sbostic #endif
26948111Sbostic 	}
27048111Sbostic 	ip->Printed = printed;
27148111Sbostic 	printed = 0;
27248111Sbostic 	ip->yyline = yyline;
27348111Sbostic 	yyline = 0;
27448111Sbostic 	ip->yyLinpt = yyLinpt;
27548111Sbostic 	yyLinpt = 0;
27648111Sbostic /*
27748111Sbostic  *	left over from before stdio
27848111Sbostic  *
27948111Sbostic  *	ip->ibp = ibp;
28048111Sbostic  *	ibp = cp;
28148111Sbostic  *
28248111Sbostic  */
28348111Sbostic #	ifdef PC
28448111Sbostic 	    stabinclude( filename , TRUE );
28548111Sbostic #	endif PC
28648111Sbostic 	return (1);
28748111Sbostic }
28848111Sbostic 
28948111Sbostic char *
skipbl(ocp)29048111Sbostic skipbl(ocp)
29148111Sbostic 	char *ocp;
29248111Sbostic {
29348111Sbostic 	register char *cp;
29448111Sbostic 
29548111Sbostic 	cp = ocp;
29648111Sbostic 	while (*cp == ' ' || *cp == '\t')
29748111Sbostic 		cp++;
29848111Sbostic 	return (cp);
29948111Sbostic }
30048111Sbostic 
30148111Sbostic 
30248111Sbostic /*
30348111Sbostic  * At the end of an include,
30448111Sbostic  * close the file, free the input buffer,
30548111Sbostic  * and restore the environment before
30648111Sbostic  * the "push", including the value of
30748111Sbostic  * the z option for pxp and the l option for pi.
30848111Sbostic  */
uninclud()30948111Sbostic uninclud()
31048111Sbostic {
31148111Sbostic 	register struct inc *ip;
31248111Sbostic 
31348111Sbostic 	if (inclev < 0)
31448111Sbostic 		return (0);
31548111Sbostic /*
31648111Sbostic  *	left over from before stdio: becomes fclose ( ibp )
31748111Sbostic  *
31848111Sbostic  *	(void) close(ibp[0]);
31948111Sbostic  *	free(ibp);
32048111Sbostic  *
32148111Sbostic  */
32248111Sbostic 	(void) fclose ( ibp );
32348111Sbostic 	ip = &incs[inclev];
32448111Sbostic 	ibp = ip->ibp;
32548111Sbostic 	yyline = ip->yyline;
32648111Sbostic 	if (inpflist(filename)) {
32748111Sbostic #ifdef PI
32848111Sbostic 		opop('l');
32948111Sbostic #endif
33048111Sbostic #ifdef PXP
33148111Sbostic 		opop('z');
33248111Sbostic #endif
33348111Sbostic 	}
33448111Sbostic 	filename = ip->filename;
33548111Sbostic 
33648111Sbostic 	yyLinpt = ip->yyLinpt;
33748111Sbostic 	/*
33848111Sbostic 	 * If we printed out the nested name,
33948111Sbostic 	 * then we should print all covered names again.
34048111Sbostic 	 * If we didn't print out the nested name
34148111Sbostic 	 * we print the uncovered name only if it
34248111Sbostic 	 * has not been printed before (unstack).
34348111Sbostic 	 */
34448111Sbostic 	if (printed) {
34548111Sbostic 		printed = 0;
34648111Sbostic 		while (ip >= incs) {
34748111Sbostic 			ip->Printed = 0;
34848111Sbostic 			ip--;
34948111Sbostic 		}
35048111Sbostic 	} else
35148111Sbostic 		printed = ip->Printed;
35248111Sbostic #	ifdef OBJ
35348111Sbostic 	/*
35448111Sbostic 	 * For the debugger pdx, we need to note that we've changed files.
35548111Sbostic 	 */
35648111Sbostic 	newfile(filename, yyline);
35748111Sbostic #endif
35848111Sbostic #	ifdef PC
35948111Sbostic 	    if ( inclev == 0 ) {
36048111Sbostic 		stabsource( filename );
36148111Sbostic 	    } else {
36248111Sbostic 		stabinclude( filename , FALSE );
36348111Sbostic 	    }
36448111Sbostic #	endif PC
36548111Sbostic 	inclev--;
36648111Sbostic 	return (1);
36748111Sbostic }
368