123928Sjaap #ifndef lint
2*30727Sjaap static char sccsid[] = "@(#)input.c	2.2 (CWI) 87/04/01";
323928Sjaap #endif lint
423928Sjaap #include <stdio.h>
523928Sjaap #include <ctype.h>
623928Sjaap #include <errno.h>
723928Sjaap #include "e.h"
823928Sjaap #include "y.tab.h"
923928Sjaap 
1023928Sjaap Infile	infile[10];
1123928Sjaap Infile	*curfile = infile;
1223928Sjaap 
1323928Sjaap #define	MAXSRC	50
1423928Sjaap Src	src[MAXSRC];	/* input source stack */
1523928Sjaap Src	*srcp	= src;
1623928Sjaap 
pushsrc(type,ptr)1723928Sjaap pushsrc(type, ptr)	/* new input source */
1823928Sjaap 	int type;
1923928Sjaap 	char *ptr;
2023928Sjaap {
2123928Sjaap 	if (++srcp >= src + MAXSRC)
2223928Sjaap 		fatal("inputs nested too deep");
2323928Sjaap 	srcp->type = type;
2423928Sjaap 	srcp->sp = ptr;
2523928Sjaap 	if (dbg > 1) {
2623928Sjaap 		printf("\n%3d ", srcp - src);
2723928Sjaap 		switch (srcp->type) {
2823928Sjaap 		case File:
2923928Sjaap 			printf("push file %s\n", ((Infile *)ptr)->fname);
3023928Sjaap 			break;
3123928Sjaap 		case Macro:
3223928Sjaap 			printf("push macro <%s>\n", ptr);
3323928Sjaap 			break;
3423928Sjaap 		case Char:
3523928Sjaap 			printf("push char <%c>\n", *ptr);
3623928Sjaap 			break;
3723928Sjaap 		case String:
3823928Sjaap 			printf("push string <%s>\n", ptr);
3923928Sjaap 			break;
4023928Sjaap 		case Free:
4123928Sjaap 			printf("push free <%s>\n", ptr);
4223928Sjaap 			break;
4323928Sjaap 		default:
4423928Sjaap 			fatal("pushed bad type %d\n", srcp->type);
4523928Sjaap 		}
4623928Sjaap 	}
4723928Sjaap }
4823928Sjaap 
popsrc()4923928Sjaap popsrc()	/* restore an old one */
5023928Sjaap {
5123928Sjaap 	if (srcp <= src)
5223928Sjaap 		fatal("too many inputs popped");
5323928Sjaap 	if (dbg > 1) {
5423928Sjaap 		printf("%3d ", srcp - src);
5523928Sjaap 		switch (srcp->type) {
5623928Sjaap 		case File:
5723928Sjaap 			printf("pop file\n");
5823928Sjaap 			break;
5923928Sjaap 		case Macro:
6023928Sjaap 			printf("pop macro\n");
6123928Sjaap 			break;
6223928Sjaap 		case Char:
6323928Sjaap 			printf("pop char <%c>\n", *srcp->sp);
6423928Sjaap 			break;
6523928Sjaap 		case String:
6623928Sjaap 			printf("pop string\n");
6723928Sjaap 			break;
6823928Sjaap 		case Free:
6923928Sjaap 			printf("pop free\n");
7023928Sjaap 			break;
7123928Sjaap 		default:
7223928Sjaap 			fatal("pop weird input %d\n", srcp->type);
7323928Sjaap 		}
7423928Sjaap 	}
7523928Sjaap 	srcp--;
7623928Sjaap }
7723928Sjaap 
7823928Sjaap Arg	args[10];	/* argument frames */
7923928Sjaap Arg	*argfp = args;	/* frame pointer */
8023928Sjaap int	argcnt;		/* number of arguments seen so far */
8123928Sjaap 
dodef(stp)8223928Sjaap dodef(stp)	/* collect args and switch input to defn */
8323928Sjaap 	tbl *stp;
8423928Sjaap {
8523928Sjaap 	int i, len;
8623928Sjaap 	char *p;
8723928Sjaap 	Arg *ap;
8823928Sjaap 
8923928Sjaap 	ap = argfp+1;
9023928Sjaap 	if (ap >= args+10)
9123928Sjaap 		fatal("arguments too deep");
9223928Sjaap 	argcnt = 0;
9323928Sjaap 	if (input() != '(')
9423928Sjaap 		fatal("disaster in dodef\n");
9523928Sjaap 	if (ap->argval == 0)
9623928Sjaap 		ap->argval = malloc(1000);
9723928Sjaap 	for (p = ap->argval; (len = getarg(p)) != -1; p += len) {
9823928Sjaap 		ap->argstk[argcnt++] = p;
9923928Sjaap 		if (input() == ')')
10023928Sjaap 			break;
10123928Sjaap 	}
10223928Sjaap 	for (i = argcnt; i < MAXARGS; i++)
10323928Sjaap 		ap->argstk[i] = "";
10423928Sjaap 	if (dbg)
10523928Sjaap 		for (i = 0; i < argcnt; i++)
10623928Sjaap 			printf("arg %d.%d = <%s>\n", ap-args, i+1, ap->argstk[i]);
10723928Sjaap 	argfp = ap;
10823928Sjaap 	pushsrc(Macro, stp->defn);
10923928Sjaap }
11023928Sjaap 
getarg(p)11123928Sjaap getarg(p)	/* pick up single argument, store in p, return length */
11223928Sjaap 	char *p;
11323928Sjaap {
11423928Sjaap 	int n, c, npar;
11523928Sjaap 
11623928Sjaap 	n = npar = 0;
11723928Sjaap 	for ( ;; ) {
11823928Sjaap 		c = input();
11923928Sjaap 		if (c == EOF)
12023928Sjaap 			fatal("end of file in getarg!\n");
12123928Sjaap 		if (npar == 0 && (c == ',' || c == ')'))
12223928Sjaap 			break;
12323928Sjaap 		if (c == '"')	/* copy quoted stuff intact */
12423928Sjaap 			do {
12523928Sjaap 				*p++ = c;
12623928Sjaap 				n++;
12723928Sjaap 			} while ((c = input()) != '"' && c != EOF);
12823928Sjaap 		else if (c == '(')
12923928Sjaap 			npar++;
13023928Sjaap 		else if (c == ')')
13123928Sjaap 			npar--;
13223928Sjaap 		n++;
13323928Sjaap 		*p++ = c;
13423928Sjaap 	}
13523928Sjaap 	*p = 0;
13623928Sjaap 	unput(c);
13723928Sjaap 	return(n + 1);
13823928Sjaap }
13923928Sjaap 
14023928Sjaap #define	PBSIZE	2000
14123928Sjaap char	pbuf[PBSIZE];		/* pushback buffer */
14223928Sjaap char	*pb	= pbuf-1;	/* next pushed back character */
14323928Sjaap 
14423928Sjaap char	ebuf[200];		/* collect input here for error reporting */
14523928Sjaap char	*ep	= ebuf;
14623928Sjaap 
input()14723928Sjaap input()
14823928Sjaap {
14923928Sjaap 	register int c;
15023928Sjaap 
15123928Sjaap   loop:
15223928Sjaap 	switch (srcp->type) {
15323928Sjaap 	case File:
15423928Sjaap 		c = getc(curfile->fin);
15523928Sjaap 		if (c == EOF) {
15623928Sjaap 			if (curfile == infile)
15723928Sjaap 				break;
15823928Sjaap 			if (curfile->fin != stdin) {
15923928Sjaap 				fclose(curfile->fin);
16023928Sjaap 				free(curfile->fname);	/* assumes allocated */
16123928Sjaap 			}
16223928Sjaap 			curfile--;
16323928Sjaap 			printf(".lf %d %s\n", curfile->lineno, curfile->fname);
16423928Sjaap 			popsrc();
16523928Sjaap 			goto loop;
16623928Sjaap 		}
16723928Sjaap 		if (c == '\n')
16823928Sjaap 			curfile->lineno++;
16923928Sjaap 		break;
17023928Sjaap 	case Char:
17123928Sjaap 		if (pb >= pbuf) {
17223928Sjaap 			c = *pb--;
17323928Sjaap 			popsrc();
17423928Sjaap 			break;
17523928Sjaap 		} else {	/* can't happen? */
17623928Sjaap 			popsrc();
17723928Sjaap 			goto loop;
17823928Sjaap 		}
17923928Sjaap 	case String:
18023928Sjaap 		c = *srcp->sp++;
18123928Sjaap 		if (c == '\0') {
18223928Sjaap 			popsrc();
18323928Sjaap 			goto loop;
18423928Sjaap 		} else {
18523928Sjaap 			if (*srcp->sp == '\0')	/* empty, so pop */
18623928Sjaap 				popsrc();
18723928Sjaap 			break;
18823928Sjaap 		}
18923928Sjaap 	case Macro:
19023928Sjaap 		c = *srcp->sp++;
19123928Sjaap 		if (c == '\0') {
19223928Sjaap 			if (--argfp < args)
19323928Sjaap 				fatal("argfp underflow");
19423928Sjaap 			popsrc();
19523928Sjaap 			goto loop;
19623928Sjaap 		} else if (c == '$' && isdigit(*srcp->sp)) {
19723928Sjaap 			int n = 0;
19823928Sjaap 			while (isdigit(*srcp->sp))
19923928Sjaap 				n = 10 * n + *srcp->sp++ - '0';
20023928Sjaap 			if (n > 0 && n <= MAXARGS)
20123928Sjaap 				pushsrc(String, argfp->argstk[n-1]);
20223928Sjaap 			goto loop;
20323928Sjaap 		}
20423928Sjaap 		break;
20523928Sjaap 	case Free:	/* free string */
20623928Sjaap 		free(srcp->sp);
20723928Sjaap 		popsrc();
20823928Sjaap 		goto loop;
20923928Sjaap 	}
21023928Sjaap 	if (ep >= ebuf + sizeof ebuf)
21123928Sjaap 		ep = ebuf;
212*30727Sjaap 	*ep++ = c;
213*30727Sjaap 	return c;
21423928Sjaap }
21523928Sjaap 
21623928Sjaap 
unput(c)21723928Sjaap unput(c)
21823928Sjaap {
21923928Sjaap 	if (++pb >= pbuf + sizeof pbuf)
22023928Sjaap 		fatal("pushback overflow\n");
22123928Sjaap 	if (--ep < ebuf)
22223928Sjaap 		ep = ebuf + sizeof(ebuf) - 1;
22323928Sjaap 	*pb = c;
22423928Sjaap 	pushsrc(Char, pb);
22523928Sjaap 	return c;
22623928Sjaap }
22723928Sjaap 
pbstr(s)22823928Sjaap pbstr(s)
22923928Sjaap 	char *s;
23023928Sjaap {
23123928Sjaap 	pushsrc(String, s);
23223928Sjaap }
23323928Sjaap 
fatal(s,s1,s2,s3,s4)23423928Sjaap fatal(s, s1, s2, s3, s4)	/* should be a flag on error */
23523928Sjaap 	char *s, *s1, *s2, *s3, *s4;
23623928Sjaap {
23723928Sjaap 	error(FATAL, s, s1, s2, s3, s4);
23823928Sjaap }
23923928Sjaap 
error(die,s,s1,s2,s3,s4)24023928Sjaap error(die, s, s1, s2, s3, s4)
24123928Sjaap 	int die;
24223928Sjaap 	char *s, *s1, *s2, *s3, *s4;
24323928Sjaap {
24423928Sjaap 	extern char *cmdname, *sys_errlist[];
24523928Sjaap 	extern int errno, sys_nerr;
24623928Sjaap 
24723928Sjaap 	if (synerr)
24823928Sjaap 		return;
24923928Sjaap 	fprintf(stderr, "%s: ", cmdname);
25023928Sjaap 	fprintf(stderr, s, s1, s2, s3, s4);
25123928Sjaap 	if (errno > 0 && errno < sys_nerr)
25223928Sjaap 		fprintf(stderr, " (%s)", sys_errlist[errno]);
25323928Sjaap 	if (curfile->fin)
25423928Sjaap 		fprintf(stderr, " near line %d, file %s",
25523928Sjaap 			curfile->lineno, curfile->fname);
25623928Sjaap 	fprintf(stderr, "\n");
25723928Sjaap 	eprint();
25823928Sjaap 	synerr = 1;
25923928Sjaap 	errno = 0;
26023928Sjaap 	if (die) {
26123928Sjaap 		if (dbg)
26223928Sjaap 			abort();
26323928Sjaap 		else
264*30727Sjaap 			exit(1);
26523928Sjaap 	}
26623928Sjaap }
26723928Sjaap 
yyerror()26823928Sjaap yyerror() {;}
26923928Sjaap 
eprint()27023928Sjaap eprint()	/* try to print context around error */
27123928Sjaap {
27223928Sjaap 	char *p, *q;
27323928Sjaap 	int c;
27423928Sjaap 
275*30727Sjaap 	if (ep == ebuf)
276*30727Sjaap 		return;				/* no context */
27723928Sjaap 	p = ep - 1;
27823928Sjaap 	if (p > ebuf && *p == '\n')
27923928Sjaap 		p--;
28023928Sjaap 	for ( ; p >= ebuf && *p != '\n'; p--)
28123928Sjaap 		;
28223928Sjaap 	while (*p == '\n')
28323928Sjaap 		p++;
28423928Sjaap 	fprintf(stderr, " context is\n\t");
28523928Sjaap 	for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
28623928Sjaap 		;
28723928Sjaap 	while (p < q)
28823928Sjaap 		putc(*p++, stderr);
28923928Sjaap 	fprintf(stderr, " >>> ");
29023928Sjaap 	while (p < ep)
29123928Sjaap 		putc(*p++, stderr);
29223928Sjaap 	fprintf(stderr, " <<< ");
29323928Sjaap 	while (pb >= pbuf)
29423928Sjaap 		putc(*pb--, stderr);
29523928Sjaap 	if (curfile->fin)
29623928Sjaap 		fgets(ebuf, sizeof ebuf, curfile->fin);
29723928Sjaap 	fprintf(stderr, "%s", ebuf);
29823928Sjaap 	pbstr("\n.EN\n");	/* safety first */
29923928Sjaap 	ep = ebuf;
30023928Sjaap }
301