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