Annotation of researchv10no/cmd/dag/util.c, revision 1.1

1.1     ! root        1: #include "draw_dag.h"
        !             2: #include "dag.h"
        !             3: #include "paths.h"
        !             4: #include "parsedag.h"
        !             5: #include "defaults.h"
        !             6: #include "unistd.h"
        !             7: 
        !             8: /*** utility functions ***/
        !             9: 
        !            10: char* Infile::gets(char *buf,int n) {
        !            11:        if (!fp) return 0;
        !            12:        line_number++;
        !            13:        return fgets(buf,n,fp);
        !            14: }
        !            15: 
        !            16: Infile nextfile(char** &argv)
        !            17: {
        !            18:        argv++;
        !            19:        while (**argv == '-') argv++;
        !            20:        Infile rv = Infile(*argv);
        !            21:        if (!rv.fp) fprintf(stderr,"%s: can't open %s\n",Cmd_name,*argv);
        !            22:        return rv;
        !            23: }
        !            24: 
        !            25: /*** shared strings ***/
        !            26: 
        !            27: shared_string_t *shared_string_pool;
        !            28: char *newstring(char *init) {
        !            29:        shared_string_t *it
        !            30:                = (shared_string_t*) malloc(sizeof(shared_string_t) + strlen(init));
        !            31:        it->next = shared_string_pool;
        !            32:        shared_string_pool = it;
        !            33:        strcpy(it->data,init);
        !            34:        return it->data;
        !            35: }
        !            36: 
        !            37: void freestrings() {
        !            38:        shared_string_t *q,*p = shared_string_pool;
        !            39:        while (p) {
        !            40:                q = p->next;
        !            41:                free((char*)p);
        !            42:                p = q;
        !            43:        }
        !            44:        shared_string_pool = 0;
        !            45: }
        !            46: 
        !            47: /*** hash table ***/
        !            48: 
        !            49: int hash(register char* s, int size) {
        !            50:        register unsigned int   h;
        !            51:        register int    c;
        !            52: 
        !            53:        h = 0;
        !            54:        while (c = *s++) {
        !            55:                if ((h <<= 1) < 0) h ^= c ^ ((~(((unsigned int)~0) >> 1)) | 1);
        !            56:                else h ^= c;
        !            57:        }
        !            58:        return(h % size);
        !            59: }
        !            60: 
        !            61: const int Hash_extent = 517;
        !            62: struct hashrec {
        !            63:        int                     node;
        !            64:        hashrec         *next;
        !            65: 
        !            66:        hashrec(int argnode, hashrec *argnext) {
        !            67:                node  = argnode;
        !            68:                next  = argnext;
        !            69:        };
        !            70: } *Hashtab[Hash_extent];
        !            71: 
        !            72: boolean expand_graph(int new_size) {
        !            73:                if (! (Node = (DAG_node_t**)realloc((char*)Node,sizeof(DAG_node_t*)*new_size)))
        !            74:                        return false;
        !            75:                else
        !            76:                        if (! (Edge = (DAG_edge_t**)realloc((char*)Edge,sizeof(DAG_edge_t*)*new_size)))
        !            77:                                return false;
        !            78:                return true;
        !            79: }
        !            80: 
        !            81: /* look name and insert in symbol table if not found. return new node's number. */
        !            82: int node_lookup(char *name) {
        !            83:        int h = hash(name,Hash_extent);
        !            84:        for (hashrec *hp = Hashtab[h]; hp; hp = hp->next)
        !            85:                if (!strcmp(name,Node[hp->node]->name)) break;
        !            86:        if (!hp) {
        !            87:                Hashtab[h] = hp =  new hashrec(N,Hashtab[h]);
        !            88: 
        !            89:                if (N > Extent - 1) {
        !            90:                        Extent += Extent;
        !            91:                        if (!expand_graph(Extent)) {
        !            92:                                yyerror("too many nodes, out of memory");
        !            93:                                exit(1);
        !            94:                        }
        !            95:                }
        !            96:                Node[N] = new DAG_node_t();
        !            97:                *Node[N] = Default_node;
        !            98:                Node[N]->setname(name);
        !            99:                Edge[N] = (DAG_edge_t*)0;
        !           100:                N++;
        !           101:        }
        !           102:        return hp->node;
        !           103: }
        !           104: 
        !           105: /*** utility functions for code gen */
        !           106: 
        !           107: void cat_libfile(char* name) {
        !           108:        char buf[BUFSIZ];
        !           109:        if (!Uselib) return;
        !           110:        if (!Lib_path) {
        !           111: #ifdef EXPTOOLS
        !           112:                char *tools = getenv("TOOLS");
        !           113:                if (tools) {
        !           114:                        Lib_path = new char[strlen(Lib_path)+strlen(EXPTOOLS_SUBDIR)+2];
        !           115:                        sprintf(Lib_path,"%s/%s",tools,EXPTOOLS_SUBDIR);
        !           116:                        sprintf(buf,"%s/%s",Lib_path,name);
        !           117:                        if (access(buf,R_OK))
        !           118:                                Lib_path = LIB_PATH;
        !           119:                }
        !           120:                else
        !           121: #endif EXPTOOLS
        !           122:                        Lib_path = LIB_PATH;
        !           123:        }
        !           124:        fflush(stdout);
        !           125:        sprintf(buf,"cat %s/%s",Lib_path,name);
        !           126:        system(buf);
        !           127: }
        !           128: 
        !           129: Point find_edge_midpoint(DAG_edge_t *e) {
        !           130:        int x,y;
        !           131:        for (int npts = 0; e->splinept[npts].y >= 0; npts++);
        !           132:        if (iabs(e->splinept[0].y - e->splinept[npts-1].y) >
        !           133:            iabs(e->splinept[0].x - e->splinept[npts-1].x)) { // "vertical" edge
        !           134:                int i,y1 = 0;
        !           135:                y1 = (e->splinept[0].y + e->splinept[npts-1].y)/2;
        !           136:                for (i = 0; e->splinept[i].y >= 0; i++)
        !           137:                        if (between(e->splinept[i].y,y1,e->splinept[i+1].y)) break;
        !           138:                y = y1;
        !           139:                x = (int) (e->splinept[i].x +
        !           140:                        (double)(y1 - e->splinept[i].y)/(e->splinept[i+1].y-e->splinept[i].y)
        !           141:                        * (e->splinept[i+1].x - e->splinept[i].x));
        !           142:        }
        !           143:        else {                                                                                          // "horizontal" edge
        !           144:                int i,x1 = 0;
        !           145:                x1 = (e->splinept[0].x + e->splinept[npts-1].x)/2;
        !           146:                for (i = 0; e->splinept[i].y >= 0; i++)
        !           147:                        if (between(e->splinept[i].x,x1,e->splinept[i+1].x)) break;
        !           148:                x = x1;
        !           149:                y = (int) (e->splinept[i].y +
        !           150:                        (double)(x1 - e->splinept[i].x)/(e->splinept[i+1].x-e->splinept[i].x)
        !           151:                        * (e->splinept[i+1].y - e->splinept[i].y));
        !           152:        }
        !           153:        Point rv;
        !           154:        rv .x = x; rv .y = y;
        !           155:        return rv;
        !           156: }
        !           157: 
        !           158: static boolean seginter(int x0,int y0, int x1, int y1, int x2, int y2, int x3, int y3,
        !           159: int& xinter, int& yinter) {
        !           160:        double m0,b0,m1,b1,x;
        !           161: 
        !           162:        if ((x0 == x1) && (x2 == x3)) return false;
        !           163:        if (x2 == x3) {swap(x0,x2); swap(x1,x3); swap(y0,y2); swap(y1,y3);}
        !           164:        if (x0 == x1) {
        !           165:                x = x0;
        !           166:        }       
        !           167:        else {
        !           168:                m0 = (y1 - y0)/(double)(x1 - x0);
        !           169:                b0 = y0 - m0*x0;
        !           170:                m1 = (y3 - y2)/(double)(x3 - x2);
        !           171:                b1 = y2 - m1*x2;
        !           172:                if (m1 == m0) {
        !           173:                        if (b0 != b1) return false;
        !           174:                        int l0lowx = min(x0,x1);
        !           175:                        int l0highx = max(x0,x1);
        !           176:                        int l1lowx = min(x2,x3);
        !           177:                        int l1highx = max(x2,x3);
        !           178:                        if (between(l0lowx,l1lowx,l0highx))
        !           179:                                x = l1lowx;
        !           180:                        else if (between(l0lowx,l1highx,l0highx))
        !           181:                                x = l1highx;
        !           182:                        else if (between(l1lowx,l0lowx,l1highx))
        !           183:                                x = l0lowx;
        !           184:                        else return false;
        !           185:                }
        !           186:                else x = (b1 - b0)/(m0 - m1);
        !           187:        }
        !           188: 
        !           189:        if (between(x2,round(x),x3)) {
        !           190:                if (between(y2,round(m1 * x + b1),y3)) {
        !           191:                        yinter = round(m1 * x + b1);
        !           192:                        xinter = round(x);
        !           193:                        return true;
        !           194:                }
        !           195:        }
        !           196:        return false;
        !           197: }
        !           198: 
        !           199: /*
        !           200:  *  return point of intersection of the node 
        !           201:  *  with the ray from (x0,y0) through (x1,y1).
        !           202:  *  p1 must be on the bounding box of the node.
        !           203:  *  assume User_defined nodes are like Box.
        !           204:  */
        !           205: Point find_nodeport(int node, Point p0, Point p1) {
        !           206:        Point rv;
        !           207:        if ((p0.x == p1.x) && (p0.y == p1.y)) {return p0;}
        !           208:        int x0 = p0.x; int y0 = p0.y; int x1 = p1.x; int y1 = p1.y;
        !           209: 
        !           210:        /* handle degenerate case of vertical line segment */
        !           211:        if (x0 == x1) return p1;
        !           212: 
        !           213:        while (1) {
        !           214:                /* normal case */
        !           215:                double m = (double)(y1 - y0) / (double)(x1 - x0); 
        !           216:                double b = y0 - m * x0;
        !           217:                switch(Node[node]->shape.shape_id) {
        !           218:                        case Circle:
        !           219:                        case Doublecircle:
        !           220:                        case Ellipse:
        !           221:                                double s0,s1;   // two solutions (x values)
        !           222:                                //double b1 = m*Node[node]->pos.x + b - Node[node]->pos.y;
        !           223:                                double b1 = (y0 - Node[node]->pos.y) - m * (x0 - Node[node]->pos.x);
        !           224:                                double rx = Node[node]->xsize/2.;
        !           225:                                double ry = Node[node]->ysize/2.;
        !           226:                                double aa = 1/(rx*rx) + (m*m)/(ry*ry);
        !           227:                                double bb = 2.*m*b1/(ry*ry);
        !           228:                                double cc = (b1*b1)/(ry*ry) - 1;
        !           229:                                if (m == 0.) {
        !           230:                                        s0 = rx;
        !           231:                                        s1 = -rx;
        !           232:                                }
        !           233:                                else {
        !           234:                                        double t = bb*bb - 4.*aa*cc;
        !           235:                                        if (t < 0) {
        !           236:                                                if (x1 == Node[node]->pos.x && y1 == Node[node]->pos.y) 
        !           237:                                                        panic("can't find node intersection");
        !           238:                                                x1 = Node[node]->pos.x;
        !           239:                                                y1 = Node[node]->pos.y;
        !           240:                                                continue;
        !           241:                                        }
        !           242:                                        s0 = (-bb + sqrt(t))/(2.*aa);
        !           243:                                        s1 = (-bb - sqrt(t))/(2.*aa);
        !           244:                                }
        !           245:                                s0 += Node[node]->pos.x;
        !           246:                                s1 += Node[node]->pos.x;
        !           247:                                if (distance(s0,m*s0+b,x0,y0) <= distance(s1,m*s1+b,x0,y0)) {
        !           248:                                        rv.x = round(s0);
        !           249:                                        rv.y = round(s0 * m + b);
        !           250:                                }
        !           251:                                else {
        !           252:                                        rv.x = round(s1);
        !           253:                                        rv.y = round(s1 * m + b);
        !           254:                                }
        !           255:                                return rv;
        !           256:                        case Diamond:
        !           257:                                x1 = Node[node]->pos.x;
        !           258:                                y1 = (int)(m*x1 + b);
        !           259:                                switch((sign(x0 - Node[node]->pos.x)== -1) + 2*(sign(y0 - Node[node]->pos.y)== -1)) {
        !           260:                                        case 0:
        !           261:                                                if (seginter(x0,y0,x1,y1,Node[node]->pos.x+Node[node]->xsize/2,Node[node]->pos.y,Node[node]->pos.x,Node[node]->pos.y+Node[node]->ysize/2,rv.x,rv.y)) return rv;
        !           262:                                                break;
        !           263:                                        case 1:
        !           264:                                                if (seginter(x0,y0,x1,y1,Node[node]->pos.x,Node[node]->pos.y+Node[node]->ysize/2,Node[node]->pos.x-Node[node]->xsize/2,Node[node]->pos.y,rv.x,rv.y)) return rv;
        !           265:                                                break;
        !           266:                                        case 2:
        !           267:                                                if (seginter(x0,y0,x1,y1,Node[node]->pos.x,Node[node]->pos.y-Node[node]->ysize/2,Node[node]->pos.x+Node[node]->xsize/2,Node[node]->pos.y,rv.x,rv.y)) return rv;
        !           268:                                                break;
        !           269:                                        case 3:
        !           270:                                                if (seginter(x0,y0,x1,y1,Node[node]->pos.x-Node[node]->xsize/2,Node[node]->pos.y,Node[node]->pos.x,Node[node]->pos.y-Node[node]->ysize/2,rv.x,rv.y)) return rv;
        !           271:                                                break;
        !           272:                                }
        !           273:                        case Box:
        !           274:                        case Square:
        !           275:                        case Plaintext:
        !           276:                        case User_defined:
        !           277:                        default:
        !           278:                                return p1;
        !           279:                }
        !           280:        }
        !           281: }
        !           282: 
        !           283: void reclaim_hashtable() {
        !           284:        for (int i = 0; i < Hash_extent; i++) {
        !           285:                hashrec *h,*h1;
        !           286:                if (Hashtab[i])
        !           287:                        for (h = Hashtab[i], h1 = h->next; h1; h1=h1->next){
        !           288:                                delete h; h = h1;
        !           289:                        }
        !           290:                Hashtab[i] = 0;
        !           291:        }
        !           292: }
        !           293: 
        !           294: void set_output_type(char *name) {
        !           295:        const int n_output_types = 4;
        !           296:        static struct {
        !           297:                char*                   name;
        !           298:                output_lang_t   lang;
        !           299:        } map[] = {     
        !           300:                "pic",          Pic,
        !           301:                "ps",           Postscript,
        !           302:                "simple",       Graphdraw,
        !           303:                "cip",          Cip
        !           304:        };
        !           305:        for (int i = 0; i < n_output_types; i++)
        !           306:                if (!strcmp(name,map[i].name)) {
        !           307:                        Output_type = map[i].lang;
        !           308:                        return;
        !           309:                }
        !           310:        fprintf(stderr,"%s: warning, no output driver for %s, option ignored.\n",
        !           311:                Cmd_name,name);
        !           312: }
        !           313: 
        !           314: void set_page_size(char *arg) {
        !           315:        double  w,h,mw,mh;      /* width, height, margin width, margin height */
        !           316:        int             nargs;
        !           317:        nargs = sscanf(arg,"%lfx%lf,%lfx%lf",&w,&h,&mw,&mh);
        !           318:        if (nargs > 1) {
        !           319:                Page_size.x = (int)(w*Resolution);
        !           320:                Page_size.y = (int)(h*Resolution);
        !           321:        }
        !           322:        if (nargs > 2) {
        !           323:                Margin.x = (int)(mw * Resolution);
        !           324:                if (nargs > 3) Margin.y = (int)(mh * Resolution);
        !           325:                else Margin.y = Margin.x;
        !           326:        }
        !           327:        Page_size.x -= 2*Margin.x;
        !           328:        Page_size.y -= 2*Margin.y;
        !           329:        if (Page_size.x <= 0 || Page_size.y <= 0) {
        !           330:                fprintf(stderr,"%s: warning, bad page or margin size options (ignored)\n",Cmd_name);
        !           331:                Page_size.x = 0; Page_size.y = 0;
        !           332:        }
        !           333: }
        !           334: 
        !           335: options_t reset_options() {
        !           336:        options_t rv;
        !           337: 
        !           338:        rv.quick                =       Default_options_quick;
        !           339:        rv.verbose              =       Default_options_verbose;
        !           340:        rv.rankadjust   =       Default_options_rankadjust;
        !           341:        rv.ranksep              =       Default_options_ranksep;
        !           342:        rv.nodesep              =       Default_options_nodesep;
        !           343:        rv.xbound               =       0;
        !           344:        rv.ybound               =       0;
        !           345: 
        !           346:        rv.n_same_nodes=        0;
        !           347:        rv.same_nodes   =       0;
        !           348:        rv.source_nodes=        0;
        !           349:        rv.sink_nodes   =       0;
        !           350:        return  rv;
        !           351: }
        !           352: 
        !           353: void set_bounds(double xdimen, double ydimen) {
        !           354:        if ((xdimen <= 0.0) || (ydimen <= 0.0)) return;
        !           355:        /* the following because the picture will be rotated down in draw_dag */
        !           356:        if (User.rotated) {double t = xdimen; xdimen = ydimen; ydimen = t;}
        !           357:        Options.xbound = round(xdimen * Resolution);
        !           358:        Options.ybound = round(ydimen * Resolution);
        !           359: }
        !           360: 
        !           361: shape_t::shape_t(int intype, char* invalue) {
        !           362:        const int n_predefined_shapes = 7;
        !           363:        static struct {
        !           364:                char *          n;
        !           365:                shape_id_t      s;
        !           366:        } map[] = {
        !           367:                "Circle", Circle,
        !           368:                "Doublecircle", Doublecircle,
        !           369:                "Box",  Box,
        !           370:                "Ellipse",      Ellipse,
        !           371:                "Square",       Square,
        !           372:                "Plaintext",    Plaintext,
        !           373:                "Diamond",      Diamond
        !           374:        };
        !           375:        type = intype;
        !           376:        value = invalue;
        !           377:        if (type == STRING) {
        !           378:                for (int i = 0; i < n_predefined_shapes; i++) {
        !           379:                        if (!strcmp(invalue,map[i].n)) {
        !           380:                                type    =       intype;
        !           381:                                predefined = true;
        !           382:                                shape_id = map[i].s;
        !           383:                                return;
        !           384:                        }
        !           385:                }
        !           386:        }
        !           387:        predefined = false;
        !           388:        shape_id = User_defined;
        !           389: }

unix.superglobalmegacorp.com

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