|
|
1.1 root 1: /* memory utilities */
2:
3: #include "ideal.h"
4: #include "y.tab.h"
5:
6: char *fooalloc;
7: #define tryalloc(new,kind) \
8: if (!(new =(kind *) malloc(sizeof (kind)))) {\
9: emergency ();\
10: if (!(new =(kind *) malloc(sizeof (kind)))) {\
11: fprintf (stderr, "ideal: Out of space\n");\
12: exit (1);\
13: }\
14: };\
15: for (fooalloc = (char *) new;\
16: fooalloc < ((char *) new) + sizeof (kind);\
17: fooalloc ++)\
18: *fooalloc = '\0';
19:
20: STMTPTR stmtgen (kind, stmt)
21: int kind;
22: char *stmt;
23: {
24: register STMTPTR newguy;
25: tryalloc(newguy,STMTNODE);
26: newguy->kind = kind;
27: newguy->stmt = stmt;
28: return (newguy);
29: }
30:
31: BOXPTR boxgen (name,stmtlist)
32: int name;
33: STMTPTR stmtlist;
34: {
35: register BOXPTR newguy;
36: STMTPTR bdstmt;
37: tryalloc(newguy,BOXNODE);
38: newguy->name = name;
39: /* the stmts are in reverse order (check the yacc grammar) */
40: newguy->stmtlist = reverse (stmtlist);
41: if (bdstmt = nextstmt (BDLIST, stmtlist))
42: bdstmt->stmt = (char *) reverse ((STMTPTR) bdstmt->stmt);
43: return (newguy);
44: }
45:
46: NAMEPTR namegen (name)
47: int name;
48: {
49: register NAMEPTR newguy;
50: tryalloc(newguy,NAMENODE);
51: newguy->name = name;
52: return (newguy);
53: }
54:
55: EXPRPTR exprgen (expr)
56: EXPR expr;
57: {
58: register EXPRPTR newguy;
59: tryalloc(newguy,EXPRNODE);
60: newguy->expr = expr;
61: return (newguy);
62: }
63:
64: PUTPTR putgen (name, parm, p_or_c)
65: int name;
66: BOXPTR parm;
67: int p_or_c;
68: {
69: register PUTPTR newguy;
70: tryalloc(newguy,PUTNODE);
71: newguy->name = name;
72: newguy->parm = parm;
73: newguy->p_or_c = p_or_c;
74: return (newguy);
75: }
76:
77: PENPTR pengen (from, to, copies, start, end, pen)
78: EXPR from,
79: to,
80: copies,
81: start,
82: end;
83: BOXPTR pen;
84: {
85: register PENPTR newguy;
86: tryalloc(newguy,PEN_NODE);
87: newguy->from = from;
88: newguy->to = to;
89: newguy->copies = copies;
90: newguy->start = start;
91: newguy->end = end;
92: newguy->pen = pen;
93: return (newguy);
94: }
95:
96: MISCPTR miscgen (info)
97: int info;
98: {
99: register MISCPTR newguy;
100: tryalloc(newguy,MISCNODE);
101: newguy->info = info;
102: return (newguy);
103: }
104:
105: INTLPTR intlgen (oper, left, right)
106: int oper;
107: EXPR left,
108: right;
109: {
110: register INTLPTR newguy;
111: tryalloc(newguy,EXPRINTL);
112: newguy->leaf = FALSE;
113: newguy->used = TRUE;
114: newguy->oper = oper;
115: newguy->left = left;
116: newguy->right = right;
117: return (newguy);
118: }
119:
120: INTLPTR commagen (real, imag)
121: float real,
122: imag;
123: {
124: register INTLPTR newguy;
125: tryalloc(newguy,EXPRINTL);
126: newguy->leaf = FALSE;
127: newguy->used = TRUE;
128: newguy->oper = ';';
129: newguy->left = (EXPR) depgen ((VARPTR) NULL, real);
130: newguy->right = (EXPR) depgen ((VARPTR) NULL, imag);
131: return (newguy);
132: }
133:
134: EXTLPTR extlgen (path)
135: NAMEPTR path;
136: {
137: register EXTLPTR newguy;
138: tryalloc(newguy,EXPREXTL);
139: newguy->leaf = TRUE;
140: newguy->used = TRUE;
141: newguy->info.path = path;
142: newguy->kind = PATH;
143: return (newguy);
144: }
145:
146: EXTLPTR fextlgen (value)
147: float value;
148: {
149: register EXTLPTR newguy;
150: tryalloc(newguy,EXPREXTL);
151: newguy->leaf = TRUE;
152: newguy->leaf = TRUE;
153: newguy->info.const = value;
154: newguy->kind = CONST;
155: return (newguy);
156: }
157:
158: NOADPTR noadgen (defnode, edgevarlist, boxvarlist)
159: PUTPTR defnode;
160: VARPTR edgevarlist;
161: VARPTR boxvarlist;
162: {
163: register NOADPTR newguy;
164: tryalloc(newguy,NOAD);
165: newguy->defnode = defnode;
166: newguy->edgevarlist = edgevarlist;
167: newguy->boxvarlist = boxvarlist;
168: return (newguy);
169: }
170:
171: VARPTR vargen (name, re, deplist)
172: int name;
173: boolean re;
174: DEPPTR deplist;
175: {
176: register VARPTR newguy;
177: tryalloc(newguy,VARNODE);
178: newguy->re_name = re?name:-name;
179: newguy->deplist = deplist;
180: return (newguy);
181: }
182:
183: static DEPPTR depavh = NULL;
184: static DEPPTR depavt = NULL;
185:
186: DEPPTR depgen (var, coeff)
187: VARPTR var;
188: float coeff;
189: {
190: register DEPPTR newguy;
191: if (depavh) {
192: newguy = depavh;
193: depavh = depavh->next;
194: if (!depavh)
195: depavt = NULL;
196: newguy->next = NULL;
197: } else
198: tryalloc(newguy,DEPNODE);
199: newguy->var = var;
200: newguy->coeff = coeff;
201: return (newguy);
202: }
203:
204: LINEPTR linegen (x0, y0, x1, y1)
205: float x0,
206: y0,
207: x1,
208: y1;
209: {
210: register LINEPTR newguy;
211: tryalloc(newguy,LINENODE);
212: newguy->kind = LINE;
213: newguy->x0 = x0;
214: newguy->y0 = y0;
215: newguy->x1 = x1;
216: newguy->y1 = y1;
217: return (newguy);
218: }
219:
220: EDGEPTR edgeline (x0, y0, x1, y1)
221: float x0,
222: y0,
223: x1,
224: y1;
225: {
226: EDGEPTR newguy;
227: tryalloc(newguy,EDGENODE);
228: newguy->fax = (ARCPTR) NULL;
229: newguy->sx = x0;
230: newguy->sy = y0;
231: newguy->ex = x1;
232: newguy->ey = y1;
233: newguy->stx = newguy->ex;
234: newguy->sty = newguy->ey;
235: newguy->etx = newguy->sx;
236: newguy->ety = newguy->sy;
237: dprintf "opaque polygon edge: %f,%f -- %f,%f\n",
238: x0,y0, x1,y1
239: );
240: return (newguy);
241: }
242:
243: LINEPTR circgen (x0, y0, r)
244: float x0,
245: y0,
246: r;
247: {
248: register CIRCPTR newguy;
249: tryalloc(newguy,CIRCNODE);
250: newguy->kind = CIRCLE;
251: newguy->x0 = x0;
252: newguy->y0 = y0;
253: newguy->r = r;
254: return ((LINEPTR) newguy);
255: }
256:
257: /*
258: LINEPTR arcgen (x0, y0, x1, y1, x2, y2, theta1, theta2, radius)
259: float x0,
260: y0,
261: x1,
262: y1,
263: x2,
264: y2,
265: theta1,
266: theta2,
267: radius;
268: {
269: register ARCPTR newguy;
270: tryalloc(newguy,ARCNODE);
271: newguy->kind = ARC;
272: newguy->x0 = x0;
273: newguy->y0 = y0;
274: newguy->x1 = x1;
275: newguy->y1 = y1;
276: newguy->x2 = x2;
277: newguy->y2 = y2;
278: newguy->theta1 = theta1;
279: newguy->theta2 = theta2;
280: newguy->radius = radius;
281: return ((LINEPTR) newguy);
282: }
283: */
284:
285: LINEPTR angularc (x0, y0, radius, theta1, theta2)
286: float x0,
287: y0,
288: theta1,
289: theta2,
290: radius;
291: {
292: /* theta1 and theta2 should be in radians */
293: register ARCPTR newguy;
294: tryalloc(newguy,ARCNODE);
295: radius = fabs(radius);
296: newguy->kind = ARC;
297: newguy->x0 = x0;
298: newguy->y0 = y0;
299: newguy->x1 = x0 + cos (theta1)*radius;
300: newguy->y1 = y0 + sin (theta1)*radius;
301: newguy->x2 = x0 + cos (theta2)*radius;
302: newguy->y2 = y0 + sin (theta2)*radius;
303: theta1 = rprin (theta1);
304: theta2 = rprin (theta2);
305: while (theta2 - theta1 < EPSILON)
306: theta2 += 2*PI;
307: if (fabs(theta2 - theta1) > PI)
308: radius *= -1;
309: newguy->theta1 = theta1;
310: newguy->theta2 = theta2;
311: newguy->radius = radius;
312: return ((LINEPTR) newguy);
313: }
314:
315: LINEPTR pointarc (x1,y1, x2,y2, x3,y3)
316: float x1,y1, x2,y2, x3,y3;
317: {
318: float A, B, C, D, E, F;
319: float denom, x, y;
320: float startang, midang, endang;
321: A = -2.0*(x2 - x1);
322: B = -2.0*(y2 - y1);
323: C = -2.0*(x3 - x2);
324: D = -2.0*(y3 - y2);
325: denom = A*D - B*C;
326: if (fabs(denom) < EPSILON) {
327: dprintf "pointarc: (%f,%f) (%f,%f) (%f,%f) collinear\n",
328: x1,y1, x2,y2, x3,y3);
329: return (linegen (x1,y1, x3,y3));
330: }
331: E = x1*x1 + y1*y1 - x2*x2 - y2*y2;
332: F = x2*x2 + y2*y2 - x3*x3 - y3*y3;
333: x = E*D - F*B;
334: x /= denom;
335: y = A*F - C*E;
336: y /= denom;
337: startang = rprin(atan2 (y1-y, x1-x));
338: midang = rprin(atan2 (y2-y, x2-x));
339: endang = rprin(atan2 (y3-y, x3-x));
340: angorder (&startang, midang, &endang);
341: dprintf "pointarc: (%f,%f) (%f,%f) (%f,%f)\n", x1,y1, x2,y2, x3,y3);
342: dprintf "pointarc: (%f,%f) %f\n", x, y, hypot(x1-x,y1-y));
343: dprintf "pointarc: /_%f -- /_%f\n", startang, endang);
344: return (angularc (x, y, hypot(x1-x,y1-y), startang, endang));
345: }
346:
347: EDGEPTR edgearc (x1,y1, x2,y2, x3,y3)
348: float x1,y1, x2,y2, x3,y3;
349: {
350: EDGEPTR newguy;
351: tryalloc(newguy,EDGENODE);
352: newguy->fax = (ARCPTR) pointarc (x1,y1, x2,y2, x3,y3);
353: if (newguy->fax->kind == LINE) {
354: newguy->sx = newguy->etx = x1;
355: newguy->sy = newguy->ety = y1;
356: newguy->ex = newguy->stx = x3;
357: newguy->ey = newguy->sty = y3;
358: tryfree(newguy->fax);
359: newguy->fax = NULL;
360: newguy->flipped = FALSE;
361: } else if (newguy->fax->kind == ARC) {
362: ARCPTR temp;
363: temp = newguy->fax;
364: newguy->sx = x1;
365: newguy->sy = y1;
366: newguy->ex = x3;
367: newguy->ey = y3;
368: if ((fabs(newguy->sx - temp->x1) > EPSILON)
369: || (fabs(newguy->sy - temp->y1) > EPSILON)) {
370: newguy->stx = x1 - temp->y0 + y1;
371: newguy->sty = y1 + temp->x0 - x1;
372: newguy->etx = x3 + temp->y0 - y3;
373: newguy->ety = y3 - temp->x0 + x3;
374: newguy->flipped = TRUE;
375: } else {
376: newguy->stx = x1 + temp->y0 - y1;
377: newguy->sty = y1 - temp->x0 + x1;
378: newguy->etx = x3 - temp->y0 + y3;
379: newguy->ety = y3 + temp->x0 - x3;
380: newguy->flipped = FALSE;
381: }
382: dprintf "edgearc: (%f,%f) --> (%f,%f)\n",
383: newguy->sx, newguy->sy,
384: newguy->ex, newguy->ey
385: );
386: dprintf "edgearc: st (%f,%f); et (%f,%f)\n",
387: newguy->stx, newguy->sty,
388: newguy->etx, newguy->ety
389: );
390: dprintf "edgearc: %sflipped\n", newguy->flipped?"":"UN");
391: } else impossible ("edgearc");
392: return (newguy);
393: }
394:
395: LINEPTR textgen (command, string, x0, y0)
396: int command;
397: char *string;
398: float x0,
399: y0;
400: {
401: register TEXTPTR newguy;
402: tryalloc(newguy,TEXTNODE);
403: newguy->kind = STRING;
404: newguy->command = command;
405: newguy->string = string;
406: newguy->x0 = x0;
407: newguy->y0 = y0;
408: return ((LINEPTR) newguy);
409: }
410:
411: LINEPTR splgen (knotlist)
412: EXPRPTR knotlist;
413: {
414: register SPLPTR newguy;
415: tryalloc(newguy,SPLNODE);
416: newguy->kind = SPLINE;
417: newguy->knotlist = knotlist;
418: return ((LINEPTR) newguy);
419: }
420:
421: STRPTR strgen (command, string, at)
422: int command;
423: char *string;
424: EXPR at;
425: {
426: register STRPTR newguy;
427: tryalloc(newguy,STRNODE);
428: newguy->command = command;
429: newguy->string = string;
430: newguy->at = at;
431: return (newguy);
432: }
433:
434:
435: EQNPTR eqngen (eqn, noad)
436: EXPR eqn;
437: NOADPTR noad;
438: {
439: register EQNPTR newguy;
440: tryalloc(newguy,EQNNODE);
441: newguy->eqn = eqn;
442: newguy->noad = noad;
443: return (newguy);
444: }
445: OPQPTR opqgen (code, alpha)
446: int code;
447: float alpha;
448: {
449: OPQPTR newguy;
450: tryalloc(newguy,OPQNODE);
451: newguy->code = code;
452: newguy->alpha = alpha;
453: return (newguy);
454: }
455:
456: void depfree (doomed)
457: DEPPTR doomed;
458: {
459: register DEPPTR doomwalk;
460: if (!doomed || doomed == depavt)
461: return;
462: if (!depavh) {
463: depavt = depavh = doomed;
464: while (depavt->next)
465: depavt = depavt->next;
466: return;
467: }
468: doomwalk = doomed;
469: while (doomwalk->next) {
470: if (doomwalk->next == depavt)
471: return;
472: doomwalk = doomwalk->next;
473: }
474: depavt->next = doomed;
475: depavt = doomwalk;
476: }
477:
478: void nextfree (doomed)
479: DEPPTR doomed;
480: {
481: register DEPPTR walk;
482: while (doomed) {
483: walk = doomed->next;
484: tryfree(doomed);
485: doomed = walk;
486: }
487: }
488:
489: void namefree (doomed)
490: NAMEPTR doomed;
491: {
492: nextfree ((DEPPTR) doomed);
493: }
494:
495: void exprlsfree (doomed)
496: EXPRPTR doomed;
497: {
498: register EXPRPTR walk;
499: while (doomed) {
500: walk = doomed->next;
501: exprfree (doomed->expr);
502: tryfree(doomed);
503: doomed = walk;
504: }
505: }
506:
507: void linefree (doomed)
508: LINEPTR doomed;
509: {
510: nextfree ((DEPPTR) doomed);
511: }
512:
513: void intlfree (doomed)
514: INTLPTR doomed;
515: {
516: depfree ((DEPPTR) doomed->left);
517: depfree ((DEPPTR) doomed->right);
518: tryfree(doomed);
519: }
520:
521: void noadfree (doomed)
522: NOADPTR doomed;
523: {
524: if (!doomed)
525: return;
526: noadfree (doomed->son);
527: noadfree (doomed->brother);
528: varfree (doomed->edgevarlist);
529: varfree (doomed->boxvarlist);
530: linefree(doomed->linelist);
531: tryfree(doomed);
532: }
533:
534: void varfree (doomed)
535: VARPTR doomed;
536: {
537: if (!doomed)
538: return;
539: varfree (doomed->next);
540: depfree (doomed->deplist);
541: tryfree(doomed);
542: }
543:
544:
545: void exprfree (doomed)
546: EXPR doomed;
547: {
548: if (!doomed)
549: return;
550: if (!((INTLPTR) doomed)->used)
551: return;
552: if (!((EXTLPTR) doomed)->leaf) {
553: /* convention for functions (name in left, arg list hanging
554: /* off right) will ream you if not careful */
555: if (((INTLPTR) doomed)->oper == NAME) {
556: exprfree (((EXPRPTR)((INTLPTR) doomed)->right)->expr);
557: /*
558: if (((INTLPTR) ((INTLPTR) doomed)->right)->used) {
559: ((INTLPTR) ((INTLPTR) doomed)->right)->used = FALSE;
560: tryfree(((INTLPTR) doomed)->right);
561: }
562: */
563: } else if (((INTLPTR) doomed)->oper == ';') {
564: depfree ((DEPPTR)((INTLPTR) doomed)->left);
565: depfree ((DEPPTR)((INTLPTR) doomed)->right);
566: } else {
567: exprfree (((INTLPTR) doomed)->left);
568: exprfree (((INTLPTR) doomed)->right);
569: }
570: }
571: ((INTLPTR) doomed)->used = FALSE;
572: tryfree((INTLPTR) doomed);
573: }
574:
575:
576:
577: void boxfree (doomed)
578: BOXPTR doomed;
579: {
580: register STMTPTR curstmt, nextstmt;
581: for (curstmt = doomed->stmtlist;
582: curstmt;
583: curstmt = nextstmt) {
584: switch (curstmt->kind) {
585: case '=':
586: exprfree ((EXPR) curstmt->stmt);
587: break;
588: case CONN:
589: exprlsfree ((EXPRPTR) curstmt->stmt);
590: break;
591: case USING:
592: exprfree (((PENPTR) curstmt->stmt)->from);
593: exprfree (((PENPTR) curstmt->stmt)->to);
594: exprfree (((PENPTR) curstmt->stmt)->copies);
595: exprfree (((PENPTR) curstmt->stmt)->start);
596: exprfree (((PENPTR) curstmt->stmt)->end);
597: boxfree (((PENPTR) curstmt->stmt)->pen);
598: tryfree(curstmt->stmt);
599: break;
600: case PUT:
601: boxfree (((PUTPTR) curstmt->stmt)->parm);
602: tryfree(curstmt->stmt);
603: break;
604: case DRAW:
605: tryfree(curstmt->stmt);
606: break;
607: case STRING:
608: /* if using malloc to get string space, can use the real free here */
609: free(((STRPTR) curstmt->stmt)->string);
610: exprfree (((STRPTR) curstmt->stmt)->at);
611: tryfree(curstmt->stmt);
612: break;
613: case SPLINE:
614: exprlsfree ((EXPRPTR) curstmt->stmt);
615: break;
616: case OPAQUE:
617: tryfree(curstmt->stmt);
618: break;
619: case BDLIST:
620: exprlsfree ((EXPRPTR) curstmt->stmt);
621: break;
622: case VAR:
623: namefree ((NAMEPTR) curstmt->stmt);
624: break;
625: }
626: nextstmt = curstmt->next;
627: tryfree(curstmt);
628: }
629: }
630:
631: void emergency ()
632: {
633: nextfree (depavh);
634: depavh = depavt = NULL;
635: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.