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
definition(s)11 definition(s) /* collect definition for s and install */
12 char *s; /* definitions picked up lexically */
13 {
14 char buf[4000], *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.p);
40 stp->s_val.p = p;
41 } else {
42 YYSTYPE u;
43 u.p = p;
44 makevar(tostring(s), DEFNAME, u);
45 }
46 dprintf("installing %s as `%s'\n", s, p);
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 dodef(stp) /* collect args and push back defn for name in table slot n */
55 struct symtab *stp;
56 {
57 int i, c, len;
58 char *p;
59
60 argcnt = 0;
61 if (input() != '(')
62 yyerror("disaster in dodef\n");
63 for (argp = argval; (len = getarg(argp)) != -1; argp += len) {
64 argstk[argcnt++] = argp;
65 if (input() == ')')
66 break;
67 }
68 for (i = argcnt; i < 10; i++)
69 argstk[i] = "";
70 if (dbg) {
71 for (i = 0; i < argcnt; i++)
72 printf("arg %d = %s\n", i, argstk[i]);
73 }
74
75 /* push them back */
76 for (p = stp->s_val.p; *p; p++)
77 ; /* find the end */
78 for (--p; p >= stp->s_val.p; p--) {
79 if (*(p-1) == '$') {
80 if (isdigit(*p)) {
81 pbstr(argstk[*p - '0' - 1]);
82 p--;
83 }
84 else
85 unput(*p);
86 } else {
87 unput(*p);
88 }
89 }
90 }
91
getarg(p)92 getarg(p) /* pick up single argument, store in p, return length */
93 char *p;
94 {
95 int n, c, npar;
96
97 n = npar = 0;
98 for ( ;; ) {
99 c = input();
100 if (c == EOF)
101 yyerror("end of file in getarg!\n");
102 if (npar == 0 && (c == ',' || c == ')'))
103 break;
104 if (c == '"') /* copy quoted stuff intact */
105 do {
106 *p++ = c;
107 n++;
108 } while ((c = input()) != '"' && c != EOF);
109 else if (c == '(')
110 npar++;
111 else if (c == ')')
112 npar--;
113 n++;
114 *p++ = c;
115 }
116 *p = 0;
117 unput(c);
118 return(n + 1);
119 }
120
121 #define PBSIZE 4000
122 char pbuf[PBSIZE]; /* pushback buffer */
123 char *pb = pbuf-1; /* next pushed back character */
124
125 char ebuf[200]; /* collect input here for error reporting */
126 char *ep = ebuf;
127
input()128 input()
129 {
130 register int c;
131
132 if (pb >= pbuf) {
133 c = *pb--;
134 } else {
135 c = getc(yyin);
136 if (c == '\n')
137 lineno++;
138 else if (c == EOF) {
139 yyerror("end of file inside .PS/.PE");
140 exit(1);
141 }
142 }
143 if (ep >= ebuf + sizeof ebuf)
144 ep = ebuf;
145 return (*ep++ = c);
146 }
147
unput(c)148 unput(c)
149 {
150 if (++pb >= pbuf + sizeof pbuf) {
151 yyerror("pushback overflow\n");
152 exit(1);
153 }
154 if (--ep < ebuf)
155 ep = ebuf + sizeof(ebuf) - 1;
156 return(*pb = c);
157 }
158
pbstr(s)159 pbstr(s)
160 char *s;
161 {
162 int n;
163
164 n = strlen(s);
165 while (--n >= 0)
166 unput(s[n]);
167 }
168
yyerror(s,s1,s2,s3,s4)169 yyerror(s, s1, s2, s3, s4)
170 char *s, *s1, *s2, *s3, *s4;
171 {
172 if (synerr)
173 return;
174 fprintf(stderr, "pic: ");
175 fprintf(stderr, s, s1, s2, s3, s4);
176 fprintf(stderr, " near line %d, file %s\n", lineno, filename);
177 eprint();
178 synerr = 1;
179 }
180
eprint()181 eprint() /* try to print context around error */
182 {
183 char *p, *q;
184 int c;
185
186 p = ep - 1;
187 if (p > ebuf && *p == '\n')
188 p--;
189 for ( ; p >= ebuf && *p != '\n'; p--)
190 ;
191 while (*p == '\n')
192 p++;
193 fprintf(stderr, " context is\n\t");
194 while (p < ep)
195 putc(*p++, stderr);
196 fprintf(stderr, " ^ ");
197 while (pb >= pbuf)
198 putc(*pb--, stderr);
199 fgets(ebuf, sizeof ebuf, yyin);
200 fprintf(stderr, "%s", ebuf);
201 pbstr(".PE\n"); /* safety first */
202 ep = ebuf;
203 }
204
yywrap()205 yywrap() {;}
206