Blame


1 3ebbd193 2017-06-19 rsc #include <stdio.h>
2 3ebbd193 2017-06-19 rsc #include <string.h>
3 3ebbd193 2017-06-19 rsc #include <stdlib.h>
4 3ebbd193 2017-06-19 rsc #include <math.h>
5 3ebbd193 2017-06-19 rsc #include "pic.h"
6 3ebbd193 2017-06-19 rsc #include "y.tab.h"
7 3ebbd193 2017-06-19 rsc
8 3ebbd193 2017-06-19 rsc int whatpos(obj *p, int corner, double *px, double *py);
9 3ebbd193 2017-06-19 rsc void makeattr(int type, int sub, YYSTYPE val);
10 3ebbd193 2017-06-19 rsc YYSTYPE getblk(obj *, char *);
11 3ebbd193 2017-06-19 rsc
12 3ebbd193 2017-06-19 rsc int
13 3ebbd193 2017-06-19 rsc setdir(int n) /* set direction (hvmode) from LEFT, RIGHT, etc. */
14 3ebbd193 2017-06-19 rsc {
15 3ebbd193 2017-06-19 rsc switch (n) {
16 3ebbd193 2017-06-19 rsc case UP: hvmode = U_DIR; break;
17 3ebbd193 2017-06-19 rsc case DOWN: hvmode = D_DIR; break;
18 3ebbd193 2017-06-19 rsc case LEFT: hvmode = L_DIR; break;
19 3ebbd193 2017-06-19 rsc case RIGHT: hvmode = R_DIR; break;
20 3ebbd193 2017-06-19 rsc }
21 3ebbd193 2017-06-19 rsc return(hvmode);
22 3ebbd193 2017-06-19 rsc }
23 3ebbd193 2017-06-19 rsc
24 3ebbd193 2017-06-19 rsc int
25 3ebbd193 2017-06-19 rsc curdir(void) /* convert current dir (hvmode) to RIGHT, LEFT, etc. */
26 3ebbd193 2017-06-19 rsc {
27 3ebbd193 2017-06-19 rsc switch (hvmode) {
28 3ebbd193 2017-06-19 rsc case R_DIR: return RIGHT;
29 3ebbd193 2017-06-19 rsc case L_DIR: return LEFT;
30 3ebbd193 2017-06-19 rsc case U_DIR: return UP;
31 3ebbd193 2017-06-19 rsc case D_DIR: return DOWN;
32 3ebbd193 2017-06-19 rsc }
33 3ebbd193 2017-06-19 rsc ERROR "can't happen curdir" FATAL;
34 3ebbd193 2017-06-19 rsc return 0;
35 3ebbd193 2017-06-19 rsc }
36 3ebbd193 2017-06-19 rsc
37 fa325e9b 2020-01-10 cross double
38 3ebbd193 2017-06-19 rsc getcomp(obj *p, int t) /* return component of a position */
39 3ebbd193 2017-06-19 rsc {
40 3ebbd193 2017-06-19 rsc switch (t) {
41 3ebbd193 2017-06-19 rsc case DOTX:
42 3ebbd193 2017-06-19 rsc return p->o_x;
43 3ebbd193 2017-06-19 rsc case DOTY:
44 3ebbd193 2017-06-19 rsc return p->o_y;
45 3ebbd193 2017-06-19 rsc case DOTWID:
46 3ebbd193 2017-06-19 rsc switch (p->o_type) {
47 3ebbd193 2017-06-19 rsc case BOX:
48 3ebbd193 2017-06-19 rsc case BLOCK:
49 3ebbd193 2017-06-19 rsc case TEXT:
50 3ebbd193 2017-06-19 rsc return p->o_val[0];
51 3ebbd193 2017-06-19 rsc case CIRCLE:
52 3ebbd193 2017-06-19 rsc case ELLIPSE:
53 3ebbd193 2017-06-19 rsc return 2 * p->o_val[0];
54 3ebbd193 2017-06-19 rsc case LINE:
55 3ebbd193 2017-06-19 rsc case ARROW:
56 3ebbd193 2017-06-19 rsc return p->o_val[0] - p->o_x;
57 3ebbd193 2017-06-19 rsc case PLACE:
58 3ebbd193 2017-06-19 rsc return 0;
59 3ebbd193 2017-06-19 rsc }
60 3ebbd193 2017-06-19 rsc case DOTHT:
61 3ebbd193 2017-06-19 rsc switch (p->o_type) {
62 3ebbd193 2017-06-19 rsc case BOX:
63 3ebbd193 2017-06-19 rsc case BLOCK:
64 3ebbd193 2017-06-19 rsc case TEXT:
65 3ebbd193 2017-06-19 rsc return p->o_val[1];
66 3ebbd193 2017-06-19 rsc case CIRCLE:
67 3ebbd193 2017-06-19 rsc case ELLIPSE:
68 3ebbd193 2017-06-19 rsc return 2 * p->o_val[1];
69 3ebbd193 2017-06-19 rsc case LINE:
70 3ebbd193 2017-06-19 rsc case ARROW:
71 3ebbd193 2017-06-19 rsc return p->o_val[1] - p->o_y;
72 3ebbd193 2017-06-19 rsc case PLACE:
73 3ebbd193 2017-06-19 rsc return 0;
74 3ebbd193 2017-06-19 rsc }
75 3ebbd193 2017-06-19 rsc case DOTRAD:
76 3ebbd193 2017-06-19 rsc switch (p->o_type) {
77 3ebbd193 2017-06-19 rsc case CIRCLE:
78 3ebbd193 2017-06-19 rsc case ELLIPSE:
79 3ebbd193 2017-06-19 rsc return p->o_val[0];
80 3ebbd193 2017-06-19 rsc }
81 3ebbd193 2017-06-19 rsc }
82 3ebbd193 2017-06-19 rsc ERROR "you asked for a weird dimension or position" WARNING;
83 3ebbd193 2017-06-19 rsc return 0;
84 3ebbd193 2017-06-19 rsc }
85 3ebbd193 2017-06-19 rsc
86 3ebbd193 2017-06-19 rsc double exprlist[100];
87 3ebbd193 2017-06-19 rsc int nexpr = 0;
88 3ebbd193 2017-06-19 rsc
89 3ebbd193 2017-06-19 rsc void exprsave(double f)
90 3ebbd193 2017-06-19 rsc {
91 3ebbd193 2017-06-19 rsc exprlist[nexpr++] = f;
92 3ebbd193 2017-06-19 rsc }
93 3ebbd193 2017-06-19 rsc
94 3ebbd193 2017-06-19 rsc char *sprintgen(char *fmt)
95 3ebbd193 2017-06-19 rsc {
96 3ebbd193 2017-06-19 rsc char buf[1000];
97 3ebbd193 2017-06-19 rsc
98 3ebbd193 2017-06-19 rsc sprintf(buf, fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]);
99 3ebbd193 2017-06-19 rsc nexpr = 0;
100 3ebbd193 2017-06-19 rsc free(fmt);
101 3ebbd193 2017-06-19 rsc return tostring(buf);
102 3ebbd193 2017-06-19 rsc }
103 3ebbd193 2017-06-19 rsc
104 3ebbd193 2017-06-19 rsc void makefattr(int type, int sub, double f) /* double attr */
105 3ebbd193 2017-06-19 rsc {
106 3ebbd193 2017-06-19 rsc YYSTYPE val;
107 3ebbd193 2017-06-19 rsc val.f = f;
108 3ebbd193 2017-06-19 rsc makeattr(type, sub, val);
109 3ebbd193 2017-06-19 rsc }
110 3ebbd193 2017-06-19 rsc
111 3ebbd193 2017-06-19 rsc void makeoattr(int type, obj *o) /* obj* attr */
112 3ebbd193 2017-06-19 rsc {
113 3ebbd193 2017-06-19 rsc YYSTYPE val;
114 3ebbd193 2017-06-19 rsc val.o = o;
115 3ebbd193 2017-06-19 rsc makeattr(type, 0, val);
116 3ebbd193 2017-06-19 rsc }
117 3ebbd193 2017-06-19 rsc
118 3ebbd193 2017-06-19 rsc void makeiattr(int type, int i) /* int attr */
119 3ebbd193 2017-06-19 rsc {
120 3ebbd193 2017-06-19 rsc YYSTYPE val;
121 3ebbd193 2017-06-19 rsc val.i = i;
122 3ebbd193 2017-06-19 rsc makeattr(type, 0, val);
123 3ebbd193 2017-06-19 rsc }
124 3ebbd193 2017-06-19 rsc
125 3ebbd193 2017-06-19 rsc void maketattr(int sub, char *p) /* text attribute: takes two */
126 3ebbd193 2017-06-19 rsc {
127 3ebbd193 2017-06-19 rsc YYSTYPE val;
128 3ebbd193 2017-06-19 rsc val.p = p;
129 3ebbd193 2017-06-19 rsc makeattr(TEXTATTR, sub, val);
130 3ebbd193 2017-06-19 rsc }
131 3ebbd193 2017-06-19 rsc
132 3ebbd193 2017-06-19 rsc void addtattr(int sub) /* add text attrib to existing item */
133 3ebbd193 2017-06-19 rsc {
134 3ebbd193 2017-06-19 rsc attr[nattr-1].a_sub |= sub;
135 3ebbd193 2017-06-19 rsc }
136 3ebbd193 2017-06-19 rsc
137 3ebbd193 2017-06-19 rsc void makevattr(char *p) /* varname attribute */
138 3ebbd193 2017-06-19 rsc {
139 3ebbd193 2017-06-19 rsc YYSTYPE val;
140 3ebbd193 2017-06-19 rsc val.p = p;
141 3ebbd193 2017-06-19 rsc makeattr(VARNAME, 0, val);
142 3ebbd193 2017-06-19 rsc }
143 3ebbd193 2017-06-19 rsc
144 3ebbd193 2017-06-19 rsc void makeattr(int type, int sub, YYSTYPE val) /* add attribute type and val */
145 3ebbd193 2017-06-19 rsc {
146 3ebbd193 2017-06-19 rsc if (type == 0 && val.i == 0) { /* clear table for next stat */
147 3ebbd193 2017-06-19 rsc nattr = 0;
148 3ebbd193 2017-06-19 rsc return;
149 3ebbd193 2017-06-19 rsc }
150 3ebbd193 2017-06-19 rsc if (nattr >= nattrlist)
151 3ebbd193 2017-06-19 rsc attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr));
152 3ebbd193 2017-06-19 rsc dprintf("attr %d: %d %d %d\n", nattr, type, sub, val.i);
153 3ebbd193 2017-06-19 rsc attr[nattr].a_type = type;
154 3ebbd193 2017-06-19 rsc attr[nattr].a_sub = sub;
155 3ebbd193 2017-06-19 rsc attr[nattr].a_val = val;
156 3ebbd193 2017-06-19 rsc nattr++;
157 3ebbd193 2017-06-19 rsc }
158 3ebbd193 2017-06-19 rsc
159 3ebbd193 2017-06-19 rsc void printexpr(double f) /* print expression for debugging */
160 3ebbd193 2017-06-19 rsc {
161 3ebbd193 2017-06-19 rsc printf("%g\n", f);
162 3ebbd193 2017-06-19 rsc }
163 3ebbd193 2017-06-19 rsc
164 3ebbd193 2017-06-19 rsc void printpos(obj *p) /* print position for debugging */
165 3ebbd193 2017-06-19 rsc {
166 3ebbd193 2017-06-19 rsc printf("%g, %g\n", p->o_x, p->o_y);
167 3ebbd193 2017-06-19 rsc }
168 3ebbd193 2017-06-19 rsc
169 3ebbd193 2017-06-19 rsc char *tostring(char *s)
170 3ebbd193 2017-06-19 rsc {
171 3ebbd193 2017-06-19 rsc register char *p;
172 3ebbd193 2017-06-19 rsc
173 3ebbd193 2017-06-19 rsc p = malloc(strlen(s)+1);
174 3ebbd193 2017-06-19 rsc if (p == NULL)
175 3ebbd193 2017-06-19 rsc ERROR "out of space in tostring on %s", s FATAL;
176 3ebbd193 2017-06-19 rsc strcpy(p, s);
177 3ebbd193 2017-06-19 rsc return(p);
178 3ebbd193 2017-06-19 rsc }
179 3ebbd193 2017-06-19 rsc
180 3ebbd193 2017-06-19 rsc obj *makepos(double x, double y) /* make a position cell */
181 3ebbd193 2017-06-19 rsc {
182 3ebbd193 2017-06-19 rsc obj *p;
183 3ebbd193 2017-06-19 rsc
184 3ebbd193 2017-06-19 rsc p = makenode(PLACE, 0);
185 3ebbd193 2017-06-19 rsc p->o_x = x;
186 3ebbd193 2017-06-19 rsc p->o_y = y;
187 3ebbd193 2017-06-19 rsc return(p);
188 3ebbd193 2017-06-19 rsc }
189 3ebbd193 2017-06-19 rsc
190 3ebbd193 2017-06-19 rsc obj *makebetween(double f, obj *p1, obj *p2) /* make position between p1 and p2 */
191 3ebbd193 2017-06-19 rsc {
192 3ebbd193 2017-06-19 rsc obj *p;
193 3ebbd193 2017-06-19 rsc
194 3ebbd193 2017-06-19 rsc dprintf("fraction = %.2f\n", f);
195 3ebbd193 2017-06-19 rsc p = makenode(PLACE, 0);
196 3ebbd193 2017-06-19 rsc p->o_x = p1->o_x + f * (p2->o_x - p1->o_x);
197 3ebbd193 2017-06-19 rsc p->o_y = p1->o_y + f * (p2->o_y - p1->o_y);
198 3ebbd193 2017-06-19 rsc return(p);
199 3ebbd193 2017-06-19 rsc }
200 3ebbd193 2017-06-19 rsc
201 3ebbd193 2017-06-19 rsc obj *getpos(obj *p, int corner) /* find position of point */
202 3ebbd193 2017-06-19 rsc {
203 3ebbd193 2017-06-19 rsc double x, y;
204 3ebbd193 2017-06-19 rsc
205 3ebbd193 2017-06-19 rsc whatpos(p, corner, &x, &y);
206 3ebbd193 2017-06-19 rsc return makepos(x, y);
207 3ebbd193 2017-06-19 rsc }
208 3ebbd193 2017-06-19 rsc
209 3ebbd193 2017-06-19 rsc int whatpos(obj *p, int corner, double *px, double *py) /* what is the position (no side effect) */
210 3ebbd193 2017-06-19 rsc {
211 3ebbd193 2017-06-19 rsc double x, y, x1, y1;
212 3ebbd193 2017-06-19 rsc
213 3ebbd193 2017-06-19 rsc x1 = y1 = 0.0; /* Botch? (gcc) */
214 3ebbd193 2017-06-19 rsc
215 3ebbd193 2017-06-19 rsc dprintf("whatpos %p %d %d\n", (void*)p, p->o_type, corner);
216 3ebbd193 2017-06-19 rsc x = p->o_x;
217 3ebbd193 2017-06-19 rsc y = p->o_y;
218 3ebbd193 2017-06-19 rsc if (p->o_type != PLACE && p->o_type != MOVE) {
219 3ebbd193 2017-06-19 rsc x1 = p->o_val[0];
220 3ebbd193 2017-06-19 rsc y1 = p->o_val[1];
221 3ebbd193 2017-06-19 rsc }
222 3ebbd193 2017-06-19 rsc switch (p->o_type) {
223 3ebbd193 2017-06-19 rsc case PLACE:
224 3ebbd193 2017-06-19 rsc break;
225 3ebbd193 2017-06-19 rsc case BOX:
226 3ebbd193 2017-06-19 rsc case BLOCK:
227 3ebbd193 2017-06-19 rsc case TEXT:
228 3ebbd193 2017-06-19 rsc switch (corner) {
229 3ebbd193 2017-06-19 rsc case NORTH: y += y1 / 2; break;
230 3ebbd193 2017-06-19 rsc case SOUTH: y -= y1 / 2; break;
231 3ebbd193 2017-06-19 rsc case EAST: x += x1 / 2; break;
232 3ebbd193 2017-06-19 rsc case WEST: x -= x1 / 2; break;
233 3ebbd193 2017-06-19 rsc case NE: x += x1 / 2; y += y1 / 2; break;
234 3ebbd193 2017-06-19 rsc case SW: x -= x1 / 2; y -= y1 / 2; break;
235 3ebbd193 2017-06-19 rsc case SE: x += x1 / 2; y -= y1 / 2; break;
236 3ebbd193 2017-06-19 rsc case NW: x -= x1 / 2; y += y1 / 2; break;
237 3ebbd193 2017-06-19 rsc case START:
238 3ebbd193 2017-06-19 rsc if (p->o_type == BLOCK)
239 3ebbd193 2017-06-19 rsc return whatpos(objlist[(int)p->o_val[2]], START, px, py);
240 3ebbd193 2017-06-19 rsc case END:
241 3ebbd193 2017-06-19 rsc if (p->o_type == BLOCK)
242 3ebbd193 2017-06-19 rsc return whatpos(objlist[(int)p->o_val[3]], END, px, py);
243 3ebbd193 2017-06-19 rsc }
244 3ebbd193 2017-06-19 rsc break;
245 3ebbd193 2017-06-19 rsc case ARC:
246 3ebbd193 2017-06-19 rsc switch (corner) {
247 3ebbd193 2017-06-19 rsc case START:
248 3ebbd193 2017-06-19 rsc if (p->o_attr & CW_ARC) {
249 3ebbd193 2017-06-19 rsc x = p->o_val[2]; y = p->o_val[3];
250 3ebbd193 2017-06-19 rsc } else {
251 3ebbd193 2017-06-19 rsc x = x1; y = y1;
252 3ebbd193 2017-06-19 rsc }
253 3ebbd193 2017-06-19 rsc break;
254 3ebbd193 2017-06-19 rsc case END:
255 3ebbd193 2017-06-19 rsc if (p->o_attr & CW_ARC) {
256 3ebbd193 2017-06-19 rsc x = x1; y = y1;
257 3ebbd193 2017-06-19 rsc } else {
258 3ebbd193 2017-06-19 rsc x = p->o_val[2]; y = p->o_val[3];
259 3ebbd193 2017-06-19 rsc }
260 3ebbd193 2017-06-19 rsc break;
261 3ebbd193 2017-06-19 rsc }
262 3ebbd193 2017-06-19 rsc if (corner == START || corner == END)
263 3ebbd193 2017-06-19 rsc break;
264 3ebbd193 2017-06-19 rsc x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y));
265 3ebbd193 2017-06-19 rsc /* Fall Through! */
266 3ebbd193 2017-06-19 rsc case CIRCLE:
267 3ebbd193 2017-06-19 rsc case ELLIPSE:
268 3ebbd193 2017-06-19 rsc switch (corner) {
269 3ebbd193 2017-06-19 rsc case NORTH: y += y1; break;
270 3ebbd193 2017-06-19 rsc case SOUTH: y -= y1; break;
271 3ebbd193 2017-06-19 rsc case EAST: x += x1; break;
272 3ebbd193 2017-06-19 rsc case WEST: x -= x1; break;
273 3ebbd193 2017-06-19 rsc case NE: x += 0.707 * x1; y += 0.707 * y1; break;
274 3ebbd193 2017-06-19 rsc case SE: x += 0.707 * x1; y -= 0.707 * y1; break;
275 3ebbd193 2017-06-19 rsc case NW: x -= 0.707 * x1; y += 0.707 * y1; break;
276 3ebbd193 2017-06-19 rsc case SW: x -= 0.707 * x1; y -= 0.707 * y1; break;
277 3ebbd193 2017-06-19 rsc }
278 3ebbd193 2017-06-19 rsc break;
279 3ebbd193 2017-06-19 rsc case LINE:
280 3ebbd193 2017-06-19 rsc case SPLINE:
281 3ebbd193 2017-06-19 rsc case ARROW:
282 3ebbd193 2017-06-19 rsc switch (corner) {
283 3ebbd193 2017-06-19 rsc case START: break; /* already in place */
284 3ebbd193 2017-06-19 rsc case END: x = x1; y = y1; break;
285 3ebbd193 2017-06-19 rsc default: /* change! */
286 3ebbd193 2017-06-19 rsc case CENTER: x = (x+x1)/2; y = (y+y1)/2; break;
287 3ebbd193 2017-06-19 rsc case NORTH: if (y1 > y) { x = x1; y = y1; } break;
288 3ebbd193 2017-06-19 rsc case SOUTH: if (y1 < y) { x = x1; y = y1; } break;
289 3ebbd193 2017-06-19 rsc case EAST: if (x1 > x) { x = x1; y = y1; } break;
290 3ebbd193 2017-06-19 rsc case WEST: if (x1 < x) { x = x1; y = y1; } break;
291 3ebbd193 2017-06-19 rsc }
292 3ebbd193 2017-06-19 rsc break;
293 3ebbd193 2017-06-19 rsc case MOVE:
294 3ebbd193 2017-06-19 rsc /* really ought to be same as line... */
295 3ebbd193 2017-06-19 rsc break;
296 3ebbd193 2017-06-19 rsc }
297 3ebbd193 2017-06-19 rsc dprintf("whatpos returns %g %g\n", x, y);
298 3ebbd193 2017-06-19 rsc *px = x;
299 3ebbd193 2017-06-19 rsc *py = y;
300 3ebbd193 2017-06-19 rsc return 1;
301 3ebbd193 2017-06-19 rsc }
302 3ebbd193 2017-06-19 rsc
303 3ebbd193 2017-06-19 rsc obj *gethere(void) /* make a place for curx,cury */
304 3ebbd193 2017-06-19 rsc {
305 3ebbd193 2017-06-19 rsc dprintf("gethere %g %g\n", curx, cury);
306 3ebbd193 2017-06-19 rsc return(makepos(curx, cury));
307 3ebbd193 2017-06-19 rsc }
308 3ebbd193 2017-06-19 rsc
309 3ebbd193 2017-06-19 rsc obj *getlast(int n, int t) /* find n-th previous occurrence of type t */
310 3ebbd193 2017-06-19 rsc {
311 3ebbd193 2017-06-19 rsc int i, k;
312 3ebbd193 2017-06-19 rsc obj *p;
313 3ebbd193 2017-06-19 rsc
314 3ebbd193 2017-06-19 rsc k = n;
315 3ebbd193 2017-06-19 rsc for (i = nobj-1; i >= 0; i--) {
316 3ebbd193 2017-06-19 rsc p = objlist[i];
317 3ebbd193 2017-06-19 rsc if (p->o_type == BLOCKEND) {
318 3ebbd193 2017-06-19 rsc i = p->o_val[4];
319 3ebbd193 2017-06-19 rsc continue;
320 3ebbd193 2017-06-19 rsc }
321 3ebbd193 2017-06-19 rsc if (p->o_type != t)
322 3ebbd193 2017-06-19 rsc continue;
323 3ebbd193 2017-06-19 rsc if (--k > 0)
324 3ebbd193 2017-06-19 rsc continue; /* not there yet */
325 3ebbd193 2017-06-19 rsc dprintf("got a last of x,y= %g,%g\n", p->o_x, p->o_y);
326 3ebbd193 2017-06-19 rsc return(p);
327 3ebbd193 2017-06-19 rsc }
328 3ebbd193 2017-06-19 rsc ERROR "there is no %dth last", n WARNING;
329 3ebbd193 2017-06-19 rsc return(NULL);
330 3ebbd193 2017-06-19 rsc }
331 3ebbd193 2017-06-19 rsc
332 3ebbd193 2017-06-19 rsc obj *getfirst(int n, int t) /* find n-th occurrence of type t */
333 3ebbd193 2017-06-19 rsc {
334 3ebbd193 2017-06-19 rsc int i, k;
335 3ebbd193 2017-06-19 rsc obj *p;
336 3ebbd193 2017-06-19 rsc
337 3ebbd193 2017-06-19 rsc k = n;
338 3ebbd193 2017-06-19 rsc for (i = 0; i < nobj; i++) {
339 3ebbd193 2017-06-19 rsc p = objlist[i];
340 3ebbd193 2017-06-19 rsc if (p->o_type == BLOCK && t != BLOCK) { /* skip whole block */
341 3ebbd193 2017-06-19 rsc i = p->o_val[5] + 1;
342 3ebbd193 2017-06-19 rsc continue;
343 3ebbd193 2017-06-19 rsc }
344 3ebbd193 2017-06-19 rsc if (p->o_type != t)
345 3ebbd193 2017-06-19 rsc continue;
346 3ebbd193 2017-06-19 rsc if (--k > 0)
347 3ebbd193 2017-06-19 rsc continue; /* not there yet */
348 3ebbd193 2017-06-19 rsc dprintf("got a first of x,y= %g,%g\n", p->o_x, p->o_y);
349 3ebbd193 2017-06-19 rsc return(p);
350 3ebbd193 2017-06-19 rsc }
351 3ebbd193 2017-06-19 rsc ERROR "there is no %dth ", n WARNING;
352 3ebbd193 2017-06-19 rsc return(NULL);
353 3ebbd193 2017-06-19 rsc }
354 3ebbd193 2017-06-19 rsc
355 3ebbd193 2017-06-19 rsc double getblkvar(obj *p, char *s) /* find variable s2 in block p */
356 3ebbd193 2017-06-19 rsc {
357 3ebbd193 2017-06-19 rsc YYSTYPE y;
358 3ebbd193 2017-06-19 rsc
359 3ebbd193 2017-06-19 rsc y = getblk(p, s);
360 3ebbd193 2017-06-19 rsc return y.f;
361 3ebbd193 2017-06-19 rsc }
362 3ebbd193 2017-06-19 rsc
363 3ebbd193 2017-06-19 rsc obj *getblock(obj *p, char *s) /* find variable s in block p */
364 3ebbd193 2017-06-19 rsc {
365 3ebbd193 2017-06-19 rsc YYSTYPE y;
366 3ebbd193 2017-06-19 rsc
367 3ebbd193 2017-06-19 rsc y = getblk(p, s);
368 3ebbd193 2017-06-19 rsc return y.o;
369 3ebbd193 2017-06-19 rsc }
370 3ebbd193 2017-06-19 rsc
371 3ebbd193 2017-06-19 rsc YYSTYPE getblk(obj *p, char *s) /* find union type for s in p */
372 3ebbd193 2017-06-19 rsc {
373 3ebbd193 2017-06-19 rsc static YYSTYPE bug;
374 3ebbd193 2017-06-19 rsc struct symtab *stp;
375 3ebbd193 2017-06-19 rsc
376 3ebbd193 2017-06-19 rsc if (p->o_type != BLOCK) {
377 3ebbd193 2017-06-19 rsc ERROR ".%s is not in that block", s WARNING;
378 3ebbd193 2017-06-19 rsc return(bug);
379 3ebbd193 2017-06-19 rsc }
380 3ebbd193 2017-06-19 rsc for (stp = p->o_symtab; stp != NULL; stp = stp->s_next)
381 3ebbd193 2017-06-19 rsc if (strcmp(s, stp->s_name) == 0) {
382 3ebbd193 2017-06-19 rsc dprintf("getblk %s found x,y= %g,%g\n",
383 3ebbd193 2017-06-19 rsc s, (stp->s_val.o)->o_x, (stp->s_val.o)->o_y);
384 3ebbd193 2017-06-19 rsc return(stp->s_val);
385 3ebbd193 2017-06-19 rsc }
386 3ebbd193 2017-06-19 rsc ERROR "there is no .%s in that []", s WARNING;
387 3ebbd193 2017-06-19 rsc return(bug);
388 3ebbd193 2017-06-19 rsc }
389 3ebbd193 2017-06-19 rsc
390 3ebbd193 2017-06-19 rsc obj *fixpos(obj *p, double x, double y)
391 3ebbd193 2017-06-19 rsc {
392 3ebbd193 2017-06-19 rsc dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y);
393 3ebbd193 2017-06-19 rsc return makepos(p->o_x + x, p->o_y + y);
394 3ebbd193 2017-06-19 rsc }
395 3ebbd193 2017-06-19 rsc
396 3ebbd193 2017-06-19 rsc obj *addpos(obj *p, obj *q)
397 3ebbd193 2017-06-19 rsc {
398 3ebbd193 2017-06-19 rsc dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y);
399 3ebbd193 2017-06-19 rsc return makepos(p->o_x+q->o_x, p->o_y+q->o_y);
400 3ebbd193 2017-06-19 rsc }
401 3ebbd193 2017-06-19 rsc
402 3ebbd193 2017-06-19 rsc obj *subpos(obj *p, obj *q)
403 3ebbd193 2017-06-19 rsc {
404 3ebbd193 2017-06-19 rsc dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y);
405 3ebbd193 2017-06-19 rsc return makepos(p->o_x-q->o_x, p->o_y-q->o_y);
406 3ebbd193 2017-06-19 rsc }
407 3ebbd193 2017-06-19 rsc
408 3ebbd193 2017-06-19 rsc obj *makenode(int type, int n)
409 3ebbd193 2017-06-19 rsc {
410 3ebbd193 2017-06-19 rsc obj *p;
411 3ebbd193 2017-06-19 rsc
412 3ebbd193 2017-06-19 rsc p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(ofloat));
413 3ebbd193 2017-06-19 rsc if (p == NULL)
414 3ebbd193 2017-06-19 rsc ERROR "out of space in makenode" FATAL;
415 3ebbd193 2017-06-19 rsc p->o_type = type;
416 3ebbd193 2017-06-19 rsc p->o_count = n;
417 3ebbd193 2017-06-19 rsc p->o_nobj = nobj;
418 3ebbd193 2017-06-19 rsc p->o_mode = hvmode;
419 3ebbd193 2017-06-19 rsc p->o_x = curx;
420 3ebbd193 2017-06-19 rsc p->o_y = cury;
421 3ebbd193 2017-06-19 rsc p->o_nt1 = ntext1;
422 3ebbd193 2017-06-19 rsc p->o_nt2 = ntext;
423 3ebbd193 2017-06-19 rsc ntext1 = ntext; /* ready for next caller */
424 3ebbd193 2017-06-19 rsc if (nobj >= nobjlist)
425 3ebbd193 2017-06-19 rsc objlist = (obj **) grow((char *) objlist, "objlist",
426 3ebbd193 2017-06-19 rsc nobjlist *= 2, sizeof(obj *));
427 3ebbd193 2017-06-19 rsc objlist[nobj++] = p;
428 3ebbd193 2017-06-19 rsc return(p);
429 3ebbd193 2017-06-19 rsc }
430 3ebbd193 2017-06-19 rsc
431 3ebbd193 2017-06-19 rsc void extreme(double x, double y) /* record max and min x and y values */
432 3ebbd193 2017-06-19 rsc {
433 3ebbd193 2017-06-19 rsc if (x > xmax)
434 3ebbd193 2017-06-19 rsc xmax = x;
435 3ebbd193 2017-06-19 rsc if (y > ymax)
436 3ebbd193 2017-06-19 rsc ymax = y;
437 3ebbd193 2017-06-19 rsc if (x < xmin)
438 3ebbd193 2017-06-19 rsc xmin = x;
439 3ebbd193 2017-06-19 rsc if (y < ymin)
440 3ebbd193 2017-06-19 rsc ymin = y;
441 3ebbd193 2017-06-19 rsc }