123946Sjaap #ifndef lint
2*24089Sjaap static char sccsid[] = "@(#)misc.c 3.1 (CWI) 85/07/30";
323946Sjaap #endif lint
4*24089Sjaap
523946Sjaap #include <stdio.h>
623946Sjaap #include "pic.h"
723946Sjaap #include "y.tab.h"
823946Sjaap
setdir(n)924016Sjaap setdir(n) /* set direction (hvmode) from LEFT, RIGHT, etc. */
1023946Sjaap int n;
1123946Sjaap {
1223946Sjaap switch (n) {
1323946Sjaap case UP: hvmode = U_DIR; break;
1423946Sjaap case DOWN: hvmode = D_DIR; break;
1523946Sjaap case LEFT: hvmode = L_DIR; break;
1623946Sjaap case RIGHT: hvmode = R_DIR; break;
1723946Sjaap }
1823946Sjaap return(hvmode);
1923946Sjaap }
2023946Sjaap
curdir()2124016Sjaap curdir() /* convert current dir (hvmode) to RIGHT, LEFT, etc. */
2224016Sjaap {
2324016Sjaap switch (hvmode) {
2424016Sjaap case R_DIR: return RIGHT;
2524016Sjaap case L_DIR: return LEFT;
2624016Sjaap case U_DIR: return UP;
2724016Sjaap case D_DIR: return DOWN;
2824016Sjaap }
2924016Sjaap }
3024016Sjaap
getcomp(p,t)3123946Sjaap float getcomp(p, t) /* return component of a position */
3224016Sjaap obj *p;
3323946Sjaap int t;
3423946Sjaap {
3523946Sjaap switch (t) {
3623946Sjaap case DOTX:
3723946Sjaap return p->o_x;
3823946Sjaap case DOTY:
3923946Sjaap return p->o_y;
4023946Sjaap case DOTWID:
4123946Sjaap switch (p->o_type) {
4223946Sjaap case BOX:
4323946Sjaap case BLOCK:
44*24089Sjaap case TEXT:
4523946Sjaap return p->o_val[0];
4623946Sjaap case CIRCLE:
4723946Sjaap case ELLIPSE:
4823946Sjaap return 2 * p->o_val[0];
4923946Sjaap case LINE:
5023946Sjaap case ARROW:
5123946Sjaap return p->o_val[0] - p->o_x;
5223946Sjaap }
5323946Sjaap case DOTHT:
5423946Sjaap switch (p->o_type) {
5523946Sjaap case BOX:
5623946Sjaap case BLOCK:
57*24089Sjaap case TEXT:
5823946Sjaap return p->o_val[1];
5923946Sjaap case CIRCLE:
6023946Sjaap case ELLIPSE:
6123946Sjaap return 2 * p->o_val[1];
6223946Sjaap case LINE:
6323946Sjaap case ARROW:
6423946Sjaap return p->o_val[1] - p->o_y;
6523946Sjaap }
6623946Sjaap case DOTRAD:
6723946Sjaap switch (p->o_type) {
6823946Sjaap case CIRCLE:
6923946Sjaap case ELLIPSE:
7023946Sjaap return p->o_val[0];
7123946Sjaap }
7223946Sjaap }
7323946Sjaap }
7423946Sjaap
7524016Sjaap float exprlist[100];
7624016Sjaap int nexpr = 0;
7724016Sjaap
exprsave(f)7824016Sjaap exprsave(f)
7924016Sjaap float f;
8024016Sjaap {
8124016Sjaap exprlist[nexpr++] = f;
8224016Sjaap }
8324016Sjaap
sprintgen(fmt)8424016Sjaap char *sprintgen(fmt)
8524016Sjaap char *fmt;
8624016Sjaap {
8724016Sjaap int i;
8824016Sjaap char buf[1000];
8924016Sjaap
9024016Sjaap sprintf(buf, fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]);
9124016Sjaap nexpr = 0;
9224016Sjaap free(fmt);
9324016Sjaap return tostring(buf);
9424016Sjaap }
9524016Sjaap
makefattr(type,sub,f)9624016Sjaap makefattr(type, sub, f) /* float attr */
9724016Sjaap int type, sub;
9824016Sjaap float f;
9924016Sjaap {
10023946Sjaap YYSTYPE val;
10124016Sjaap val.f = f;
10224016Sjaap makeattr(type, sub, val);
10324016Sjaap }
10424016Sjaap
makeoattr(type,o)10524016Sjaap makeoattr(type, o) /* obj* attr */
10624016Sjaap obj *o;
10723946Sjaap {
10824016Sjaap YYSTYPE val;
10924016Sjaap val.o = o;
11024016Sjaap makeattr(type, 0, val);
11124016Sjaap }
11224016Sjaap
makeiattr(type,i)11324016Sjaap makeiattr(type, i) /* int attr */
11424016Sjaap int i;
11524016Sjaap {
11624016Sjaap YYSTYPE val;
11724016Sjaap val.i = i;
11824016Sjaap makeattr(type, 0, val);
11924016Sjaap }
12024016Sjaap
maketattr(sub,p)12124016Sjaap maketattr(sub, p) /* text attribute: takes two */
12224016Sjaap char *p;
12324016Sjaap {
12424016Sjaap YYSTYPE val;
12524016Sjaap val.p = p;
12624016Sjaap makeattr(TEXTATTR, sub, val);
12724016Sjaap }
12824016Sjaap
addtattr(sub)12924016Sjaap addtattr(sub) /* add text attrib to existing item */
13024016Sjaap {
13124016Sjaap attr[nattr-1].a_sub |= sub;
13224016Sjaap }
13324016Sjaap
makevattr(p)13424016Sjaap makevattr(p) /* varname attribute */
13524016Sjaap char *p;
13624016Sjaap {
13724016Sjaap YYSTYPE val;
13824016Sjaap val.p = p;
13924016Sjaap makeattr(VARNAME, 0, val);
14024016Sjaap }
14124016Sjaap
makeattr(type,sub,val)14224016Sjaap makeattr(type, sub, val) /* add attribute type and val */
14324016Sjaap int type, sub;
14424016Sjaap YYSTYPE val;
14524016Sjaap {
14623946Sjaap if (type == 0 && val.i == 0) { /* clear table for next stat */
14723946Sjaap nattr = 0;
14823946Sjaap return;
14923946Sjaap }
15024016Sjaap if (nattr >= nattrlist)
15124016Sjaap attr = (Attr *) grow(attr, "attr", nattrlist += 100, sizeof(Attr));
15224016Sjaap dprintf("attr %d: %d %d %d\n", nattr, type, sub, val.i);
15323946Sjaap attr[nattr].a_type = type;
15424016Sjaap attr[nattr].a_sub = sub;
15523946Sjaap attr[nattr].a_val = val;
15623946Sjaap nattr++;
15723946Sjaap }
15823946Sjaap
printexpr(f)15923946Sjaap printexpr(f) /* print expression for debugging */
16023946Sjaap float f;
16123946Sjaap {
16224016Sjaap printf("%g\n", f);
16323946Sjaap }
16423946Sjaap
printpos(p)16523946Sjaap printpos(p) /* print position for debugging */
16624016Sjaap obj *p;
16723946Sjaap {
16824016Sjaap printf("%g, %g\n", p->o_x, p->o_y);
16923946Sjaap }
17023946Sjaap
tostring(s)17123946Sjaap char *tostring(s)
17223946Sjaap register char *s;
17323946Sjaap {
17423946Sjaap register char *p;
17523946Sjaap
17623946Sjaap p = malloc(strlen(s)+1);
17723946Sjaap if (p == NULL) {
17823946Sjaap yyerror("out of space in tostring on %s", s);
17923946Sjaap exit(1);
18023946Sjaap }
18123946Sjaap strcpy(p, s);
18223946Sjaap return(p);
18323946Sjaap }
18423946Sjaap
makepos(x,y)18524016Sjaap obj *makepos(x, y) /* make a osition cell */
18623946Sjaap float x, y;
18723946Sjaap {
18824016Sjaap obj *p;
18923946Sjaap
19023946Sjaap p = makenode(PLACE, 0);
19123946Sjaap p->o_x = x;
19223946Sjaap p->o_y = y;
19323946Sjaap return(p);
19423946Sjaap }
19523946Sjaap
makebetween(f,p1,p2)19624016Sjaap obj *makebetween(f, p1, p2) /* make position between p1 and p2 */
19723946Sjaap float f;
19824016Sjaap obj *p1, *p2;
19923946Sjaap {
20024016Sjaap obj *p;
20123946Sjaap
20223946Sjaap dprintf("fraction = %.2f\n", f);
20323946Sjaap p = makenode(PLACE, 0);
20423946Sjaap p->o_x = p1->o_x + f * (p2->o_x - p1->o_x);
20523946Sjaap p->o_y = p1->o_y + f * (p2->o_y - p1->o_y);
20623946Sjaap return(p);
20723946Sjaap }
20823946Sjaap
getpos(p,corner)20924016Sjaap obj *getpos(p, corner) /* find position of point */
21024016Sjaap obj *p;
21123946Sjaap int corner;
21223946Sjaap {
21324016Sjaap float x, y;
21424016Sjaap
21524016Sjaap whatpos(p, corner, &x, &y);
21624016Sjaap return makepos(x, y);
21724016Sjaap }
21824016Sjaap
whatpos(p,corner,px,py)21924016Sjaap whatpos(p, corner, px, py) /* what is the position (no side effect) */
22024016Sjaap obj *p;
22124016Sjaap int corner;
22224016Sjaap float *px, *py;
22324016Sjaap {
22423946Sjaap float x, y, x1, y1;
22524016Sjaap extern double sqrt();
22623946Sjaap
22724016Sjaap dprintf("whatpos %o %d\n", p, corner);
22823946Sjaap x = p->o_x;
22923946Sjaap y = p->o_y;
23023946Sjaap x1 = p->o_val[0];
23123946Sjaap y1 = p->o_val[1];
23223946Sjaap switch (p->o_type) {
23323946Sjaap case PLACE:
23423946Sjaap break;
23523946Sjaap case BOX:
23623946Sjaap case BLOCK:
237*24089Sjaap case TEXT:
23823946Sjaap switch (corner) {
23923946Sjaap case NORTH: y += y1 / 2; break;
24023946Sjaap case SOUTH: y -= y1 / 2; break;
24123946Sjaap case EAST: x += x1 / 2; break;
24223946Sjaap case WEST: x -= x1 / 2; break;
24323946Sjaap case NE: x += x1 / 2; y += y1 / 2; break;
24423946Sjaap case SW: x -= x1 / 2; y -= y1 / 2; break;
24523946Sjaap case SE: x += x1 / 2; y -= y1 / 2; break;
24623946Sjaap case NW: x -= x1 / 2; y += y1 / 2; break;
24723946Sjaap case START:
24823946Sjaap if (p->o_type == BLOCK)
24924016Sjaap return whatpos(objlist[(int)p->o_val[2]], START, px, py);
25023946Sjaap case END:
25123946Sjaap if (p->o_type == BLOCK)
25224016Sjaap return whatpos(objlist[(int)p->o_val[3]], END, px, py);
25323946Sjaap }
25423946Sjaap break;
25524016Sjaap case ARC:
25624016Sjaap switch (corner) {
25724016Sjaap case START:
25824016Sjaap if (p->o_attr & CW_ARC) {
25924016Sjaap x = p->o_val[2]; y = p->o_val[3];
26024016Sjaap } else {
26124016Sjaap x = x1; y = y1;
26224016Sjaap }
26324016Sjaap break;
26424016Sjaap case END:
26524016Sjaap if (p->o_attr & CW_ARC) {
26624016Sjaap x = x1; y = y1;
26724016Sjaap } else {
26824016Sjaap x = p->o_val[2]; y = p->o_val[3];
26924016Sjaap }
27024016Sjaap break;
27124016Sjaap }
27224016Sjaap if (corner == START || corner == END)
27324016Sjaap break;
27424016Sjaap x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y));
27524016Sjaap /* Fall Through! */
27623946Sjaap case CIRCLE:
27723946Sjaap case ELLIPSE:
27823946Sjaap switch (corner) {
27923946Sjaap case NORTH: y += y1; break;
28023946Sjaap case SOUTH: y -= y1; break;
28123946Sjaap case EAST: x += x1; break;
28223946Sjaap case WEST: x -= x1; break;
28323946Sjaap case NE: x += 0.707 * x1; y += 0.707 * y1; break;
28423946Sjaap case SE: x += 0.707 * x1; y -= 0.707 * y1; break;
28523946Sjaap case NW: x -= 0.707 * x1; y += 0.707 * y1; break;
28623946Sjaap case SW: x -= 0.707 * x1; y -= 0.707 * y1; break;
28723946Sjaap }
28823946Sjaap break;
28923946Sjaap case LINE:
29023946Sjaap case SPLINE:
29123946Sjaap case ARROW:
29223946Sjaap case MOVE:
29323946Sjaap switch (corner) {
29423946Sjaap case START: break; /* already in place */
29523946Sjaap case END: x = x1; y = y1; break;
29624016Sjaap default: /* change! */
29723946Sjaap case CENTER: x = (x+x1)/2; y = (y+y1)/2; break;
29823946Sjaap case NORTH: if (y1 > y) { x = x1; y = y1; } break;
29923946Sjaap case SOUTH: if (y1 < y) { x = x1; y = y1; } break;
30023946Sjaap case EAST: if (x1 > x) { x = x1; y = y1; } break;
30123946Sjaap case WEST: if (x1 < x) { x = x1; y = y1; } break;
30223946Sjaap }
30323946Sjaap break;
30423946Sjaap }
30524016Sjaap dprintf("whatpos returns %g %g\n", x, y);
30624016Sjaap *px = x;
30724016Sjaap *py = y;
30823946Sjaap }
30923946Sjaap
gethere(n)31024016Sjaap obj *gethere(n) /* make a place for curx,cury */
31123946Sjaap {
31223946Sjaap dprintf("gethere %g %g\n", curx, cury);
31323946Sjaap return(makepos(curx, cury));
31423946Sjaap }
31523946Sjaap
getlast(n,t)31624016Sjaap obj *getlast(n, t) /* find n-th previous occurrence of type t */
31723946Sjaap int n, t;
31823946Sjaap {
31923946Sjaap int i, k;
32024016Sjaap obj *p;
32123946Sjaap
32223946Sjaap k = n;
32323946Sjaap for (i = nobj-1; i >= 0; i--) {
32423946Sjaap p = objlist[i];
32523946Sjaap if (p->o_type == BLOCKEND) {
32623946Sjaap i = p->o_val[4];
32723946Sjaap continue;
32823946Sjaap }
32923946Sjaap if (p->o_type != t)
33023946Sjaap continue;
33123946Sjaap if (--k > 0)
33223946Sjaap continue; /* not there yet */
33323946Sjaap dprintf("got a last of x,y= %g,%g\n", p->o_x, p->o_y);
33423946Sjaap return(p);
33523946Sjaap }
33623946Sjaap yyerror("there is no %dth last", n);
33723946Sjaap return(NULL);
33823946Sjaap }
33923946Sjaap
getfirst(n,t)34024016Sjaap obj *getfirst(n, t) /* find n-th occurrence of type t */
34123946Sjaap int n, t;
34223946Sjaap {
34323946Sjaap int i, k;
34424016Sjaap obj *p;
34523946Sjaap
34623946Sjaap k = n;
34723946Sjaap for (i = 0; i < nobj; i++) {
34823946Sjaap p = objlist[i];
34923946Sjaap if (p->o_type == BLOCK && t != BLOCK) { /* skip whole block */
35023946Sjaap i = p->o_val[5] + 1;
35123946Sjaap continue;
35223946Sjaap }
35323946Sjaap if (p->o_type != t)
35423946Sjaap continue;
35523946Sjaap if (--k > 0)
35623946Sjaap continue; /* not there yet */
35723946Sjaap dprintf("got a first of x,y= %g,%g\n", p->o_x, p->o_y);
35823946Sjaap return(p);
35923946Sjaap }
36023946Sjaap yyerror("there is no %dth ", n);
36123946Sjaap return(NULL);
36223946Sjaap }
36323946Sjaap
getblkvar(p,s)364*24089Sjaap float getblkvar(p, s) /* find variable s2 in block p */
365*24089Sjaap obj *p;
366*24089Sjaap char *s;
367*24089Sjaap {
368*24089Sjaap YYSTYPE y, getblk();
369*24089Sjaap
370*24089Sjaap y = getblk(p, s);
371*24089Sjaap return y.f;
372*24089Sjaap }
373*24089Sjaap
getblock(p,s)37424016Sjaap obj *getblock(p, s) /* find variable s in block p */
37524016Sjaap obj *p;
37623946Sjaap char *s;
37723946Sjaap {
378*24089Sjaap YYSTYPE y, getblk();
379*24089Sjaap
380*24089Sjaap y = getblk(p, s);
381*24089Sjaap return y.o;
382*24089Sjaap }
383*24089Sjaap
getblk(p,s)384*24089Sjaap YYSTYPE getblk(p, s) /* find union type for s in p */
385*24089Sjaap obj *p;
386*24089Sjaap char *s;
387*24089Sjaap {
388*24089Sjaap static YYSTYPE bug;
38923946Sjaap struct symtab *stp;
39023946Sjaap
39123946Sjaap if (p->o_type != BLOCK) {
39223946Sjaap yyerror(".%s is not in that block", s);
393*24089Sjaap return(bug);
39423946Sjaap }
39524016Sjaap for (stp = p->o_symtab; stp != NULL; stp = stp->s_next)
39623946Sjaap if (strcmp(s, stp->s_name) == 0) {
397*24089Sjaap dprintf("getblk found x,y= %g,%g\n",
39823946Sjaap (stp->s_val.o)->o_x, (stp->s_val.o)->o_y);
399*24089Sjaap return(stp->s_val);
40023946Sjaap }
40123946Sjaap yyerror("there is no .%s in that []", s);
402*24089Sjaap return(bug);
40323946Sjaap }
40423946Sjaap
fixpos(p,x,y)40524016Sjaap obj *fixpos(p, x, y)
40624016Sjaap obj *p;
40723946Sjaap float x, y;
40823946Sjaap {
40923946Sjaap dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y);
41023946Sjaap return makepos(p->o_x + x, p->o_y + y);
41123946Sjaap }
41223946Sjaap
addpos(p,q)41324016Sjaap obj *addpos(p, q)
41424016Sjaap obj *p, *q;
41524016Sjaap {
41624016Sjaap dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y);
41724016Sjaap return makepos(p->o_x+q->o_x, p->o_y+q->o_y);
41824016Sjaap }
41924016Sjaap
subpos(p,q)42024016Sjaap obj *subpos(p, q)
42124016Sjaap obj *p, *q;
42224016Sjaap {
42324016Sjaap dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y);
42424016Sjaap return makepos(p->o_x-q->o_x, p->o_y-q->o_y);
42524016Sjaap }
42624016Sjaap
makenode(type,n)42724016Sjaap obj *makenode(type, n)
42823946Sjaap int type, n;
42923946Sjaap {
43024016Sjaap obj *p;
43123946Sjaap int i;
43224016Sjaap extern char *calloc();
43323946Sjaap
43424016Sjaap p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(float));
43523946Sjaap if (p == NULL) {
43623946Sjaap yyerror("out of space in makenode\n");
43723946Sjaap exit(1);
43823946Sjaap }
43923946Sjaap p->o_type = type;
44023946Sjaap p->o_count = n;
44123946Sjaap p->o_nobj = nobj;
44223946Sjaap p->o_mode = hvmode;
44323946Sjaap p->o_x = curx;
44423946Sjaap p->o_y = cury;
44523946Sjaap p->o_nt1 = ntext1;
44623946Sjaap p->o_nt2 = ntext;
44723946Sjaap ntext1 = ntext; /* ready for next caller */
44824016Sjaap if (nobj >= nobjlist)
44924016Sjaap objlist = (obj **) grow(objlist, "objlist",
45024016Sjaap nobjlist += 100, sizeof(obj *));
45123946Sjaap objlist[nobj++] = p;
45223946Sjaap return(p);
45323946Sjaap }
45423946Sjaap
extreme(x,y)45523946Sjaap extreme(x, y) /* record max and min x and y values */
45623946Sjaap float x, y;
45723946Sjaap {
45823946Sjaap if (x > xmax)
45923946Sjaap xmax = x;
46023946Sjaap if (y > ymax)
46123946Sjaap ymax = y;
46223946Sjaap if (x < xmin)
46323946Sjaap xmin = x;
46423946Sjaap if (y < ymin)
46523946Sjaap ymin = y;
46623946Sjaap }
467