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