]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/grap/misc.c
aux/realemu: run cpuproc in same fd group as fileserver
[plan9front.git] / sys / src / cmd / grap / misc.c
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
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
22 void setjust(int j)
23 {
24         just |= j;
25 }
26
27 void setsize(int op, double expr)
28 {
29         sizeop = op;
30         sizexpr = expr;
31 }
32
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
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
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
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
105 double getvar(Obj *p)   /* return value of variable */
106 {
107         return p->fval;
108 }
109
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
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
131 Attr *makefattr(int type, double fval)  /* set double in attribute */
132 {
133         return makeattr(type, fval, (char *) 0, 0, 0);
134 }
135
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
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
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
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
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
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
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 }