1 #ifndef lint
2 static char sccsid[] = "@(#)misc.c 3.1 (CWI) 85/07/30";
3 #endif lint
4
5 #include <stdio.h>
6 #include "pic.h"
7 #include "y.tab.h"
8
setdir(n)9 setdir(n) /* set direction (hvmode) from LEFT, RIGHT, etc. */
10 int n;
11 {
12 switch (n) {
13 case UP: hvmode = U_DIR; break;
14 case DOWN: hvmode = D_DIR; break;
15 case LEFT: hvmode = L_DIR; break;
16 case RIGHT: hvmode = R_DIR; break;
17 }
18 return(hvmode);
19 }
20
curdir()21 curdir() /* convert current dir (hvmode) to RIGHT, LEFT, etc. */
22 {
23 switch (hvmode) {
24 case R_DIR: return RIGHT;
25 case L_DIR: return LEFT;
26 case U_DIR: return UP;
27 case D_DIR: return DOWN;
28 }
29 }
30
getcomp(p,t)31 float getcomp(p, t) /* return component of a position */
32 obj *p;
33 int t;
34 {
35 switch (t) {
36 case DOTX:
37 return p->o_x;
38 case DOTY:
39 return p->o_y;
40 case DOTWID:
41 switch (p->o_type) {
42 case BOX:
43 case BLOCK:
44 case TEXT:
45 return p->o_val[0];
46 case CIRCLE:
47 case ELLIPSE:
48 return 2 * p->o_val[0];
49 case LINE:
50 case ARROW:
51 return p->o_val[0] - p->o_x;
52 }
53 case DOTHT:
54 switch (p->o_type) {
55 case BOX:
56 case BLOCK:
57 case TEXT:
58 return p->o_val[1];
59 case CIRCLE:
60 case ELLIPSE:
61 return 2 * p->o_val[1];
62 case LINE:
63 case ARROW:
64 return p->o_val[1] - p->o_y;
65 }
66 case DOTRAD:
67 switch (p->o_type) {
68 case CIRCLE:
69 case ELLIPSE:
70 return p->o_val[0];
71 }
72 }
73 }
74
75 float exprlist[100];
76 int nexpr = 0;
77
exprsave(f)78 exprsave(f)
79 float f;
80 {
81 exprlist[nexpr++] = f;
82 }
83
sprintgen(fmt)84 char *sprintgen(fmt)
85 char *fmt;
86 {
87 int i;
88 char buf[1000];
89
90 sprintf(buf, fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]);
91 nexpr = 0;
92 free(fmt);
93 return tostring(buf);
94 }
95
makefattr(type,sub,f)96 makefattr(type, sub, f) /* float attr */
97 int type, sub;
98 float f;
99 {
100 YYSTYPE val;
101 val.f = f;
102 makeattr(type, sub, val);
103 }
104
makeoattr(type,o)105 makeoattr(type, o) /* obj* attr */
106 obj *o;
107 {
108 YYSTYPE val;
109 val.o = o;
110 makeattr(type, 0, val);
111 }
112
makeiattr(type,i)113 makeiattr(type, i) /* int attr */
114 int i;
115 {
116 YYSTYPE val;
117 val.i = i;
118 makeattr(type, 0, val);
119 }
120
maketattr(sub,p)121 maketattr(sub, p) /* text attribute: takes two */
122 char *p;
123 {
124 YYSTYPE val;
125 val.p = p;
126 makeattr(TEXTATTR, sub, val);
127 }
128
addtattr(sub)129 addtattr(sub) /* add text attrib to existing item */
130 {
131 attr[nattr-1].a_sub |= sub;
132 }
133
makevattr(p)134 makevattr(p) /* varname attribute */
135 char *p;
136 {
137 YYSTYPE val;
138 val.p = p;
139 makeattr(VARNAME, 0, val);
140 }
141
makeattr(type,sub,val)142 makeattr(type, sub, val) /* add attribute type and val */
143 int type, sub;
144 YYSTYPE val;
145 {
146 if (type == 0 && val.i == 0) { /* clear table for next stat */
147 nattr = 0;
148 return;
149 }
150 if (nattr >= nattrlist)
151 attr = (Attr *) grow(attr, "attr", nattrlist += 100, sizeof(Attr));
152 dprintf("attr %d: %d %d %d\n", nattr, type, sub, val.i);
153 attr[nattr].a_type = type;
154 attr[nattr].a_sub = sub;
155 attr[nattr].a_val = val;
156 nattr++;
157 }
158
printexpr(f)159 printexpr(f) /* print expression for debugging */
160 float f;
161 {
162 printf("%g\n", f);
163 }
164
printpos(p)165 printpos(p) /* print position for debugging */
166 obj *p;
167 {
168 printf("%g, %g\n", p->o_x, p->o_y);
169 }
170
tostring(s)171 char *tostring(s)
172 register char *s;
173 {
174 register char *p;
175
176 p = malloc(strlen(s)+1);
177 if (p == NULL) {
178 yyerror("out of space in tostring on %s", s);
179 exit(1);
180 }
181 strcpy(p, s);
182 return(p);
183 }
184
makepos(x,y)185 obj *makepos(x, y) /* make a osition cell */
186 float x, y;
187 {
188 obj *p;
189
190 p = makenode(PLACE, 0);
191 p->o_x = x;
192 p->o_y = y;
193 return(p);
194 }
195
makebetween(f,p1,p2)196 obj *makebetween(f, p1, p2) /* make position between p1 and p2 */
197 float f;
198 obj *p1, *p2;
199 {
200 obj *p;
201
202 dprintf("fraction = %.2f\n", f);
203 p = makenode(PLACE, 0);
204 p->o_x = p1->o_x + f * (p2->o_x - p1->o_x);
205 p->o_y = p1->o_y + f * (p2->o_y - p1->o_y);
206 return(p);
207 }
208
getpos(p,corner)209 obj *getpos(p, corner) /* find position of point */
210 obj *p;
211 int corner;
212 {
213 float x, y;
214
215 whatpos(p, corner, &x, &y);
216 return makepos(x, y);
217 }
218
whatpos(p,corner,px,py)219 whatpos(p, corner, px, py) /* what is the position (no side effect) */
220 obj *p;
221 int corner;
222 float *px, *py;
223 {
224 float x, y, x1, y1;
225 extern double sqrt();
226
227 dprintf("whatpos %o %d\n", p, corner);
228 x = p->o_x;
229 y = p->o_y;
230 x1 = p->o_val[0];
231 y1 = p->o_val[1];
232 switch (p->o_type) {
233 case PLACE:
234 break;
235 case BOX:
236 case BLOCK:
237 case TEXT:
238 switch (corner) {
239 case NORTH: y += y1 / 2; break;
240 case SOUTH: y -= y1 / 2; break;
241 case EAST: x += x1 / 2; break;
242 case WEST: x -= x1 / 2; break;
243 case NE: x += x1 / 2; y += y1 / 2; break;
244 case SW: x -= x1 / 2; y -= y1 / 2; break;
245 case SE: x += x1 / 2; y -= y1 / 2; break;
246 case NW: x -= x1 / 2; y += y1 / 2; break;
247 case START:
248 if (p->o_type == BLOCK)
249 return whatpos(objlist[(int)p->o_val[2]], START, px, py);
250 case END:
251 if (p->o_type == BLOCK)
252 return whatpos(objlist[(int)p->o_val[3]], END, px, py);
253 }
254 break;
255 case ARC:
256 switch (corner) {
257 case START:
258 if (p->o_attr & CW_ARC) {
259 x = p->o_val[2]; y = p->o_val[3];
260 } else {
261 x = x1; y = y1;
262 }
263 break;
264 case END:
265 if (p->o_attr & CW_ARC) {
266 x = x1; y = y1;
267 } else {
268 x = p->o_val[2]; y = p->o_val[3];
269 }
270 break;
271 }
272 if (corner == START || corner == END)
273 break;
274 x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y));
275 /* Fall Through! */
276 case CIRCLE:
277 case ELLIPSE:
278 switch (corner) {
279 case NORTH: y += y1; break;
280 case SOUTH: y -= y1; break;
281 case EAST: x += x1; break;
282 case WEST: x -= x1; break;
283 case NE: x += 0.707 * x1; y += 0.707 * y1; break;
284 case SE: x += 0.707 * x1; y -= 0.707 * y1; break;
285 case NW: x -= 0.707 * x1; y += 0.707 * y1; break;
286 case SW: x -= 0.707 * x1; y -= 0.707 * y1; break;
287 }
288 break;
289 case LINE:
290 case SPLINE:
291 case ARROW:
292 case MOVE:
293 switch (corner) {
294 case START: break; /* already in place */
295 case END: x = x1; y = y1; break;
296 default: /* change! */
297 case CENTER: x = (x+x1)/2; y = (y+y1)/2; break;
298 case NORTH: if (y1 > y) { x = x1; y = y1; } break;
299 case SOUTH: if (y1 < y) { x = x1; y = y1; } break;
300 case EAST: if (x1 > x) { x = x1; y = y1; } break;
301 case WEST: if (x1 < x) { x = x1; y = y1; } break;
302 }
303 break;
304 }
305 dprintf("whatpos returns %g %g\n", x, y);
306 *px = x;
307 *py = y;
308 }
309
gethere(n)310 obj *gethere(n) /* make a place for curx,cury */
311 {
312 dprintf("gethere %g %g\n", curx, cury);
313 return(makepos(curx, cury));
314 }
315
getlast(n,t)316 obj *getlast(n, t) /* find n-th previous occurrence of type t */
317 int n, t;
318 {
319 int i, k;
320 obj *p;
321
322 k = n;
323 for (i = nobj-1; i >= 0; i--) {
324 p = objlist[i];
325 if (p->o_type == BLOCKEND) {
326 i = p->o_val[4];
327 continue;
328 }
329 if (p->o_type != t)
330 continue;
331 if (--k > 0)
332 continue; /* not there yet */
333 dprintf("got a last of x,y= %g,%g\n", p->o_x, p->o_y);
334 return(p);
335 }
336 yyerror("there is no %dth last", n);
337 return(NULL);
338 }
339
getfirst(n,t)340 obj *getfirst(n, t) /* find n-th occurrence of type t */
341 int n, t;
342 {
343 int i, k;
344 obj *p;
345
346 k = n;
347 for (i = 0; i < nobj; i++) {
348 p = objlist[i];
349 if (p->o_type == BLOCK && t != BLOCK) { /* skip whole block */
350 i = p->o_val[5] + 1;
351 continue;
352 }
353 if (p->o_type != t)
354 continue;
355 if (--k > 0)
356 continue; /* not there yet */
357 dprintf("got a first of x,y= %g,%g\n", p->o_x, p->o_y);
358 return(p);
359 }
360 yyerror("there is no %dth ", n);
361 return(NULL);
362 }
363
getblkvar(p,s)364 float getblkvar(p, s) /* find variable s2 in block p */
365 obj *p;
366 char *s;
367 {
368 YYSTYPE y, getblk();
369
370 y = getblk(p, s);
371 return y.f;
372 }
373
getblock(p,s)374 obj *getblock(p, s) /* find variable s in block p */
375 obj *p;
376 char *s;
377 {
378 YYSTYPE y, getblk();
379
380 y = getblk(p, s);
381 return y.o;
382 }
383
getblk(p,s)384 YYSTYPE getblk(p, s) /* find union type for s in p */
385 obj *p;
386 char *s;
387 {
388 static YYSTYPE bug;
389 struct symtab *stp;
390
391 if (p->o_type != BLOCK) {
392 yyerror(".%s is not in that block", s);
393 return(bug);
394 }
395 for (stp = p->o_symtab; stp != NULL; stp = stp->s_next)
396 if (strcmp(s, stp->s_name) == 0) {
397 dprintf("getblk found x,y= %g,%g\n",
398 (stp->s_val.o)->o_x, (stp->s_val.o)->o_y);
399 return(stp->s_val);
400 }
401 yyerror("there is no .%s in that []", s);
402 return(bug);
403 }
404
fixpos(p,x,y)405 obj *fixpos(p, x, y)
406 obj *p;
407 float x, y;
408 {
409 dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y);
410 return makepos(p->o_x + x, p->o_y + y);
411 }
412
addpos(p,q)413 obj *addpos(p, q)
414 obj *p, *q;
415 {
416 dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y);
417 return makepos(p->o_x+q->o_x, p->o_y+q->o_y);
418 }
419
subpos(p,q)420 obj *subpos(p, q)
421 obj *p, *q;
422 {
423 dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y);
424 return makepos(p->o_x-q->o_x, p->o_y-q->o_y);
425 }
426
makenode(type,n)427 obj *makenode(type, n)
428 int type, n;
429 {
430 obj *p;
431 int i;
432 extern char *calloc();
433
434 p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(float));
435 if (p == NULL) {
436 yyerror("out of space in makenode\n");
437 exit(1);
438 }
439 p->o_type = type;
440 p->o_count = n;
441 p->o_nobj = nobj;
442 p->o_mode = hvmode;
443 p->o_x = curx;
444 p->o_y = cury;
445 p->o_nt1 = ntext1;
446 p->o_nt2 = ntext;
447 ntext1 = ntext; /* ready for next caller */
448 if (nobj >= nobjlist)
449 objlist = (obj **) grow(objlist, "objlist",
450 nobjlist += 100, sizeof(obj *));
451 objlist[nobj++] = p;
452 return(p);
453 }
454
extreme(x,y)455 extreme(x, y) /* record max and min x and y values */
456 float x, y;
457 {
458 if (x > xmax)
459 xmax = x;
460 if (y > ymax)
461 ymax = y;
462 if (x < xmin)
463 xmin = x;
464 if (y < ymin)
465 ymin = y;
466 }
467