Annotation of researchv10no/cmd/pic/misc.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.