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