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