1 b6d98463 2006-04-14 devnull #include <stdio.h>
2 b6d98463 2006-04-14 devnull #include <string.h>
3 b6d98463 2006-04-14 devnull #include <math.h>
4 b6d98463 2006-04-14 devnull #include "pic.h"
5 b6d98463 2006-04-14 devnull #include "y.tab.h"
8 b6d98463 2006-04-14 devnull setdir(int n) /* set direction (hvmode) from LEFT, RIGHT, etc. */
10 b6d98463 2006-04-14 devnull switch (n) {
11 b6d98463 2006-04-14 devnull case UP: hvmode = U_DIR; break;
12 b6d98463 2006-04-14 devnull case DOWN: hvmode = D_DIR; break;
13 b6d98463 2006-04-14 devnull case LEFT: hvmode = L_DIR; break;
14 b6d98463 2006-04-14 devnull case RIGHT: hvmode = R_DIR; break;
16 b6d98463 2006-04-14 devnull return(hvmode);
20 b6d98463 2006-04-14 devnull curdir(void) /* convert current dir (hvmode) to RIGHT, LEFT, etc. */
22 b6d98463 2006-04-14 devnull switch (hvmode) {
23 b6d98463 2006-04-14 devnull case R_DIR: return RIGHT;
24 b6d98463 2006-04-14 devnull case L_DIR: return LEFT;
25 b6d98463 2006-04-14 devnull case U_DIR: return UP;
26 b6d98463 2006-04-14 devnull case D_DIR: return DOWN;
28 b6d98463 2006-04-14 devnull ERROR "can't happen curdir" FATAL;
29 b6d98463 2006-04-14 devnull return 0;
33 b6d98463 2006-04-14 devnull getcomp(obj *p, int t) /* return component of a position */
35 b6d98463 2006-04-14 devnull switch (t) {
36 b6d98463 2006-04-14 devnull case DOTX:
37 b6d98463 2006-04-14 devnull return p->o_x;
38 b6d98463 2006-04-14 devnull case DOTY:
39 b6d98463 2006-04-14 devnull return p->o_y;
40 b6d98463 2006-04-14 devnull case DOTWID:
41 b6d98463 2006-04-14 devnull switch (p->o_type) {
42 b6d98463 2006-04-14 devnull case BOX:
43 b6d98463 2006-04-14 devnull case BLOCK:
44 b6d98463 2006-04-14 devnull case TEXT:
45 b6d98463 2006-04-14 devnull return p->o_val[0];
46 b6d98463 2006-04-14 devnull case CIRCLE:
47 b6d98463 2006-04-14 devnull case ELLIPSE:
48 b6d98463 2006-04-14 devnull return 2 * p->o_val[0];
49 b6d98463 2006-04-14 devnull case LINE:
50 b6d98463 2006-04-14 devnull case ARROW:
51 b6d98463 2006-04-14 devnull return p->o_val[0] - p->o_x;
52 b6d98463 2006-04-14 devnull case PLACE:
53 b6d98463 2006-04-14 devnull return 0;
55 b6d98463 2006-04-14 devnull case DOTHT:
56 b6d98463 2006-04-14 devnull switch (p->o_type) {
57 b6d98463 2006-04-14 devnull case BOX:
58 b6d98463 2006-04-14 devnull case BLOCK:
59 b6d98463 2006-04-14 devnull case TEXT:
60 b6d98463 2006-04-14 devnull return p->o_val[1];
61 b6d98463 2006-04-14 devnull case CIRCLE:
62 b6d98463 2006-04-14 devnull case ELLIPSE:
63 b6d98463 2006-04-14 devnull return 2 * p->o_val[1];
64 b6d98463 2006-04-14 devnull case LINE:
65 b6d98463 2006-04-14 devnull case ARROW:
66 b6d98463 2006-04-14 devnull return p->o_val[1] - p->o_y;
67 b6d98463 2006-04-14 devnull case PLACE:
68 b6d98463 2006-04-14 devnull return 0;
70 b6d98463 2006-04-14 devnull case DOTRAD:
71 b6d98463 2006-04-14 devnull switch (p->o_type) {
72 b6d98463 2006-04-14 devnull case CIRCLE:
73 b6d98463 2006-04-14 devnull case ELLIPSE:
74 b6d98463 2006-04-14 devnull return p->o_val[0];
77 b6d98463 2006-04-14 devnull ERROR "you asked for a weird dimension or position" WARNING;
78 b6d98463 2006-04-14 devnull return 0;
81 b6d98463 2006-04-14 devnull double exprlist[100];
82 b6d98463 2006-04-14 devnull int nexpr = 0;
85 b6d98463 2006-04-14 devnull exprsave(double f)
87 b6d98463 2006-04-14 devnull exprlist[nexpr++] = f;
91 b6d98463 2006-04-14 devnull sprintgen(char *fmt)
93 b6d98463 2006-04-14 devnull char buf[1000];
95 b6d98463 2006-04-14 devnull sprintf(buf, fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]);
96 b6d98463 2006-04-14 devnull nexpr = 0;
97 b6d98463 2006-04-14 devnull free(fmt);
98 b6d98463 2006-04-14 devnull return tostring(buf);
102 b6d98463 2006-04-14 devnull makefattr(int type, int sub, double f) /* double attr */
104 b6d98463 2006-04-14 devnull YYSTYPE val;
105 b6d98463 2006-04-14 devnull val.f = f;
106 b6d98463 2006-04-14 devnull makeattr(type, sub, val);
110 b6d98463 2006-04-14 devnull makeoattr(int type, obj *o) /* obj* attr */
112 b6d98463 2006-04-14 devnull YYSTYPE val;
113 b6d98463 2006-04-14 devnull val.o = o;
114 b6d98463 2006-04-14 devnull makeattr(type, 0, val);
118 b6d98463 2006-04-14 devnull makeiattr(int type, int i) /* int attr */
120 b6d98463 2006-04-14 devnull YYSTYPE val;
121 b6d98463 2006-04-14 devnull val.i = i;
122 b6d98463 2006-04-14 devnull makeattr(type, 0, val);
126 b6d98463 2006-04-14 devnull maketattr(int sub, char *p) /* text attribute: takes two */
128 b6d98463 2006-04-14 devnull YYSTYPE val;
129 b6d98463 2006-04-14 devnull val.p = p;
130 b6d98463 2006-04-14 devnull makeattr(TEXTATTR, sub, val);
134 b6d98463 2006-04-14 devnull addtattr(int sub) /* add text attrib to existing item */
136 b6d98463 2006-04-14 devnull attr[nattr-1].a_sub |= sub;
140 b6d98463 2006-04-14 devnull makevattr(char *p) /* varname attribute */
142 b6d98463 2006-04-14 devnull YYSTYPE val;
143 b6d98463 2006-04-14 devnull val.p = p;
144 b6d98463 2006-04-14 devnull makeattr(VARNAME, 0, val);
148 b6d98463 2006-04-14 devnull makeattr(int type, int sub, YYSTYPE val) /* add attribute type and val */
150 b6d98463 2006-04-14 devnull if (type == 0 && val.i == 0) { /* clear table for next stat */
151 b6d98463 2006-04-14 devnull nattr = 0;
154 b6d98463 2006-04-14 devnull if (nattr >= nattrlist)
155 b6d98463 2006-04-14 devnull attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr));
156 b6d98463 2006-04-14 devnull dprintf("attr %d: %d %d %d\n", nattr, type, sub, val.i);
157 b6d98463 2006-04-14 devnull attr[nattr].a_type = type;
158 b6d98463 2006-04-14 devnull attr[nattr].a_sub = sub;
159 b6d98463 2006-04-14 devnull attr[nattr].a_val = val;
160 b6d98463 2006-04-14 devnull nattr++;
164 b6d98463 2006-04-14 devnull printexpr(double f) /* print expression for debugging */
166 b6d98463 2006-04-14 devnull printf("%g\n", f);
170 b6d98463 2006-04-14 devnull printpos(obj *p) /* print position for debugging */
172 b6d98463 2006-04-14 devnull printf("%g, %g\n", p->o_x, p->o_y);
176 b6d98463 2006-04-14 devnull tostring(char *s)
178 b6d98463 2006-04-14 devnull char *p;
180 b6d98463 2006-04-14 devnull p = malloc(strlen(s)+1);
181 b6d98463 2006-04-14 devnull if (p == NULL)
182 b6d98463 2006-04-14 devnull ERROR "out of space in tostring on %s", s FATAL;
183 b6d98463 2006-04-14 devnull strcpy(p, s);
184 b6d98463 2006-04-14 devnull return(p);
188 b6d98463 2006-04-14 devnull makepos(double x, double y) /* make a position cell */
192 b6d98463 2006-04-14 devnull p = makenode(PLACE, 0);
193 b6d98463 2006-04-14 devnull p->o_x = x;
194 b6d98463 2006-04-14 devnull p->o_y = y;
195 b6d98463 2006-04-14 devnull return(p);
199 b6d98463 2006-04-14 devnull makebetween(double f, obj *p1, obj* p2) /* make position between p1 and p2 */
203 b6d98463 2006-04-14 devnull dprintf("fraction = %.2f\n", f);
204 b6d98463 2006-04-14 devnull p = makenode(PLACE, 0);
205 b6d98463 2006-04-14 devnull p->o_x = p1->o_x + f * (p2->o_x - p1->o_x);
206 b6d98463 2006-04-14 devnull p->o_y = p1->o_y + f * (p2->o_y - p1->o_y);
207 b6d98463 2006-04-14 devnull return(p);
211 b6d98463 2006-04-14 devnull getpos(obj *p, int corner) /* find position of point */
213 b6d98463 2006-04-14 devnull double x, y;
215 b6d98463 2006-04-14 devnull whatpos(p, corner, &x, &y);
216 b6d98463 2006-04-14 devnull return makepos(x, y);
220 b6d98463 2006-04-14 devnull whatpos(obj *p, int corner, double *px, double *py) /* what is the position (no side effect) */
222 b6d98463 2006-04-14 devnull double x, y, x1, y1;
224 b6d98463 2006-04-14 devnull dprintf("whatpos %p %d %d\n", p, p->o_type, corner);
225 b6d98463 2006-04-14 devnull x = p->o_x;
226 b6d98463 2006-04-14 devnull y = p->o_y;
229 b6d98463 2006-04-14 devnull if (p->o_type != PLACE) {
230 b6d98463 2006-04-14 devnull x1 = p->o_val[0];
231 b6d98463 2006-04-14 devnull y1 = p->o_val[1];
233 b6d98463 2006-04-14 devnull switch (p->o_type) {
234 b6d98463 2006-04-14 devnull case PLACE:
236 b6d98463 2006-04-14 devnull case BOX:
237 b6d98463 2006-04-14 devnull case BLOCK:
238 b6d98463 2006-04-14 devnull case TEXT:
239 b6d98463 2006-04-14 devnull switch (corner) {
240 b6d98463 2006-04-14 devnull case NORTH: y += y1 / 2; break;
241 b6d98463 2006-04-14 devnull case SOUTH: y -= y1 / 2; break;
242 b6d98463 2006-04-14 devnull case EAST: x += x1 / 2; break;
243 b6d98463 2006-04-14 devnull case WEST: x -= x1 / 2; break;
244 b6d98463 2006-04-14 devnull case NE: x += x1 / 2; y += y1 / 2; break;
245 b6d98463 2006-04-14 devnull case SW: x -= x1 / 2; y -= y1 / 2; break;
246 b6d98463 2006-04-14 devnull case SE: x += x1 / 2; y -= y1 / 2; break;
247 b6d98463 2006-04-14 devnull case NW: x -= x1 / 2; y += y1 / 2; break;
248 b6d98463 2006-04-14 devnull case START:
249 b6d98463 2006-04-14 devnull if (p->o_type == BLOCK)
250 b6d98463 2006-04-14 devnull return whatpos(objlist[(int)p->o_val[2]], START, px, py);
251 b6d98463 2006-04-14 devnull case END:
252 b6d98463 2006-04-14 devnull if (p->o_type == BLOCK)
253 b6d98463 2006-04-14 devnull return whatpos(objlist[(int)p->o_val[3]], END, px, py);
256 b6d98463 2006-04-14 devnull case ARC:
257 b6d98463 2006-04-14 devnull switch (corner) {
258 b6d98463 2006-04-14 devnull case START:
259 b6d98463 2006-04-14 devnull if (p->o_attr & CW_ARC) {
260 b6d98463 2006-04-14 devnull x = p->o_val[2]; y = p->o_val[3];
261 b6d98463 2006-04-14 devnull } else {
262 b6d98463 2006-04-14 devnull x = x1; y = y1;
265 b6d98463 2006-04-14 devnull case END:
266 b6d98463 2006-04-14 devnull if (p->o_attr & CW_ARC) {
267 b6d98463 2006-04-14 devnull x = x1; y = y1;
268 b6d98463 2006-04-14 devnull } else {
269 b6d98463 2006-04-14 devnull x = p->o_val[2]; y = p->o_val[3];
273 b6d98463 2006-04-14 devnull if (corner == START || corner == END)
275 b6d98463 2006-04-14 devnull x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y));
276 b6d98463 2006-04-14 devnull /* Fall Through! */
277 b6d98463 2006-04-14 devnull case CIRCLE:
278 b6d98463 2006-04-14 devnull case ELLIPSE:
279 b6d98463 2006-04-14 devnull switch (corner) {
280 b6d98463 2006-04-14 devnull case NORTH: y += y1; break;
281 b6d98463 2006-04-14 devnull case SOUTH: y -= y1; break;
282 b6d98463 2006-04-14 devnull case EAST: x += x1; break;
283 b6d98463 2006-04-14 devnull case WEST: x -= x1; break;
284 b6d98463 2006-04-14 devnull case NE: x += 0.707 * x1; y += 0.707 * y1; break;
285 b6d98463 2006-04-14 devnull case SE: x += 0.707 * x1; y -= 0.707 * y1; break;
286 b6d98463 2006-04-14 devnull case NW: x -= 0.707 * x1; y += 0.707 * y1; break;
287 b6d98463 2006-04-14 devnull case SW: x -= 0.707 * x1; y -= 0.707 * y1; break;
290 b6d98463 2006-04-14 devnull case LINE:
291 b6d98463 2006-04-14 devnull case SPLINE:
292 b6d98463 2006-04-14 devnull case ARROW:
293 b6d98463 2006-04-14 devnull switch (corner) {
294 b6d98463 2006-04-14 devnull case START: break; /* already in place */
295 b6d98463 2006-04-14 devnull case END: x = x1; y = y1; break;
296 b6d98463 2006-04-14 devnull default: /* change! */
297 b6d98463 2006-04-14 devnull case CENTER: x = (x+x1)/2; y = (y+y1)/2; break;
298 b6d98463 2006-04-14 devnull case NORTH: if (y1 > y) { x = x1; y = y1; } break;
299 b6d98463 2006-04-14 devnull case SOUTH: if (y1 < y) { x = x1; y = y1; } break;
300 b6d98463 2006-04-14 devnull case EAST: if (x1 > x) { x = x1; y = y1; } break;
301 b6d98463 2006-04-14 devnull case WEST: if (x1 < x) { x = x1; y = y1; } break;
304 b6d98463 2006-04-14 devnull case MOVE:
305 b6d98463 2006-04-14 devnull /* really ought to be same as line... */
308 b6d98463 2006-04-14 devnull dprintf("whatpos returns %g %g\n", x, y);
309 b6d98463 2006-04-14 devnull *px = x;
310 b6d98463 2006-04-14 devnull *py = y;
311 b6d98463 2006-04-14 devnull return 1;
315 b6d98463 2006-04-14 devnull gethere(void) /* make a place for curx,cury */
317 b6d98463 2006-04-14 devnull dprintf("gethere %g %g\n", curx, cury);
318 b6d98463 2006-04-14 devnull return(makepos(curx, cury));
322 b6d98463 2006-04-14 devnull getlast(int n, int t) /* find n-th previous occurrence of type t */
324 b6d98463 2006-04-14 devnull int i, k;
328 b6d98463 2006-04-14 devnull for (i = nobj-1; i >= 0; i--) {
329 b6d98463 2006-04-14 devnull p = objlist[i];
330 b6d98463 2006-04-14 devnull if (p->o_type == BLOCKEND) {
331 b6d98463 2006-04-14 devnull i = p->o_val[4];
332 b6d98463 2006-04-14 devnull continue;
334 b6d98463 2006-04-14 devnull if (p->o_type != t)
335 b6d98463 2006-04-14 devnull continue;
336 b6d98463 2006-04-14 devnull if (--k > 0)
337 b6d98463 2006-04-14 devnull continue; /* not there yet */
338 b6d98463 2006-04-14 devnull dprintf("got a last of x,y= %g,%g\n", p->o_x, p->o_y);
339 b6d98463 2006-04-14 devnull return(p);
341 b6d98463 2006-04-14 devnull ERROR "there is no %dth last", n WARNING;
342 b6d98463 2006-04-14 devnull return(NULL);
346 b6d98463 2006-04-14 devnull getfirst(int n, int t) /* find n-th occurrence of type t */
348 b6d98463 2006-04-14 devnull int i, k;
352 b6d98463 2006-04-14 devnull for (i = 0; i < nobj; i++) {
353 b6d98463 2006-04-14 devnull p = objlist[i];
354 b6d98463 2006-04-14 devnull if (p->o_type == BLOCK && t != BLOCK) { /* skip whole block */
355 b6d98463 2006-04-14 devnull i = p->o_val[5] + 1;
356 b6d98463 2006-04-14 devnull continue;
358 b6d98463 2006-04-14 devnull if (p->o_type != t)
359 b6d98463 2006-04-14 devnull continue;
360 b6d98463 2006-04-14 devnull if (--k > 0)
361 b6d98463 2006-04-14 devnull continue; /* not there yet */
362 b6d98463 2006-04-14 devnull dprintf("got a first of x,y= %g,%g\n", p->o_x, p->o_y);
363 b6d98463 2006-04-14 devnull return(p);
365 b6d98463 2006-04-14 devnull ERROR "there is no %dth ", n WARNING;
366 b6d98463 2006-04-14 devnull return(NULL);
370 b6d98463 2006-04-14 devnull getblkvar(obj *p, char *s) /* find variable s2 in block p */
372 90a99688 2006-04-14 devnull YYSTYPE y;
374 b6d98463 2006-04-14 devnull y = getblk(p, s);
375 b6d98463 2006-04-14 devnull return y.f;
379 b6d98463 2006-04-14 devnull getblock(obj *p, char *s) /* find variable s in block p */
381 90a99688 2006-04-14 devnull YYSTYPE y;
383 b6d98463 2006-04-14 devnull y = getblk(p, s);
384 b6d98463 2006-04-14 devnull return y.o;
388 b6d98463 2006-04-14 devnull getblk(obj *p, char *s) /* find union type for s in p */
390 b6d98463 2006-04-14 devnull static YYSTYPE bug;
391 b6d98463 2006-04-14 devnull struct symtab *stp;
393 b6d98463 2006-04-14 devnull if (p->o_type != BLOCK) {
394 b6d98463 2006-04-14 devnull ERROR ".%s is not in that block", s WARNING;
395 b6d98463 2006-04-14 devnull return(bug);
397 b6d98463 2006-04-14 devnull for (stp = p->o_symtab; stp != NULL; stp = stp->s_next)
398 b6d98463 2006-04-14 devnull if (strcmp(s, stp->s_name) == 0) {
399 b6d98463 2006-04-14 devnull dprintf("getblk %s found x,y= %g,%g\n",
400 b6d98463 2006-04-14 devnull s, (stp->s_val.o)->o_x, (stp->s_val.o)->o_y);
401 b6d98463 2006-04-14 devnull return(stp->s_val);
403 b6d98463 2006-04-14 devnull ERROR "there is no .%s in that []", s WARNING;
404 b6d98463 2006-04-14 devnull return(bug);
408 b6d98463 2006-04-14 devnull fixpos(obj *p, double x, double y)
410 b6d98463 2006-04-14 devnull dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y);
411 b6d98463 2006-04-14 devnull return makepos(p->o_x + x, p->o_y + y);
415 b6d98463 2006-04-14 devnull addpos(obj *p, obj *q)
417 b6d98463 2006-04-14 devnull dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y);
418 b6d98463 2006-04-14 devnull return makepos(p->o_x+q->o_x, p->o_y+q->o_y);
422 b6d98463 2006-04-14 devnull subpos(obj *p, obj *q)
424 b6d98463 2006-04-14 devnull dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y);
425 b6d98463 2006-04-14 devnull return makepos(p->o_x-q->o_x, p->o_y-q->o_y);
429 b6d98463 2006-04-14 devnull makenode(int type, int n)
433 b6d98463 2006-04-14 devnull p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(ofloat));
434 b6d98463 2006-04-14 devnull if (p == NULL)
435 b6d98463 2006-04-14 devnull ERROR "out of space in makenode" FATAL;
436 b6d98463 2006-04-14 devnull p->o_type = type;
437 b6d98463 2006-04-14 devnull p->o_count = n;
438 b6d98463 2006-04-14 devnull p->o_nobj = nobj;
439 b6d98463 2006-04-14 devnull p->o_mode = hvmode;
440 b6d98463 2006-04-14 devnull p->o_x = curx;
441 b6d98463 2006-04-14 devnull p->o_y = cury;
442 b6d98463 2006-04-14 devnull p->o_nt1 = ntext1;
443 b6d98463 2006-04-14 devnull p->o_nt2 = ntext;
444 b6d98463 2006-04-14 devnull ntext1 = ntext; /* ready for next caller */
445 b6d98463 2006-04-14 devnull if (nobj >= nobjlist)
446 b6d98463 2006-04-14 devnull objlist = (obj **) grow((char *) objlist, "objlist",
447 b6d98463 2006-04-14 devnull nobjlist *= 2, sizeof(obj *));
448 b6d98463 2006-04-14 devnull objlist[nobj++] = p;
449 b6d98463 2006-04-14 devnull return(p);
453 b6d98463 2006-04-14 devnull extreme(double x, double y) /* record max and min x and y values */
455 b6d98463 2006-04-14 devnull if (x > xmax)
456 b6d98463 2006-04-14 devnull xmax = x;
457 b6d98463 2006-04-14 devnull if (y > ymax)
458 b6d98463 2006-04-14 devnull ymax = y;
459 b6d98463 2006-04-14 devnull if (x < xmin)
460 b6d98463 2006-04-14 devnull xmin = x;
461 b6d98463 2006-04-14 devnull if (y < ymin)
462 b6d98463 2006-04-14 devnull ymin = y;