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
);
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 */
147 switch (srcp
->type
) {
149 c
= getc(curfile
->fin
);
151 if (curfile
== infile
)
153 if (curfile
->fin
!= stdin
) {
154 fclose(curfile
->fin
);
155 free(curfile
->fname
); /* assumes allocated */
158 printf(".lf %d %s\n", curfile
->lineno
, curfile
->fname
);
170 } else { /* can't happen? */
180 if (*srcp
->sp
== '\0') /* empty, so pop */
188 ERROR
"argfp underflow" FATAL
;
191 } else if (c
== '$' && isdigit(*srcp
->sp
)) {
193 while (isdigit(*srcp
->sp
))
194 n
= 10 * n
+ *srcp
->sp
++ - '0';
195 if (n
> 0 && n
<= MAXARGS
)
196 pushsrc(String
, argfp
->argstk
[n
-1]);
200 case Free
: /* free string */
205 if (ep
>= ebuf
+ sizeof ebuf
)
214 if (++pb
>= pbuf
+ sizeof pbuf
)
215 ERROR
"pushback overflow\n"FATAL
;
217 ep
= ebuf
+ sizeof(ebuf
) - 1;
228 void error(int die
, char *s
)
230 extern char *cmdname
;
234 fprintf(stderr
, "%s: ", cmdname
);
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 */