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