|
|
1.1 root 1: #include <stdio.h>
2: #include <ctype.h>
3: #include <errno.h>
4: #include "e.h"
5: #include "y.tab.h"
6:
7: Infile infile[10];
8: Infile *curfile = infile;
9:
10: #define MAXSRC 50
11: Src src[MAXSRC]; /* input source stack */
12: Src *srcp = src;
13:
14: pushsrc(type, ptr) /* new input source */
15: int type;
16: char *ptr;
17: {
18: if (++srcp >= src + MAXSRC)
19: fatal("inputs nested too deep");
20: srcp->type = type;
21: srcp->sp = ptr;
22: if (dbg > 1) {
23: printf("\n%3d ", srcp - src);
24: switch (srcp->type) {
25: case File:
26: printf("push file %s\n", ((Infile *)ptr)->fname);
27: break;
28: case Macro:
29: printf("push macro <%s>\n", ptr);
30: break;
31: case Char:
32: printf("push char <%c>\n", *ptr);
33: break;
34: case String:
35: printf("push string <%s>\n", ptr);
36: break;
37: case Free:
38: printf("push free <%s>\n", ptr);
39: break;
40: default:
41: fatal("pushed bad type %d\n", srcp->type);
42: }
43: }
44: }
45:
46: popsrc() /* restore an old one */
47: {
48: if (srcp <= src)
49: fatal("too many inputs popped");
50: if (dbg > 1) {
51: printf("%3d ", srcp - src);
52: switch (srcp->type) {
53: case File:
54: printf("pop file\n");
55: break;
56: case Macro:
57: printf("pop macro\n");
58: break;
59: case Char:
60: printf("pop char <%c>\n", *srcp->sp);
61: break;
62: case String:
63: printf("pop string\n");
64: break;
65: case Free:
66: printf("pop free\n");
67: break;
68: default:
69: fatal("pop weird input %d\n", srcp->type);
70: }
71: }
72: srcp--;
73: }
74:
75: Arg args[10]; /* argument frames */
76: Arg *argfp = args; /* frame pointer */
77: int argcnt; /* number of arguments seen so far */
78:
79: dodef(stp) /* collect args and switch input to defn */
80: tbl *stp;
81: {
82: int i, len;
83: char *p;
84: Arg *ap;
85:
86: ap = argfp+1;
87: if (ap >= args+10)
88: fatal("arguments too deep");
89: argcnt = 0;
90: if (input() != '(')
91: fatal("disaster in dodef\n");
92: if (ap->argval == 0)
93: ap->argval = malloc(1000);
94: for (p = ap->argval; (len = getarg(p)) != -1; p += len) {
95: ap->argstk[argcnt++] = p;
96: if (input() == ')')
97: break;
98: }
99: for (i = argcnt; i < MAXARGS; i++)
100: ap->argstk[i] = "";
101: if (dbg)
102: for (i = 0; i < argcnt; i++)
103: printf("arg %d.%d = <%s>\n", ap-args, i+1, ap->argstk[i]);
104: argfp = ap;
105: pushsrc(Macro, stp->defn);
106: }
107:
108: getarg(p) /* pick up single argument, store in p, return length */
109: char *p;
110: {
111: int n, c, npar;
112:
113: n = npar = 0;
114: for ( ;; ) {
115: c = input();
116: if (c == EOF)
117: fatal("end of file in getarg!\n");
118: if (npar == 0 && (c == ',' || c == ')'))
119: break;
120: if (c == '"') /* copy quoted stuff intact */
121: do {
122: *p++ = c;
123: n++;
124: } while ((c = input()) != '"' && c != EOF);
125: else if (c == '(')
126: npar++;
127: else if (c == ')')
128: npar--;
129: n++;
130: *p++ = c;
131: }
132: *p = 0;
133: unput(c);
134: return(n + 1);
135: }
136:
137: #define PBSIZE 2000
138: char pbuf[PBSIZE]; /* pushback buffer */
139: char *pb = pbuf-1; /* next pushed back character */
140:
141: char ebuf[200]; /* collect input here for error reporting */
142: char *ep = ebuf;
143:
144: input()
145: {
146: register int c;
147:
148: loop:
149: switch (srcp->type) {
150: case File:
151: c = getc(curfile->fin);
152: if (c == EOF) {
153: if (curfile == infile)
154: break;
155: if (curfile->fin != stdin) {
156: fclose(curfile->fin);
157: free(curfile->fname); /* assumes allocated */
158: }
159: curfile--;
160: printf(".lf %d %s\n", curfile->lineno, curfile->fname);
161: popsrc();
162: goto loop;
163: }
164: if (c == '\n')
165: curfile->lineno++;
166: break;
167: case Char:
168: if (pb >= pbuf) {
169: c = *pb--;
170: popsrc();
171: break;
172: } else { /* can't happen? */
173: popsrc();
174: goto loop;
175: }
176: case String:
177: c = *srcp->sp++;
178: if (c == '\0') {
179: popsrc();
180: goto loop;
181: } else {
182: if (*srcp->sp == '\0') /* empty, so pop */
183: popsrc();
184: break;
185: }
186: case Macro:
187: c = *srcp->sp++;
188: if (c == '\0') {
189: if (--argfp < args)
190: fatal("argfp underflow");
191: popsrc();
192: goto loop;
193: } else if (c == '$' && isdigit(*srcp->sp)) {
194: int n = 0;
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]);
199: goto loop;
200: }
201: break;
202: case Free: /* free string */
203: free(srcp->sp);
204: popsrc();
205: goto loop;
206: }
207: if (ep >= ebuf + sizeof ebuf)
208: ep = ebuf;
209: *ep++ = c;
210: return c;
211: }
212:
213:
214: unput(c)
215: {
216: if (++pb >= pbuf + sizeof pbuf)
217: fatal("pushback overflow\n");
218: if (--ep < ebuf)
219: ep = ebuf + sizeof(ebuf) - 1;
220: *pb = c;
221: pushsrc(Char, pb);
222: return c;
223: }
224:
225: pbstr(s)
226: char *s;
227: {
228: pushsrc(String, s);
229: }
230:
231: fatal(s, s1, s2, s3, s4) /* should be a flag on error */
232: char *s, *s1, *s2, *s3, *s4;
233: {
234: error(FATAL, s, s1, s2, s3, s4);
235: }
236:
237: error(die, s, s1, s2, s3, s4)
238: int die;
239: char *s, *s1, *s2, *s3, *s4;
240: {
241: extern char *cmdname, *sys_errlist[];
242: extern int errno, sys_nerr;
243:
244: if (synerr)
245: return;
246: fprintf(stderr, "%s: ", cmdname);
247: fprintf(stderr, s, s1, s2, s3, s4);
248: if (errno > 0 && errno < sys_nerr)
249: fprintf(stderr, " (%s)", sys_errlist[errno]);
250: if (curfile->fin)
251: fprintf(stderr, " near line %d, file %s",
252: curfile->lineno, curfile->fname);
253: fprintf(stderr, "\n");
254: eprint();
255: synerr = 1;
256: errno = 0;
257: if (die) {
258: if (dbg)
259: abort();
260: else
261: exit(1);
262: }
263: }
264:
265: yyerror() {;}
266:
267: eprint() /* try to print context around error */
268: {
269: char *p, *q;
270: int c;
271:
272: if (ep == ebuf)
273: return; /* no context */
274: p = ep - 1;
275: if (p > ebuf && *p == '\n')
276: p--;
277: for ( ; p >= ebuf && *p != '\n'; p--)
278: ;
279: while (*p == '\n')
280: p++;
281: fprintf(stderr, " context is\n\t");
282: for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
283: ;
284: while (p < q)
285: putc(*p++, stderr);
286: fprintf(stderr, " >>> ");
287: while (p < ep)
288: putc(*p++, stderr);
289: fprintf(stderr, " <<< ");
290: while (pb >= pbuf)
291: putc(*pb--, stderr);
292: if (curfile->fin)
293: fgets(ebuf, sizeof ebuf, curfile->fin);
294: fprintf(stderr, "%s", ebuf);
295: pbstr("\n.EN\n"); /* safety first */
296: ep = ebuf;
297: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.