Annotation of researchv10no/cmd/pic/misc.c, revision 1.1.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.