|
|
1.1 root 1: #include <stdio.h>
2: #include <ctype.h>
3: #include "pic.h"
4: #include "y.tab.h"
5:
6: extern FILE *yyin;
7: extern int lineno;
8: extern char *filename;
9: extern int synerr;
10:
11: char *definition(s) /* collect definition for s and install */
12: char *s; /* definitions picked up lexically */
13: {
14: char buf[2000], *p, *tostring();
15: int c, delim;
16: struct symtab *stp;
17:
18: while ((delim = input()) == ' ' || delim == '\t')
19: ;
20: for (p = buf; (c = input()) != delim; ) {
21: if (p >= buf + sizeof(buf)) {
22: yyerror("definition of %s is too long", s);
23: exit(1);
24: }
25: if (c == EOF) {
26: yyerror("end of file while defining %s", s);
27: exit(1);
28: }
29: *p++ = c;
30: }
31: *p = '\0';
32: p = tostring(buf);
33: stp = lookup(s);
34: if (stp != NULL) { /* it's there before */
35: if (stp->s_type != DEFNAME) {
36: yyerror("%s used as variable and definition\n", s);
37: return;
38: }
39: free(stp->s_val);
40: stp->s_val = (int) p;
41: } else {
42: makevar(tostring(s), DEFNAME, p);
43: }
44: dprintf("installing %s as `%s'\n", s, p);
45: sprintf(buf, ".md %s", s);
46: return(tostring(buf)); /* handled as TROFF */
47: }
48:
49: char *argstk[10]; /* pointers to actual arguments in argval */
50: char argval[1000]; /* arguments stored here end to end */
51: char *argp; /* current position in argval */
52: int argcnt; /* number of arguments seen so far */
53:
54: char *defuse(s, p) /* used definition s, found at tbl p */
55: char *s;
56: struct symtab *p;
57: {
58: int c;
59: char buf[100], buf1[1000], *bp;
60:
61: c = input();
62: unput(c);
63: /* this only works for macros with no args */
64: if (c == '(') /* it's name(...) */
65: dodef(p);
66: else { /* no argument list */
67: bp = buf1;
68: do {
69: *bp = input();
70: } while (*bp++ != '\n'); /* collect rest of input line */
71: *bp = 0;
72: sprintf(buf, ".e %s\n", s);
73: dprintf("pushing back `%s'\n", buf);
74: pbstr(buf); /* terminate use of defined name */
75: dprintf("pushing back `%s'\n", buf1);
76: pbstr(buf1);
77: dprintf("pushing back `%s'\n", p->s_val);
78: pbstr(p->s_val);
79: unput('\n');
80: }
81: sprintf(buf, ".u %s%s", s, buf1);
82: return(tostring(buf));
83: }
84:
85: dodef(stp) /* collect args and push back defn for name in table slot n */
86: struct symtab *stp;
87: {
88: int i, c, len;
89: char *p;
90:
91: argcnt = 0;
92: if (input() != '(')
93: yyerror("disaster in dodef\n");
94: for (argp = argval; (len = getarg(argp)) != -1; argp += len) {
95: argstk[argcnt++] = argp;
96: if (input() == ')')
97: break;
98: }
99: for (i = argcnt; i < 10; i++)
100: argstk[i] = "";
101: if (dbg) {
102: for (i = 0; i < argcnt; i++)
103: printf("arg %d = %s\n", i, argstk[i]);
104: }
105:
106: /* push them back */
107: for (p = (char *) stp->s_val; *p; p++)
108: ; /* find the end */
109: for (--p; p >= (char *) stp->s_val; p--) {
110: if (*(p-1) == '$') {
111: if (isdigit(*p)) {
112: pbstr(argstk[*p - '0' - 1]);
113: p--;
114: }
115: else
116: unput(*p);
117: } else {
118: unput(*p);
119: }
120: }
121: }
122:
123: getarg(p) /* pick up single argument, store in p, return length */
124: char *p;
125: {
126: int n, c, npar;
127:
128: n = npar = 0;
129: for ( ;; ) {
130: c = input();
131: if (c == EOF)
132: yyerror("end of file in getarg!\n");
133: if (npar == 0 && (c == ',' || c == ')'))
134: break;
135: if (c == '"') /* copy quoted stuff intact */
136: do {
137: *p++ = c;
138: n++;
139: } while ((c = input()) != '"' && c != EOF);
140: else if (c == '(')
141: npar++;
142: else if (c == ')')
143: npar--;
144: n++;
145: *p++ = c;
146: }
147: *p = 0;
148: unput(c);
149: return(n + 1);
150: }
151:
152: #define PBSIZE 2000
153: char pbuf[PBSIZE]; /* pushback buffer */
154: char *pb = pbuf-1; /* next pushed back character */
155:
156: char ebuf[200]; /* collect input here for error reporting */
157: char *ep = ebuf;
158:
159: input()
160: {
161: register int c;
162:
163: if (pb >= pbuf) {
164: c = *pb--;
165: } else {
166: c = getc(yyin);
167: if (c == '\n')
168: lineno++;
169: else if (c == EOF) {
170: yyerror("end of file inside .PS/.PE");
171: exit(1);
172: }
173: }
174: if (ep >= ebuf + sizeof ebuf)
175: ep = ebuf;
176: return (*ep++ = c);
177: }
178:
179: unput(c)
180: {
181: if (++pb >= pbuf + sizeof pbuf) {
182: yyerror("pushback overflow\n");
183: exit(1);
184: }
185: if (--ep < ebuf)
186: ep = ebuf + sizeof(ebuf) - 1;
187: return(*pb = c);
188: }
189:
190: pbstr(s)
191: char *s;
192: {
193: int n;
194:
195: n = strlen(s);
196: while (--n >= 0)
197: unput(s[n]);
198: }
199:
200: yyerror(s, s1, s2, s3, s4)
201: char *s, *s1, *s2, *s3, *s4;
202: {
203: if (synerr)
204: return;
205: fprintf(stderr, "pic: ");
206: fprintf(stderr, s, s1, s2, s3, s4);
207: fprintf(stderr, " near line %d, file %s\n", lineno, filename);
208: eprint();
209: synerr = 1;
210: }
211:
212: eprint() /* try to print context around error */
213: {
214: char *p, *q;
215: int c;
216:
217: p = ep - 1;
218: if (p > ebuf && *p == '\n')
219: p--;
220: for ( ; p >= ebuf && *p != '\n'; p--)
221: ;
222: while (*p == '\n')
223: p++;
224: fprintf(stderr, " context is\n\t");
225: while (p < ep)
226: putc(*p++, stderr);
227: fprintf(stderr, " ^ ");
228: while (pb >= pbuf)
229: putc(*pb--, stderr);
230: fgets(ebuf, sizeof ebuf, yyin);
231: fprintf(stderr, "%s", ebuf);
232: pbstr(".PE\n"); /* safety first */
233: ep = ebuf;
234: }
235:
236: yywrap() {;}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.