6 Infile *curfile = infile;
9 Src src[MAXSRC]; /* input source stack */
12 extern int getarg(char *);
13 extern void eprint(void);
15 void pushsrc(int type, char *ptr) /* new input source */
17 if (++srcp >= src + MAXSRC)
18 ERROR "inputs nested too deep" FATAL;
22 printf("\n%3ld ", (long)(srcp - src));
25 printf("push file %s\n", ((Infile *)ptr)->fname);
28 printf("push macro <%s>\n", ptr);
31 printf("push char <%c>\n", *ptr);
34 printf("push string <%s>\n", ptr);
37 printf("push free <%s>\n", ptr);
40 ERROR "pushed bad type %d\n", srcp->type FATAL;
45 void popsrc(void) /* restore an old one */
48 ERROR "too many inputs popped" FATAL;
50 printf("%3ld ", (long)(srcp - src));
56 printf("pop macro\n");
59 printf("pop char <%c>\n", *srcp->sp);
62 printf("pop string\n");
68 ERROR "pop weird input %d\n", srcp->type FATAL;
74 Arg args[10]; /* argument frames */
75 Arg *argfp = args; /* frame pointer */
76 int argcnt; /* number of arguments seen so far */
78 void dodef(tbl *stp) /* collect args and switch input to defn */
86 ERROR "more than arguments\n" FATAL;
89 ERROR "disaster in dodef\n"FATAL;
91 ap->argval = malloc(1000);
92 for (p = ap->argval; (len = getarg(p)) != -1; p += len) {
93 ap->argstk[argcnt++] = p;
97 for (i = argcnt; i < MAXARGS; i++)
100 for (i = 0; i < argcnt; i++)
101 printf("arg %ld.%d = <%s>\n", (long)(ap-args), i+1, ap->argstk[i]);
103 pushsrc(Macro, stp->cval);
107 getarg(char *p) /* pick up single argument, store in p, return length */
115 ERROR "end of file in getarg!\n" FATAL;
116 if (npar == 0 && (c == ',' || c == ')'))
118 if (c == '"') /* copy quoted stuff intact */
122 } while ((c = input()) != '"' && c != EOF);
136 char pbuf[PBSIZE]; /* pushback buffer */
137 char *pb = pbuf-1; /* next pushed back character */
139 char ebuf[200]; /* collect input here for error reporting */
148 switch (srcp->type) {
150 c = getc(curfile->fin);
152 if (curfile == infile)
154 if (curfile->fin != stdin) {
155 fclose(curfile->fin);
156 free(curfile->fname); /* assumes allocated */
159 printf(".lf %d %s\n", curfile->lineno, curfile->fname);
171 } else { /* can't happen? */
181 if (*srcp->sp == '\0') /* empty, so pop */
189 ERROR "argfp underflow" FATAL;
192 } else if (c == '$' && isdigit((unsigned char)*srcp->sp)) {
194 while (isdigit((unsigned char)*srcp->sp))
195 n = 10 * n + *srcp->sp++ - '0';
196 if (n > 0 && n <= MAXARGS)
197 pushsrc(String, argfp->argstk[n-1]);
201 case Free: /* free string */
206 if (ep >= ebuf + sizeof ebuf)
215 if (++pb >= pbuf + sizeof pbuf)
216 ERROR "pushback overflow\n"FATAL;
218 ep = ebuf + sizeof(ebuf) - 1;
229 void error(int die, char *s)
231 extern char *cmdname;
235 fprintf(stderr, "%s: %s", cmdname, s);
239 fprintf(stderr, " near %s:%d",
240 curfile->fname, curfile->lineno+1);
241 fprintf(stderr, "\n");
253 void yyerror(char *s)
255 error(0, s); /* temporary */
260 void eprint(void) /* try to print context around error */
265 return; /* no context */
267 if (p > ebuf && *p == '\n')
269 for ( ; p >= ebuf && *p != '\n'; p--)
273 fprintf(stderr, " context is\n\t");
274 for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
278 fprintf(stderr, " >>> ");
281 fprintf(stderr, " <<< ");
285 fgets(ebuf, sizeof ebuf, curfile->fin);
286 fprintf(stderr, "%s", ebuf);
287 pbstr("\n.EN\n"); /* safety first */