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