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