7 Infile *curfile = infile;
10 Src src[MAXSRC]; /* input source stack */
13 extern int getarg(char *);
14 extern void eprint(void);
16 void pushsrc(int type, char *ptr) /* new input source */
18 if (++srcp >= src + MAXSRC)
19 ERROR "inputs nested too deep" FATAL;
23 printf("\n%3d ", srcp - src);
26 printf("push file %s\n", ((Infile *)ptr)->fname);
29 printf("push macro <%s>\n", ptr);
32 printf("push char <%c>\n", *ptr);
35 printf("push string <%s>\n", ptr);
38 printf("push free <%s>\n", ptr);
41 ERROR "pushed bad type %d\n", srcp->type FATAL;
46 void popsrc(void) /* restore an old one */
49 ERROR "too many inputs popped" FATAL;
51 printf("%3d ", srcp - src);
57 printf("pop macro\n");
60 printf("pop char <%c>\n", *srcp->sp);
63 printf("pop string\n");
69 ERROR "pop weird input %d\n", srcp->type FATAL;
75 Arg args[10]; /* argument frames */
76 Arg *argfp = args; /* frame pointer */
77 int argcnt; /* number of arguments seen so far */
79 void dodef(tbl *stp) /* collect args and switch input to defn */
87 ERROR "more than arguments\n" FATAL;
90 ERROR "disaster in dodef\n"FATAL;
92 ap->argval = malloc(1000);
93 for (p = ap->argval; (len = getarg(p)) != -1; p += len) {
94 ap->argstk[argcnt++] = p;
98 for (i = argcnt; i < MAXARGS; i++)
101 for (i = 0; i < argcnt; i++)
102 printf("arg %d.%d = <%s>\n", ap-args, i+1, ap->argstk[i]);
104 pushsrc(Macro, stp->cval);
108 getarg(char *p) /* pick up single argument, store in p, return length */
116 ERROR "end of file in getarg!\n" FATAL;
117 if (npar == 0 && (c == ',' || c == ')'))
119 if (c == '"') /* copy quoted stuff intact */
123 } while ((c = input()) != '"' && c != EOF);
137 char pbuf[PBSIZE]; /* pushback buffer */
138 char *pb = pbuf-1; /* next pushed back character */
140 char ebuf[200]; /* collect input here for error reporting */
149 switch (srcp->type) {
151 c = getc(curfile->fin);
153 if (curfile == infile)
155 if (curfile->fin != stdin) {
156 fclose(curfile->fin);
157 free(curfile->fname); /* assumes allocated */
160 printf(".lf %d %s\n", curfile->lineno, curfile->fname);
172 } else { /* can't happen? */
182 if (*srcp->sp == '\0') /* empty, so pop */
190 ERROR "argfp underflow" FATAL;
193 } else if (c == '$' && isdigit(*srcp->sp)) {
195 while (isdigit(*srcp->sp))
196 n = 10 * n + *srcp->sp++ - '0';
197 if (n > 0 && n <= MAXARGS)
198 pushsrc(String, argfp->argstk[n-1]);
202 case Free: /* free string */
207 if (ep >= ebuf + sizeof ebuf)
216 if (++pb >= pbuf + sizeof pbuf)
217 ERROR "pushback overflow\n"FATAL;
219 ep = ebuf + sizeof(ebuf) - 1;
230 void error(int die, char *s)
232 extern char *cmdname;
236 fprintf(stderr, "%s: ", cmdname);
241 fprintf(stderr, " near %s:%d",
242 curfile->fname, curfile->lineno+1);
243 fprintf(stderr, "\n");
255 void yyerror(char *s)
257 error(0, s); /* temporary */
262 void eprint(void) /* try to print context around error */
267 return; /* no context */
269 if (p > ebuf && *p == '\n')
271 for ( ; p >= ebuf && *p != '\n'; p--)
275 fprintf(stderr, " context is\n\t");
276 for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
280 fprintf(stderr, " >>> ");
283 fprintf(stderr, " <<< ");
287 fgets(ebuf, sizeof ebuf, curfile->fin);
288 fprintf(stderr, "%s", ebuf);
289 pbstr("\n.EN\n"); /* safety first */