xref: /plan9/sys/src/cmd/grap/misc.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include "grap.h"
5 #include "y.tab.h"
6 
7 int	nnum	= 0;	/* number of saved numbers */
8 double	num[MAXNUM];
9 
10 int	just;		/* current justification mode (RJUST, etc.) */
11 int	sizeop;		/* current optional operator for size change */
12 double	sizexpr;	/* current size change expression */
13 
savenum(int n,double f)14 void savenum(int n, double f)	/* save f in num[n] */
15 {
16 	num[n] = f;
17 	nnum = n+1;
18 	if (nnum >= MAXNUM)
19 		ERROR "too many numbers" WARNING;
20 }
21 
setjust(int j)22 void setjust(int j)
23 {
24 	just |= j;
25 }
26 
setsize(int op,double expr)27 void setsize(int op, double expr)
28 {
29 	sizeop = op;
30 	sizexpr = expr;
31 }
32 
tostring(char * s)33 char *tostring(char *s)
34 {
35 	register char *p;
36 
37 	p = malloc(strlen(s)+1);
38 	if (p == NULL)
39 		ERROR "out of space in tostring on %s", s FATAL;
40 	strcpy(p, s);
41 	return(p);
42 }
43 
range(Point pt)44 void range(Point pt)	/* update the range for point pt */
45 {
46 	Obj *p = pt.obj;
47 
48 	if (!(p->coord & XFLAG)) {
49 		if (pt.x > p->pt1.x)
50 			p->pt1.x = pt.x;
51 		if (pt.x < p->pt.x)
52 			p->pt.x = pt.x;
53 	}
54 	if (!(p->coord & YFLAG)) {
55 		if (pt.y > p->pt1.y)
56 			p->pt1.y = pt.y;
57 		if (pt.y < p->pt.y)
58 			p->pt.y = pt.y;
59 	}
60 }
61 
halfrange(Obj * p,int side,double val)62 void halfrange(Obj *p, int side, double val)	/* record max and min for one direction */
63 {
64 	if (!(p->coord&XFLAG) && (side == LEFT || side == RIGHT)) {
65 		if (val < p->pt.y)
66 			p->pt.y = val;
67 		if (val > p->pt1.y)
68 			p->pt1.y = val;
69 	} else if (!(p->coord&YFLAG) && (side == TOP || side == BOT)) {
70 		if (val < p->pt.x)
71 			p->pt.x = val;
72 		if (val > p->pt1.x)
73 			p->pt1.x = val;
74 	}
75 }
76 
77 
lookup(char * s,int inst)78 Obj *lookup(char *s, int inst)	/* find s in objlist, install if inst */
79 {
80 	Obj *p;
81 	int found = 0;
82 
83 	for (p = objlist; p; p = p->next){
84 		if (strcmp(s, p->name) == 0) {
85 			found = 1;
86 			break;
87 		}
88 	}
89 	if (p == NULL && inst != 0) {
90 		p = (Obj *) calloc(1, sizeof(Obj));
91 		if (p == NULL)
92 			ERROR "out of space in lookup" FATAL;
93 		p->name = tostring(s);
94 		p->type = NAME;
95 		p->pt = ptmax;
96 		p->pt1 = ptmin;
97 		p->fval = 0.0;
98 		p->next = objlist;
99 		objlist = p;
100 	}
101 	dprintf("lookup(%s,%d) = %d\n", s, inst, found);
102 	return p;
103 }
104 
getvar(Obj * p)105 double getvar(Obj *p)	/* return value of variable */
106 {
107 	return p->fval;
108 }
109 
setvar(Obj * p,double f)110 double setvar(Obj *p, double f)	/* set value of variable to f */
111 {
112 	if (strcmp(p->name, "pointsize") == 0) {	/* kludge */
113 		pointsize = f;
114 		ps_set = 1;
115 	}
116 	p->type = VARNAME;
117 	return p->fval = f;
118 }
119 
makepoint(Obj * s,double x,double y)120 Point makepoint(Obj *s, double x, double y)	/* make a Point */
121 {
122 	Point p;
123 
124 	dprintf("makepoint: %s, %g,%g\n", s->name, x, y);
125 	p.obj = s;
126 	p.x = x;
127 	p.y = y;
128 	return p;
129 }
130 
makefattr(int type,double fval)131 Attr *makefattr(int type, double fval)	/* set double in attribute */
132 {
133 	return makeattr(type, fval, (char *) 0, 0, 0);
134 }
135 
makesattr(char * s)136 Attr *makesattr(char *s)		/* make an Attr cell containing s */
137 {
138 	Attr *ap = makeattr(STRING, sizexpr, s, just, sizeop);
139 	just = sizeop = 0;
140 	sizexpr = 0.0;
141 	return ap;
142 }
143 
makeattr(int type,double fval,char * sval,int just,int op)144 Attr *makeattr(int type, double fval, char *sval, int just, int op)
145 {
146 	Attr *a;
147 
148 	a = (Attr *) malloc(sizeof(Attr));
149 	if (a == NULL)
150 		ERROR "out of space in makeattr" FATAL;
151 	a->type = type;
152 	a->fval = fval;
153 	a->sval = sval;
154 	a->just = just;
155 	a->op = op;
156 	a->next = NULL;
157 	return a;
158 }
159 
addattr(Attr * a1,Attr * ap)160 Attr *addattr(Attr *a1, Attr *ap)	/* add attr ap to end of list a1 */
161 {
162 	Attr *p;
163 
164 	if (a1 == 0)
165 		return ap;
166 	if (ap == 0)
167 		return a1;
168 	for (p = a1; p->next; p = p->next)
169 		;
170 	p->next = ap;
171 	return a1;
172 }
173 
freeattr(Attr * ap)174 void freeattr(Attr *ap)	/* free an attribute list */
175 {
176 	Attr *p;
177 
178 	while (ap) {
179 		p = ap->next;	/* save next */
180 		if (ap->sval)
181 			free(ap->sval);
182 		free((char *) ap);
183 		ap = p;
184 	}
185 }
186 
slprint(Attr * stringlist)187 char *slprint(Attr *stringlist)	/* print strings from stringlist */
188 {
189 	int ntext, n, last_op, last_just;
190 	double last_fval;
191 	static char buf[1000];
192 	Attr *ap;
193 
194 	buf[0] = '\0';
195 	last_op = last_just = 0;
196 	last_fval = 0.0;
197 	for (ntext = 0, ap = stringlist; ap != NULL; ap = ap->next)
198 		ntext++;
199 	sprintf(buf, "box invis wid 0 ht %d*textht", ntext);
200 	n = strlen(buf);
201 	for (ap = stringlist; ap != NULL; ap = ap->next) {
202 		if (ap->op == 0) {	/* propagate last value */
203 			ap->op = last_op;
204 			ap->fval = last_fval;
205 		} else {
206 			last_op = ap->op;
207 			last_fval = ap->fval;
208 		}
209 		sprintf(buf+n, " \"%s\"", ps_set || ap->op ? sizeit(ap) : ap->sval);
210 		if (ap->just)
211 			last_just = ap->just;
212 		if (last_just)
213 			strcat(buf+n, juststr(last_just));
214 		n = strlen(buf);
215 	}
216 	return buf;	/* watch it:  static */
217 }
218 
juststr(int j)219 char *juststr(int j)	/* convert RJUST, etc., into string */
220 {
221 	static char buf[50];
222 
223 	buf[0] = '\0';
224 	if (j & RJUST)
225 		strcat(buf, " rjust");
226 	if (j & LJUST)
227 		strcat(buf, " ljust");
228 	if (j & ABOVE)
229 		strcat(buf, " above");
230 	if (j & BELOW)
231 		strcat(buf, " below");
232 	return buf;	/* watch it:  static */
233 }
234 
sprntf(char * s,Attr * ap)235 char *sprntf(char *s, Attr *ap)	/* sprintf(s, attrlist ap) */
236 {
237 	char buf[500];
238 	int n;
239 	Attr *p;
240 
241 	for (n = 0, p = ap; p; p = p->next)
242 		n++;
243 	switch (n) {
244 	case 0:
245 		return s;
246 	case 1:
247 		sprintf(buf, s, ap->fval);
248 		break;
249 	case 2:
250 		sprintf(buf, s, ap->fval, ap->next->fval);
251 		break;
252 	case 3:
253 		sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval);
254 		break;
255 	case 5:
256 		ERROR "too many expressions in sprintf" WARNING;
257 	case 4:
258 		sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval, ap->next->next->next->fval);
259 		break;
260 	}
261 	free(s);
262 	return tostring(buf);
263 }
264