1 #include <stdio.h>
2 #include <signal.h>
3 #include "pic.h"
4 #include "y.tab.h"
5
6 obj **objlist = 0; /* store the elements here */
7 int nobjlist = 0; /* size of objlist array */
8 int nobj = 0;
9
10 Attr *attr; /* attributes stored here as collected */
11 int nattrlist = 0;
12 int nattr = 0; /* number of entries in attr_list */
13
14 Text *text = 0; /* text strings stored here as collected */
15 int ntextlist = 0; /* size of text[] array */
16 int ntext = 0;
17 int ntext1 = 0; /* record ntext here on entry to each figure */
18
19 double curx = 0;
20 double cury = 0;
21
22 int hvmode = R_DIR; /* R => join left to right, D => top to bottom, etc. */
23
24 int codegen = 0; /* 1=>output for this picture; 0=>no output */
25 int PEseen = 0; /* 1=> PE seen during parsing */
26
27 double deltx = 6; /* max x value in output, for scaling */
28 double delty = 6; /* max y value in output, for scaling */
29 int dbg = 0;
30 int lineno = 0;
31 char *filename = "-";
32 int synerr = 0;
33 int anyerr = 0; /* becomes 1 if synerr ever 1 */
34 char *cmdname;
35
36 double xmin = 30000; /* min values found in actual data */
37 double ymin = 30000;
38 double xmax = -30000; /* max */
39 double ymax = -30000;
40
41 int
main(int argc,char ** argv)42 main(int argc, char **argv)
43 {
44 char buf[20];
45 extern void fpecatch(int);
46
47 signal(SIGFPE, fpecatch);
48 cmdname = argv[0];
49 while (argc > 1 && *argv[1] == '-') {
50 switch (argv[1][1]) {
51 case 'd':
52 dbg = atoi(&argv[1][2]);
53 if (dbg == 0)
54 dbg = 1;
55 break;
56 }
57 argc--;
58 argv++;
59 }
60 setdefaults();
61 objlist = (obj **) grow((char *)objlist, "objlist", nobjlist += 1000, sizeof(obj *));
62 text = (Text *) grow((char *)text, "text", ntextlist += 1000, sizeof(Text));
63 attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr));
64
65 sprintf(buf, "/%d/", getpid());
66 pushsrc(String, buf);
67 definition("pid");
68
69 curfile = infile;
70 pushsrc(File, curfile->fname);
71 if (argc <= 1) {
72 curfile->fin = stdin;
73 curfile->fname = tostring("-");
74 getdata();
75 } else
76 while (argc-- > 1) {
77 if ((curfile->fin = fopen(*++argv, "r")) == NULL) {
78 fprintf(stderr, "%s: can't open %s\n", cmdname, *argv);
79 exit(1);
80 }
81 curfile->fname = tostring(*argv);
82 getdata();
83 fclose(curfile->fin);
84 free(curfile->fname);
85 }
86 exit(anyerr);
87 return 0;
88 }
89
90 void
fpecatch(int arg)91 fpecatch(int arg)
92 {
93 ERROR "floating point exception" FATAL;
94 }
95
96 char *
grow(char * ptr,char * name,int num,int size)97 grow(char *ptr, char *name, int num, int size) /* make array bigger */
98 {
99 char *p;
100
101 if (ptr == NULL)
102 p = malloc(num * size);
103 else
104 p = realloc(ptr, num * size);
105 if (p == NULL)
106 ERROR "can't grow %s to %d", name, num * size FATAL;
107 return p;
108 }
109
110 static struct {
111 char *name;
112 double val;
113 short scalable; /* 1 => adjust when "scale" changes */
114 } defaults[] ={
115 "scale", SCALE, 1,
116 "lineht", HT, 1,
117 "linewid", HT, 1,
118 "moveht", HT, 1,
119 "movewid", HT, 1,
120 "dashwid", HT10, 1,
121 "boxht", HT, 1,
122 "boxwid", WID, 1,
123 "circlerad", HT2, 1,
124 "arcrad", HT2, 1,
125 "ellipseht", HT, 1,
126 "ellipsewid", WID, 1,
127 "arrowht", HT5, 1,
128 "arrowwid", HT10, 1,
129 "arrowhead", 2, 0, /* arrowhead style */
130 "textht", 0.0, 1, /* 6 lines/inch is also a useful value */
131 "textwid", 0.0, 1,
132 "maxpsht", MAXHT, 0,
133 "maxpswid", MAXWID, 0,
134 "fillval", 0.3, 0, /* gray value for filling boxes */
135 NULL, 0, 0
136 };
137
138 void
setdefaults(void)139 setdefaults(void) /* set default sizes for variables like boxht */
140 {
141 int i;
142 YYSTYPE v;
143
144 for (i = 0; defaults[i].name != NULL; i++) {
145 v.f = defaults[i].val;
146 makevar(tostring(defaults[i].name), VARNAME, v);
147 }
148 }
149
150 void
resetvar(void)151 resetvar(void) /* reset variables listed */
152 {
153 int i, j;
154
155 if (nattr == 0) { /* none listed, so do all */
156 setdefaults();
157 return;
158 }
159 for (i = 0; i < nattr; i++) {
160 for (j = 0; defaults[j].name != NULL; j++)
161 if (strcmp(defaults[j].name, attr[i].a_val.p) == 0) {
162 setfval(defaults[j].name, defaults[j].val);
163 free(attr[i].a_val.p);
164 break;
165 }
166 }
167 }
168
169 void
checkscale(char * s)170 checkscale(char *s) /* if s is "scale", adjust default variables */
171 {
172 int i;
173 double scale;
174
175 if (strcmp(s, "scale") == 0) {
176 scale = getfval("scale");
177 for (i = 1; defaults[i].name != NULL; i++)
178 if (defaults[i].scalable)
179 setfval(defaults[i].name, defaults[i].val * scale);
180 }
181 }
182
183 void
getdata(void)184 getdata(void)
185 {
186 char *p, buf[1000], buf1[100];
187 int ln;
188
189 curfile->lineno = 0;
190 printlf(1, curfile->fname);
191 while (fgets(buf, sizeof buf, curfile->fin) != NULL) {
192 curfile->lineno++;
193 if (*buf == '.' && *(buf+1) == 'P' && *(buf+2) == 'S') {
194 for (p = &buf[3]; *p == ' '; p++)
195 ;
196 if (*p++ == '<') {
197 Infile svfile;
198 svfile = *curfile;
199 sscanf(p, "%s", buf1);
200 if ((curfile->fin=fopen(buf1, "r")) == NULL)
201 ERROR "can't open %s", buf1 FATAL;
202 curfile->fname = tostring(buf1);
203 getdata();
204 fclose(curfile->fin);
205 free(curfile->fname);
206 *curfile = svfile;
207 printlf(curfile->lineno, curfile->fname);
208 continue;
209 }
210 reset();
211 yyparse();
212 anyerr += synerr;
213 /* yylval.i now contains 'E' or 'F' from .PE or .PF */
214
215 deltx = (xmax - xmin) / getfval("scale");
216 delty = (ymax - ymin) / getfval("scale");
217 if (buf[3] == ' ') { /* next things are wid & ht */
218 if (sscanf(&buf[4],"%lf %lf", &deltx, &delty) < 2)
219 delty = deltx * (ymax-ymin) / (xmax-xmin);
220 /* else {
221 /* double xfac, yfac; */
222 /* xfac = deltx / (xmax-xmin);
223 /* yfac = delty / (ymax-ymin);
224 /* if (xfac <= yfac)
225 /* delty = xfac * (ymax-ymin);
226 /* else
227 /* deltx = yfac * (xmax-xmin);
228 /*}
229 */
230 }
231 dprintf("deltx = %g, delty = %g\n", deltx, delty);
232 if (codegen && !synerr) {
233 openpl(); /* puts out .PS, with ht & wid stuck in */
234 printlf(curfile->lineno+1, NULL);
235 print(); /* assumes \n at end */
236 closepl(); /* does the .PE/F */
237 }
238 printlf(curfile->lineno+1, NULL);
239 fflush(stdout);
240 } else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') {
241 if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) {
242 free(curfile->fname);
243 printlf(curfile->lineno = ln, curfile->fname = tostring(buf1));
244 } else
245 printlf(curfile->lineno = ln, NULL);
246 } else
247 fputs(buf, stdout);
248 }
249 }
250
251 void
reset(void)252 reset(void)
253 {
254 obj *op;
255 int i;
256 extern int nstack;
257
258 for (i = 0; i < nobj; i++) {
259 op = objlist[i];
260 if (op->o_type == BLOCK)
261 freesymtab(op->o_symtab);
262 free((char *)objlist[i]);
263 }
264 nobj = 0;
265 nattr = 0;
266 for (i = 0; i < ntext; i++)
267 if (text[i].t_val)
268 free(text[i].t_val);
269 ntext = ntext1 = 0;
270 codegen = synerr = 0;
271 nstack = 0;
272 curx = cury = 0;
273 PEseen = 0;
274 hvmode = R_DIR;
275 xmin = ymin = 30000;
276 xmax = ymax = -30000;
277 }
278