From: erg Date: Wed, 9 Jan 2008 20:50:35 +0000 (+0000) Subject: Commit versions of tools using the cgraph library. X-Git-Tag: LAST_LIBGRAPH~32^2~4892 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=12e966558de4ed55afc79d7a7620fa1af55699ab;p=graphviz Commit versions of tools using the cgraph library. The new code is wrapped in #ifdef USE_CGRAPH --- diff --git a/cmd/tools/convert.h b/cmd/tools/convert.h index cd389514f..55e40680a 100644 --- a/cmd/tools/convert.h +++ b/cmd/tools/convert.h @@ -25,7 +25,12 @@ extern "C" { #include "config.h" #endif +#ifdef USE_CGRAPH +#include +#include +#else #include +#endif #include #ifdef HAVE_STDLIB_H #include diff --git a/cmd/tools/dijkstra.c b/cmd/tools/dijkstra.c index 3e9db4500..e2e1853c7 100644 --- a/cmd/tools/dijkstra.c +++ b/cmd/tools/dijkstra.c @@ -21,7 +21,11 @@ #include #include #include +#ifdef USE_CGRAPH +#include +#else #include +#endif #include #ifdef HAVE_GETOPT_H #include @@ -155,7 +159,11 @@ static void post(Agraph_t * g) if (setall) sprintf(dflt, "%.3lf", HUGE); +#ifdef USE_CGRAPH + for (v = agfstnode(g); v; v = agnxtnode(g, v)) { +#else for (v = agfstnode(g); v; v = agnxtnode(v)) { +#endif dist = getdist(v); if (dist) { dist--; @@ -197,7 +205,11 @@ void dijkstra(Dict_t * Q, Agraph_t * G, Agnode_t * n) setdist(n, 1); dtinsert(Q, n); while ((u = extract_min(Q))) { +#ifdef USE_CGRAPH + for (e = agfstedge(G, u); e; e = agnxtedge(G, e, u)) { +#else for (e = agfstedge(u); e; e = agnxtedge(e, u)) { +#endif update(Q, e->node, u, getlength(e)); } } diff --git a/cmd/tools/gc.c b/cmd/tools/gc.c index 463e6bb40..5ddb3dd4a 100644 --- a/cmd/tools/gc.c +++ b/cmd/tools/gc.c @@ -29,6 +29,16 @@ #endif #include +#ifdef USE_CGRAPH +#include +#include +typedef struct { + Agrec_t h; + int dfs_mark; +} Agnodeinfo_t; + +#define ND_dfs_mark(n) (((Agnodeinfo_t*)(n->base.data))->dfs_mark) +#else typedef struct { int cl_cnt; } Agraphinfo_t; @@ -39,8 +49,12 @@ typedef struct { #define GD_cl_cnt(g) (g)->u.cl_cnt #define ND_dfs_mark(n) (n)->u.dfs_mark +#define agtail(e) ((e)->tail) +#define aghead(e) ((e)->head) +#define agnameof(g) ((g)->name) #include +#endif #include #ifdef HAVE_GETOPT_H @@ -97,7 +111,9 @@ static void init(int argc, char *argv[]) { unsigned int c; +#ifndef USE_CGRAPH aginit(); +#endif while ((c = getopt(argc, argv, ":necCaDUrsv?")) != -1) { switch (c) { @@ -160,15 +176,24 @@ static void cc_dfs(Agraph_t * g, Agnode_t * n) ND_dfs_mark(n) = 1; for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { - if (n == e->tail) - nxt = e->head; + if (n == agtail(e)) + nxt = aghead(e); else - nxt = e->tail; + nxt = agtail(e); if (ND_dfs_mark(nxt) == 0) cc_dfs(g, nxt); } } +#ifdef USE_CGRAPH +static void cntCluster (Agraph_t * g, Agobj_t* sg, void* arg) +{ + char* sgname = agnameof ((Agraph_t*)sg); + + if (strncmp(sgname, "cluster", 7) == 0) + *(int*)(arg) += 1; +} +#else static void cl_count(Agraph_t * g) { Agraph_t *mg; @@ -188,6 +213,7 @@ static void cl_count(Agraph_t * g) } GD_cl_cnt(g) = sum; } +#endif static int cc_decompose(Agraph_t * g) { @@ -235,7 +261,7 @@ wcp(int nnodes, int nedges, int ncc, int ncl, char *gname, char *fname) printf(" %s\n", gname); } -static void emit(Agraph_t * g, int root) +static void emit(Agraph_t * g, int root, int cl_count) { int n_edges = agnedges(g); int n_nodes = agnnodes(g); @@ -247,11 +273,15 @@ static void emit(Agraph_t * g, int root) n_cc = cc_decompose(g); if (flags & CL) +#ifdef USE_CGRAPH + n_cl = cl_count; +#else n_cl = GD_cl_cnt(g); +#endif if (root) file = fname; - wcp(n_nodes, n_edges, n_cc, n_cl, g->name, file); + wcp(n_nodes, n_edges, n_cc, n_cl, agnameof(g), file); if (root) { n_graphs++; @@ -262,6 +292,37 @@ static void emit(Agraph_t * g, int root) } } +#ifdef USE_CGRAPH +#define GTYPE(g) (agisdirected(g)?DIRECTED:UNDIRECTED) + +static int eval(Agraph_t * g, int root) +{ + Agraph_t *subg; + int cl_count; + + if (root && !(GTYPE(g) & gtype)) + return 1; + + if (root) { + aginit(g, AGNODE, "nodeinfo", sizeof(Agnodeinfo_t), TRUE); + } + + if ((flags & CL) && root) { + cl_count = 0; + agapply (g, (Agobj_t *)g, cntCluster, &cl_count, 0); + } + + emit(g, root, cl_count); + + if (recurse) { + n_indent++; + for (subg = agfstsubg (g); subg; subg = agnxtsubg (subg)) + eval(subg, 0); + n_indent--; + } + return 0; +} +#else #define GTYPE(g) (AG_IS_DIRECTED(g)?DIRECTED:UNDIRECTED) static int eval(Agraph_t * g, int root) @@ -277,7 +338,7 @@ static int eval(Agraph_t * g, int root) if ((flags & CL) && root) cl_count(g); - emit(g, root); + emit(g, root, 0); if (recurse) { n_indent++; mg = g->meta_node->graph; @@ -290,6 +351,14 @@ static int eval(Agraph_t * g, int root) } return 0; } +#endif + +#ifdef USE_CGRAPH +static Agraph_t *gread(FILE * fp) +{ + return agread(fp, (Agdisc_t *) 0); +} +#endif int main(int argc, char *argv[]) { @@ -298,12 +367,16 @@ int main(int argc, char *argv[]) int rv = 0; init(argc, argv); +#ifdef USE_CGRAPH + newIngraph(&ig, Files, gread); +#else newIngraph(&ig, Files, agread); +#endif while ((g = nextGraph(&ig)) != 0) { fname = fileName(&ig); if (verbose) - fprintf(stderr, "Process graph %s in file %s\n", g->name, + fprintf(stderr, "Process graph %s in file %s\n", agnameof(g), fname); rv |= eval(g, 1); agclose(g); diff --git a/cmd/tools/gvcolor.c b/cmd/tools/gvcolor.c index 6afc19d40..c1e45f047 100644 --- a/cmd/tools/gvcolor.c +++ b/cmd/tools/gvcolor.c @@ -27,6 +27,19 @@ /* if NC changes, a bunch of scanf calls below are in trouble */ #define NC 3 /* size of HSB color vector */ +#ifdef USE_CGRAPH +#include +#include +typedef struct Agnodeinfo_t { + Agrec_t h; + double relrank; /* coordinate of its rank, smaller means lower rank */ + double x[NC]; /* color vector */ +} Agnodeinfo_t; + +#define ND_relrank(n) (((Agnodeinfo_t*)((n)->base.data))->relrank) +#define ND_x(n) (((Agnodeinfo_t*)((n)->base.data))->x) + +#else typedef struct Agnodeinfo_t { double relrank; /* coordinate of its rank, smaller means lower rank */ double x[NC]; /* color vector */ @@ -41,8 +54,11 @@ typedef struct Agraphinfo_t { #define ND_relrank(n) (n)->u.relrank #define ND_x(n) (n)->u.x +#define aghead(e) ((e)->head) +#define agtail(e) ((e)->tail) #include +#endif #include #include #ifdef HAVE_UNISTD_H @@ -68,7 +84,7 @@ extern char *colorxlate(char *str, char *buf); static int cmpf(Agnode_t ** n0, Agnode_t ** n1) { double t; - t = ((*n0)->u.relrank - (*n1)->u.relrank); + t = ND_relrank(*n0) - ND_relrank(*n1); if (t < 0.0) return -1; if (t > 0.0) @@ -128,13 +144,23 @@ static void color(Agraph_t * g) double x, y, maxrank = 0.0; double sum[NC], d, lowsat, highsat; +#ifdef USE_CGRAPH + if (agattr(g, AGNODE, "pos", 0) == NULL) { +#else if (agfindattr(g->proto->n, "pos") == NULL) { +#endif fprintf(stderr, "graph must be run through 'dot' before 'gvcolor'\n"); exit(1); } +#ifdef USE_CGRAPH + aginit(g, AGNODE, "nodeinfo", sizeof(Agnodeinfo_t), TRUE); + if (agattr(g, AGNODE, "style", 0) == NULL) + agattr(g, AGNODE, "style", "filled"); +#else if (agfindattr(g->proto->n, "style") == NULL) agnodeattr(g, "style", "filled"); +#endif if ((p = agget(g, "Defcolor"))) setcolor(p, Defcolor); @@ -188,9 +214,9 @@ static void color(Agraph_t * g) sum[j] = 0.0; cnt = 0; for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { - v = e->head; + v = aghead(e); if (v == n) - v = e->tail; + v = agtail(e); d = ND_relrank(v) - ND_relrank(n) - 0.01; if (d < 0) { double t = 0.0; @@ -239,14 +265,25 @@ static void color(Agraph_t * g) } } +#ifdef USE_CGRAPH +static Agraph_t *gread(FILE * fp) +{ + return agread(fp, (Agdisc_t *) 0); +} +#endif + int main(int argc, char **argv) { Agraph_t *g; ingraph_state ig; init(argc, argv); +#ifdef USE_CGRAPH + newIngraph(&ig, Files, gread); +#else newIngraph(&ig, Files, agread); aginit(); +#endif while ((g = nextGraph(&ig)) != 0) { color(g); diff --git a/cmd/tools/nop.c b/cmd/tools/nop.c index 2593e40ad..0995f9866 100644 --- a/cmd/tools/nop.c +++ b/cmd/tools/nop.c @@ -18,10 +18,14 @@ #include "config.h" #endif +#ifdef USE_CGRAPH +#include +#else typedef char Agnodeinfo_t; typedef char Agedgeinfo_t; typedef char Agraphinfo_t; #include +#endif #include #include #include @@ -76,7 +80,11 @@ static void init(int argc, char *argv[]) static Agraph_t *gread(FILE * fp) { +#ifdef USE_CGRAPH + return agread(fp, (Agdisc_t *) 0); +#else return agread(fp); +#endif } int main(int argc, char **argv) @@ -85,7 +93,9 @@ int main(int argc, char **argv) ingraph_state ig; init(argc, argv); +#ifndef USE_CGRAPH aginit (); +#endif newIngraph(&ig, Files, gread); while ((g = nextGraph(&ig)) != 0) { diff --git a/cmd/tools/sccmap.c b/cmd/tools/sccmap.c index ca56f9af2..a5a1b9a3d 100644 --- a/cmd/tools/sccmap.c +++ b/cmd/tools/sccmap.c @@ -34,7 +34,11 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef USE_CGRAPH +#include +#else #include +#endif #include #ifdef HAVE_GETOPT_H @@ -144,6 +148,29 @@ int Verbose; char *CmdName; char **Files; +#ifdef USE_CGRAPH +static void nodeInduce(Agraph_t * g, Agraph_t* map) +{ + Agnode_t *n; + Agedge_t *e; + Agraph_t* rootg = agroot (g); + + + for (n = agfstnode(g); n; n = agnxtnode(g, n)) { + for (e = agfstout(rootg, n); e; e = agnxtout(rootg, e)) { + if (agsubnode(g, aghead(e), FALSE)) + agsubedge(g, e, TRUE); + else { + Agraph_t* tscc = getscc(agtail(e)); + Agraph_t* hscc = getscc(aghead(e)); + if (tscc && hscc) + agedge(map, getrep(tscc), + getrep(hscc), NIL(char *), TRUE); + } + } + } +} +#else static void nodeInduce(Agraph_t * g) { Agnode_t *n, *rootn; @@ -162,6 +189,7 @@ static void nodeInduce(Agraph_t * g) } } } +#endif static int visit(Agnode_t * n, Agraph_t * map, Stack * sp, sccstate * st) { @@ -174,7 +202,11 @@ static int visit(Agnode_t * n, Agraph_t * map, Stack * sp, sccstate * st) setval(n, min); push(sp, n); +#ifdef USE_CGRAPH + for (e = agfstout(n->root, n); e; e = agnxtout(n->root, e)) { +#else for (e = agfstout(n); e; e = agnxtout(e)) { +#endif t = aghead(e); if (getval(t) == 0) m = visit(t, map, sp, st); @@ -202,7 +234,11 @@ static int visit(Agnode_t * n, Agraph_t * map, Stack * sp, sccstate * st) setscc(t, subg); st->N_nodes_in_nontriv_SCC++; } while (t != n); +#ifdef USE_CGRAPH + nodeInduce(subg, map); +#else nodeInduce(subg); +#endif if (!Silent) agwrite(subg, stdout); } @@ -216,7 +252,11 @@ static int label(Agnode_t * n, int nodecnt, int *edgecnt) setval(n, 1); nodecnt++; +#ifdef USE_CGRAPH + for (e = agfstedge(n->root, n); e; e = agnxtedge(n->root, e, n)) { +#else for (e = agfstedge(n); e; e = agnxtedge(e, n)) { +#endif (*edgecnt) += 1; if (e->node == n) e = agopp(e); @@ -237,7 +277,11 @@ countComponents(Agraph_t * g, int *max_degree, float *nontree_frac) int n_nodes; Agnode_t *n; +#ifdef USE_CGRAPH + for (n = agfstnode(g); n; n = agnxtnode(g, n)) { +#else for (n = agfstnode(g); n; n = agnxtnode(n)) { +#endif if (!getval(n)) { nc++; n_edges = 0; @@ -248,8 +292,13 @@ countComponents(Agraph_t * g, int *max_degree, float *nontree_frac) } if (max_degree) { int maxd = 0; +#ifdef USE_CGRAPH + for (n = agfstnode(g); n; n = agnxtnode(g, n)) { + deg = agdegree(g, n, TRUE, TRUE); +#else for (n = agfstnode(g); n; n = agnxtnode(n)) { deg = agdegree(n, TRUE, TRUE); +#endif if (maxd < deg) maxd = deg; setval(n, 0); @@ -285,7 +334,11 @@ static void process(Agraph_t * G) initStack(&stack, agnnodes(G) + 1); map = agopen("scc_map", Agdirected, (Agdisc_t *) 0); +#ifdef USE_CGRAPH + for (n = agfstnode(G); n; n = agnxtnode(G, n)) +#else for (n = agfstnode(G); n; n = agnxtnode(n)) +#endif if (getval(n) == 0) visit(n, map, &stack, &state); freeStack(&stack); diff --git a/cmd/tools/tred.c b/cmd/tools/tred.c index d97e9c834..62bf034a3 100644 --- a/cmd/tools/tred.c +++ b/cmd/tools/tred.c @@ -29,6 +29,17 @@ #include "config.h" #endif +#ifdef USE_CGRAPH +#include +#include + +typedef struct { + Agrec_t h; + int mark; +} Agnodeinfo_t; + +#define agrootof(n) ((n)->root) +#else typedef struct { int mark; } Agnodeinfo_t; @@ -36,6 +47,11 @@ typedef char Agedgeinfo_t; typedef char Agraphinfo_t; #include +#define agnameof(n) ((n)->name) +#define aghead(e) ((e)->head) +#define agtail(e) ((e)->tail) +#define agrootof(n) ((n)->graph) +#endif #ifdef HAVE_UNISTD_H #include #endif @@ -49,14 +65,17 @@ typedef char Agraphinfo_t; char **Files; char *CmdName; - +#ifdef USE_CGRAPH +#define MARK(n) (((Agnodeinfo_t*)(n->base.data))->mark) +#else #define MARK(n) ((n)->u.mark) +#endif static int dfs(Agnode_t * n, Agedge_t * link, int warn) { Agedge_t *e; Agedge_t *f; - Agraph_t *g = n->graph; + Agraph_t *g = agrootof(n); MARK(n) = 1; @@ -64,22 +83,26 @@ static int dfs(Agnode_t * n, Agedge_t * link, int warn) f = agnxtin(g, e); if (e == link) continue; - if (MARK(e->tail)) + if (MARK(agtail(e))) agdelete(g, e); } for (e = agfstout(g, n); e; e = agnxtout(g, e)) { - if (MARK(e->head)) { + if (MARK(aghead(e))) { if (!warn) { warn++; fprintf(stderr, "warning: %s has cycle(s), transitive reduction not unique\n", +#ifdef USE_CGRAPH + agnameof(g)); +#else g->name); +#endif fprintf(stderr, "cycle involves edge %s -> %s", - e->tail->name, e->head->name); + agnameof(agtail(e)), agnameof(aghead(e))); } } else - warn = dfs(e->head, e, warn); + warn = dfs(aghead(e), e, warn); } MARK(n) = 0; @@ -100,7 +123,9 @@ static void init(int argc, char *argv[]) { int c; +#ifndef USE_CGRAPH aginit(); +#endif CmdName = argv[0]; while ((c = getopt(argc, argv, ":?")) != -1) { switch (c) { @@ -125,6 +150,9 @@ static void process(Agraph_t * g) Agnode_t *n; int warn = 0; +#ifdef USE_CGRAPH + aginit(g, AGNODE, "info", sizeof(Agnodeinfo_t), TRUE); +#endif for (n = agfstnode(g); n; n = agnxtnode(g, n)) { warn = dfs(n, 0, warn); } @@ -132,19 +160,35 @@ static void process(Agraph_t * g) fflush(stdout); } +#ifdef USE_CGRAPH +static Agraph_t *gread(FILE * fp) +{ + return agread(fp, (Agdisc_t *) 0); +} +#endif + int main(int argc, char **argv) { Agraph_t *g; ingraph_state ig; init(argc, argv); +#ifdef USE_CGRAPH + newIngraph(&ig, Files, gread); +#else newIngraph(&ig, Files, agread); +#endif while ((g = nextGraph(&ig)) != 0) { +#ifdef USE_CGRAPH + if (agisdirected(g)) +#else if (AG_IS_DIRECTED(g)) +#endif process(g); agclose(g); } return 0; } + diff --git a/cmd/tools/unflatten.c b/cmd/tools/unflatten.c index d0c34369c..2fcf160fa 100644 --- a/cmd/tools/unflatten.c +++ b/cmd/tools/unflatten.c @@ -29,7 +29,13 @@ #ifdef HAVE_UNISTD_H #include #endif +#ifdef USE_CGRAPH +#include +#define degreeOf(n,I,O) (agdegree(n->root, n, I, O)) +#else #include +#define degreeOf(n,I,O) (agdegree(n, I, O)) +#endif #include #ifdef HAVE_GETOPT_H @@ -48,13 +54,13 @@ static char *cmd; static int isleaf(Agnode_t * n) { - return (agdegree(n, TRUE, TRUE) == 1); + return (degreeOf(n, TRUE, TRUE) == 1); } static int ischainnode(Agnode_t * n) { - return ((agdegree(n, TRUE, FALSE) == 1) - && agdegree(n, FALSE, TRUE) == 1); + return ((degreeOf(n, TRUE, FALSE) == 1) + && degreeOf(n, FALSE, TRUE) == 1); } static void adjustlen(Agedge_t * e, Agsym_t * sym, int newlen) @@ -81,13 +87,21 @@ static void transform(Agraph_t * g) m_ix = bindedgeattr(g, "minlen"); s_ix = bindedgeattr(g, "style"); +#ifdef USE_CGRAPH + for (n = agfstnode(g); n; n = agnxtnode(g, n)) { +#else for (n = agfstnode(g); n; n = agnxtnode(n)) { - d = agdegree(n, TRUE, TRUE); +#endif + d = degreeOf(n, TRUE, TRUE); if (d == 0) { if (ChainLimit < 1) continue; if (ChainNode) { +#ifdef USE_CGRAPH + e = agedge(g, ChainNode, n, "", TRUE); +#else e = agedge(ChainNode, n, "", TRUE); +#endif agxset(e, s_ix, "invis"); ChainSize++; if (ChainSize < ChainLimit) @@ -102,7 +116,11 @@ static void transform(Agraph_t * g) if (MaxMinlen < 1) continue; cnt = 0; +#ifdef USE_CGRAPH + for (e = agfstin(g, n); e; e = agnxtin(g, e)) { +#else for (e = agfstin(n); e; e = agnxtin(e)) { +#endif if (isleaf(agtail(e))) { str = agxget(e, m_ix); if (str[0] == 0) { @@ -113,7 +131,11 @@ static void transform(Agraph_t * g) } cnt = 0; +#ifdef USE_CGRAPH + for (e = agfstout(g, n); e; e = agnxtout(g, e)) { +#else for (e = agfstout(n); e; e = agnxtout(e)) { +#endif if (isleaf(e->node) || (Do_fans && ischainnode(e->node))) { str = agxget(e, m_ix); if (str[0] == 0)