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