/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/pack/ptest.c

Go to the documentation of this file.
00001 /* $Id: ptest.c,v 1.2 2005/10/18 18:42:59 ellson Exp $ $Revision: 1.2 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 #include <render.h>
00018 #include <neatoprocs.h>
00019 #include <assert.h>
00020 #include <pack.h>
00021 
00022 /* Test driver for libpack library.
00023  * Input consists of graphs in dot format.
00024  * If -c is not specified, the graphs must have pos information,
00025  * typically the output of one of the layout programs using -Tdot.
00026  *  -c computes connected components of input graphs
00027  *   Otherwise, ptest packs the input graphs.
00028  *  -s causes all the input graphs to be combined
00029  *   into a single output graph, ready to be sent to neato -s -n2.
00030  *   Otherwise, each graph is output separately, but with the
00031  *   appropriately adjusted coordinates.
00032  *  -e causes the packing to not use edge splines, if any.
00033  *   If any input graph does not have spline info, -e goes into 
00034  *   effect automatically.
00035  *  -m <i> specifies the margin, in points, about each graph.
00036  */
00037 char *Info[] = {
00038     "ptest",                    /* Program */
00039     "1.0",                      /* Version */
00040     DATE                        /* Build Date */
00041 };
00042 
00043 static int margin = 8;
00044 static int doEdges = 1;
00045 static int doComps = 0;
00046 static int verbose = 0;
00047 static char **Files = 0;
00048 static int nFiles = 0;
00049 static int single = 0;
00050 
00051 static char *useString = "Usage: ptest [-cesv?] [-m <margine>] <files>\n\
00052   -c - components\n\
00053   -e - no edges\n\
00054   -m n - set margine\n\
00055   -v - verbose\n\
00056   -s - single graph\n\
00057   -? - print usage\n\
00058 If no files are specified, stdin is used\n";
00059 
00060 static void usage(int v)
00061 {
00062     printf(useString);
00063     exit(v);
00064 }
00065 
00066 static void init(int argc, char *argv[])
00067 {
00068     int c;
00069 
00070     aginit();
00071     while ((c = getopt(argc, argv, ":escvm:?")) != -1) {
00072         switch (c) {
00073         case 'e':
00074             doEdges = 0;
00075             break;
00076         case 'c':
00077             doComps = 1;
00078             break;
00079         case 'm':
00080             margin = atoi(optarg);
00081             break;
00082         case 's':
00083             single = 1;
00084             break;
00085         case 'v':
00086             verbose = 1;
00087             Verbose = 1;
00088             break;
00089         case '?':
00090             if (optopt == '?')
00091                 usage(0);
00092             else
00093                 fprintf(stderr,
00094                         "ptest: option -%c unrecognized - ignored\n", c);
00095             break;
00096         }
00097     }
00098     argv += optind;
00099     argc -= optind;
00100 
00101     if (argc) {
00102         Files = argv;
00103         nFiles = argc;
00104     }
00105 
00106 }
00107 
00108 static int numFields(char *pos)
00109 {
00110     int cnt = 0;
00111     char c;
00112 
00113     while (isspace(*pos))
00114         pos++;
00115     while (*pos) {
00116         cnt++;
00117         while ((c = *pos) && !isspace(c))
00118             pos++;              /* skip token */
00119         while (isspace(*pos))
00120             pos++;
00121     }
00122     return cnt;
00123 }
00124 
00125 static point *user_spline(attrsym_t * symptr, edge_t * e, int *np)
00126 {
00127     char *pos;
00128     int i, n, nc;
00129     point *ps = 0;
00130     point *pp;
00131     double x, y;
00132 
00133     if (symptr == NULL)
00134         return 0;
00135     pos = agxget(e, symptr->index);
00136     if (*pos == '\0')
00137         return 0;
00138     n = numFields(pos);
00139     *np = n;
00140     if (n > 1) {
00141         ps = ALLOC(n, 0, point);
00142         pp = ps;
00143         while (n) {
00144             i = sscanf(pos, "%lf,%lf%n", &x, &y, &nc);
00145             if (i < 2) {
00146                 free(ps);
00147                 ps = 0;
00148                 break;
00149             }
00150             pos = pos + nc;
00151             pp->x = (int) x;
00152             pp->y = (int) y;
00153             pp++;
00154             n--;
00155         }
00156     }
00157     return ps;
00158 }
00159 
00160 static void initPos(Agraph_t * g)
00161 {
00162     Agnode_t *n;
00163     Agedge_t *e;
00164     double *pvec;
00165     char *p;
00166     point *sp;
00167     int pn;
00168     attrsym_t *N_pos = agfindattr(g->proto->n, "pos");
00169     attrsym_t *E_pos = agfindattr(g->proto->e, "pos");
00170 
00171     assert(N_pos);
00172     if (!E_pos) {
00173         if (doEdges)
00174             fprintf(stderr, "Warning: turning off doEdges, graph %s\n",
00175                     g->name);
00176         doEdges = 0;
00177     }
00178     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00179         pvec = ND_pos(n);
00180         p = agxget(n, N_pos->index);
00181         if (p[0] && (sscanf(p, "%lf,%lf", pvec, pvec + 1) == 2)) {
00182             int i;
00183             for (i = 0; i < NDIM; i++)
00184                 pvec[i] = pvec[i] / PSinputscale;
00185         } else {
00186             fprintf(stderr, "could not find pos for node %s in graph %s\n",
00187                     n->name, g->name);
00188             exit(1);
00189         }
00190         ND_coord_i(n).x = POINTS(ND_pos(n)[0]);
00191         ND_coord_i(n).y = POINTS(ND_pos(n)[1]);
00192     }
00193 
00194     if (doEdges) {
00195         for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00196             for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00197                 if ((sp = user_spline(E_pos, e, &pn)) != 0) {
00198                     clip_and_install(e, sp, pn);
00199                     free(sp);
00200                 } else {
00201                     fprintf(stderr,
00202                             "Missing edge pos for edge %s - %s in graph %s\n",
00203                             n->name, e->head->name, g->name);
00204                     exit(1);
00205                 }
00206             }
00207         }
00208     }
00209 }
00210 
00211 static void ptest_nodesize(node_t * n, bool flip)
00212 {
00213     int w;
00214 
00215     w = ND_xsize(n) = POINTS(ND_width(n));
00216     ND_lw_i(n) = ND_rw_i(n) = w / 2;
00217     ND_ht_i(n) = ND_ysize(n) = POINTS(ND_height(n));
00218 }
00219 
00220 
00221 static void ptest_initNode(node_t * n)
00222 {
00223     char *str;
00224     ND_width(n) =
00225         late_double(n, N_width, DEFAULT_NODEWIDTH, MIN_NODEWIDTH);
00226     ND_height(n) =
00227         late_double(n, N_height, DEFAULT_NODEHEIGHT, MIN_NODEWIDTH);
00228     if (N_label == NULL)
00229         str = NODENAME_ESC;
00230     else
00231         str = agxget(n, N_label->index);
00232     str = strdup_and_subst(str, NODENAME_ESC, n->name);
00233     ND_label(n) = make_label(str,
00234                              late_double(n, N_fontsize, DEFAULT_FONTSIZE,
00235                                          MIN_FONTSIZE), late_nnstring(n,
00236                                                                       N_fontname,
00237                                                                       DEFAULT_FONTNAME),
00238                              late_nnstring(n, N_fontcolor, DEFAULT_COLOR),
00239                              n->graph);
00240     ND_shape(n) = bind_shape(late_nnstring(n, N_shape, DEFAULT_NODESHAPE));
00241     ND_shape(n)->initfn(n);     /* ### need to quantize ? */
00242     ptest_nodesize(n, n->GD_flip(graph));
00243 
00244 
00245 }
00246 
00247 static void ptest_initGraph(graph_t * g)
00248 {
00249     node_t *n;
00250     /* edge_t *e; */
00251 
00252     for (n = agfstnode(g); n; n = agnxtnode(g, n))
00253         ptest_initNode(n);
00254 /*
00255   for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
00256     for (e = agfstout(g,n); e; e = agnxtout(g,e)) ptest_initEdge(e);
00257   }
00258 */
00259 }
00260 
00261 static void dumpG(graph_t * g)
00262 {
00263     node_t *n;
00264     /* point  p; */
00265     edge_t *e;
00266 
00267     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00268         fprintf(stderr, " node %s \n", n->name);
00269 
00270         for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00271             fprintf(stderr, " %s - %s \n", e->tail->name, e->head->name);
00272         }
00273 #ifdef OLD
00274         p = coord(n);
00275         fprintf(stderr, " %s pos (%f,%f) (%d,%d)\n",
00276                 n->name, ND_pos(n)[0], ND_pos(n)[1], p.x, p.y);
00277         fprintf(stderr, "   width %f height %f xsize %d ysize %d\n",
00278                 ND_width(n), ND_height(n), ND_xsize(n), ND_ysize(n));
00279 #endif
00280     }
00281 }
00282 
00283 static void copyPos(Agraph_t * g)
00284 {
00285     Agnode_t *n;
00286     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00287         ND_coord_i(n).x = POINTS(ND_pos(n)[0]);
00288         ND_coord_i(n).y = POINTS(ND_pos(n)[1]);
00289     }
00290 }
00291 
00292 main(int argc, char *argv[])
00293 {
00294     Agraph_t **gs;
00295     Agraph_t **ccs;
00296     Agraph_t *g;
00297     Agraph_t *gp;
00298     char *fname;
00299     FILE *fp;
00300     int cnt;
00301     int i;
00302 
00303     init(argc, argv);
00304     if (!Files) {
00305         fprintf(stderr, "No input files given\n");
00306         exit(1);
00307     }
00308 
00309     PSinputscale = POINTS_PER_INCH;
00310     if (doComps) {
00311         if (verbose)
00312             fprintf(stderr, "do Comps\n");
00313         while (fname = *Files++) {
00314             fp = fopen(fname, "r");
00315             if (!fp) {
00316                 fprintf(stderr, "Could not open %s\n", fname);
00317                 continue;
00318             }
00319             g = agread(fp);
00320             fclose(fp);
00321             if (!g) {
00322                 fprintf(stderr, "Could not read graph\n");
00323                 continue;
00324             }
00325             printf("%s %d nodes %d edges %sconnected\n",
00326                    g->name, agnnodes(g), agnedges(g),
00327                    (isConnected(g) ? "" : "not "));
00328             gs = ccomps(g, &cnt, "abc");
00329             for (i = 0; i < cnt; i++) {
00330                 gp = gs[i];
00331                 printf(" %s %d nodes %d edges\n", gp->name, agnnodes(gp),
00332                        agnedges(gp));
00333             }
00334         }
00335     } else {
00336         gs = N_GNEW(nFiles, Agraph_t *);
00337         cnt = 0;
00338         while (fname = Files[cnt]) {
00339             fp = fopen(fname, "r");
00340             if (!fp) {
00341                 fprintf(stderr, "Could not open %s\n", fname);
00342                 exit(1);
00343             }
00344             g = agread(fp);
00345             fclose(fp);
00346             if (!g) {
00347                 fprintf(stderr, "Could not read graph\n");
00348                 exit(1);
00349             }
00350             if (!single) {
00351                 graph_init(g);
00352                 ptest_initGraph(g);
00353             }
00354             initPos(g);
00355             /* if (Verbose) dumpG (g); */
00356             gs[cnt++] = g;
00357         }
00358         if (single) {
00359             Agraph_t *root;
00360             Agnode_t *n;
00361             Agnode_t *np;
00362             Agnode_t *tp;
00363             Agnode_t *hp;
00364             Agedge_t *e;
00365             Agedge_t *ep;
00366             root = agopen("root", 0);
00367             agedgeattr(root, "pos", "");
00368             for (i = 0; i < cnt; i++) {
00369                 g = gs[i];
00370                 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00371                     if (agfindnode(root, n->name)) {
00372                         fprintf(stderr,
00373                                 "Error: node %s in graph %d (%s) previously added\n",
00374                                 n->name, i, Files[i]);
00375                         exit(1);
00376                     }
00377                     np = agnode(root, n->name);
00378                     ND_pos(np)[0] = ND_pos(n)[0];
00379                     ND_pos(np)[1] = ND_pos(n)[1];
00380                     ND_coord_i(np).x = ND_coord_i(n).x;
00381                     ND_coord_i(np).y = ND_coord_i(n).y;
00382                 }
00383                 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00384                     tp = agfindnode(root, n->name);
00385                     for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00386                         hp = agfindnode(root, e->head->name);
00387                         ep = agedge(root, tp, hp);
00388                         ED_spl(ep) = ED_spl(e);
00389                     }
00390                 }
00391             }
00392             graph_init(root);
00393             ptest_initGraph(root);
00394             ccs = ccomps(root, &cnt, 0);
00395             packGraphs(cnt, ccs, root, margin, doEdges);
00396             if (!doEdges)
00397                 copyPos(root);
00398             else
00399                 State = GVSPLINES;
00400             attach_attrs(root);
00401             for (i = 0; i < cnt; i++) {
00402                 agdelete(root, ccs[i]);
00403             }
00404             agwrite(root, stdout);
00405         } else {
00406             packGraphs(cnt, gs, 0, margin, doEdges);
00407             if (doEdges)
00408                 State = GVSPLINES;
00409             for (i = 0; i < cnt; i++) {
00410                 if (!doEdges)
00411                     copyPos(gs[i]);
00412                 attach_attrs(gs[i]);
00413                 agwrite(gs[i], stdout);
00414             }
00415         }
00416     }
00417 }

Generated on Mon Mar 31 19:03:28 2008 for Graphviz by  doxygen 1.5.1