|
|
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.