From 0b53cb54824711e89d804d0318509751ae6704da Mon Sep 17 00:00:00 2001
From: Emden Gansner <erg@research.att.com>
Date: Thu, 29 Sep 2011 17:00:26 -0400
Subject: [PATCH] Add remainder of Glen Low's changes fo graphviz to use
 cgraph.

---
 lib/dotgen/dotinit.c    |  32 ++++++++-
 lib/dotgen/dotsplines.c | 147 +++++++++++++++++++++++++++++++++-------
 lib/dotgen/fastgr.c     |  13 +++-
 lib/dotgen/mincross.c   |   3 +
 lib/dotgen/position.c   |  31 +++++++--
 lib/dotgen/rank.c       |  19 ++++++
 lib/dotgen/sameport.c   |   2 +-
 lib/fdpgen/comp.c       |   4 +-
 lib/fdpgen/fdpinit.c    |   2 +-
 lib/fdpgen/layout.c     |  21 ++++--
 10 files changed, 232 insertions(+), 42 deletions(-)

diff --git a/lib/dotgen/dotinit.c b/lib/dotgen/dotinit.c
index 3c1b7e609..0c45ee41a 100644
--- a/lib/dotgen/dotinit.c
+++ b/lib/dotgen/dotinit.c
@@ -16,6 +16,21 @@
 #include "dot.h"
 #include "aspect.h"
 
+#ifdef WITH_CGRAPH
+static void
+dot_init_subg(graph_t * g)
+{
+    graph_t* subg;
+
+    if ((g != agroot(g)) && is_cluster(g))
+	agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
+    for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
+	dot_init_subg(subg);
+    }
+}
+#endif
+
+
 static void 
 dot_init_node(node_t * n)
 {
@@ -99,7 +114,7 @@ dot_cleanup_node(node_t * n)
 #ifndef WITH_CGRAPH
     memset(&(n->u), 0, sizeof(Agnodeinfo_t));
 #else /* WITH_CGRAPH */
-	agclean(agraphof(n), AGNODE,"Agnodeinfo_t");	
+    agdelrec(n, "Agnodeinfo_t");	
 #endif /* WITH_CGRAPH */
 }
 
@@ -111,11 +126,17 @@ static void free_virtual_edge_list(node_t * n)
     for (i = ND_in(n).size - 1; i >= 0; i--) {
 	e = ND_in(n).list[i];
 	delete_fast_edge(e);
+#ifdef WITH_CGRAPH
+	free(e->base.data);
+#endif
 	free(e);
     }
     for (i = ND_out(n).size - 1; i >= 0; i--) {
 	e = ND_out(n).list[i];
 	delete_fast_edge(e);
+#ifdef WITH_CGRAPH
+	free(e->base.data);
+#endif
 	free(e);
     }
 }
@@ -130,6 +151,9 @@ static void free_virtual_node_list(node_t * vn)
 	if (ND_node_type(vn) == VIRTUAL) {
 	    free_list(ND_out(vn));
 	    free_list(ND_in(vn));
+#ifdef WITH_CGRAPH
+	    free(vn->base.data);
+#endif
 	    free(vn);
 	}
 	vn = next_vn;
@@ -163,7 +187,7 @@ dot_cleanup_graph(graph_t * g)
 #ifndef WITH_CGRAPH
 	memset(&(g->u), 0, sizeof(Agraphinfo_t));
 #else /* WITH_CGRAPH */
-	agclean(g,AGRAPH,"Agraphinfo_t");
+	agdelrec(g,"Agraphinfo_t");
 #endif /* WITH_CGRAPH */
 }
 
@@ -257,6 +281,10 @@ void dot_layout(Agraph_t * g)
     setEdgeType (g, ET_SPLINE);
     asp = setAspect (g, &aspect);
 
+#ifdef WITH_CGRAPH
+    dot_init_subg(g);
+#endif
+
     dot_init_node_edge(g);
 
     do {
diff --git a/lib/dotgen/dotsplines.c b/lib/dotgen/dotsplines.c
index 73cd4430a..0b77b7747 100644
--- a/lib/dotgen/dotsplines.c
+++ b/lib/dotgen/dotsplines.c
@@ -50,8 +50,12 @@
 #else /* WITH_CGRAPH */
 #define MAKEFWDEDGE(new, old) { \
 	edge_t *newp; \
+	Agedgeinfo_t *info; \
 	newp = new; \
+	info = (Agedgeinfo_t*)newp->base.data; \
+	*info = *(Agedgeinfo_t*)old->base.data; \
 	*newp = *old; \
+	newp->base.data = (Agrec_t*)info; \
 	AGTAIL(newp) = AGHEAD(old); \
 	AGHEAD(newp) = AGTAIL(old); \
 	ED_tail_port(newp) = ED_head_port(old); \
@@ -264,14 +268,19 @@ static void _dot_splines(graph_t * g, int normalize)
 {
     int i, j, k, n_nodes, n_edges, ind, cnt;
     node_t *n;
+#ifndef WITH_CGRAPH
     edge_t fwdedgea, fwdedgeb;
+#else
+    Agedgeinfo_t fwdedgeai, fwdedgebi;
+    Agedgepair_t fwdedgea, fwdedgeb;
+#endif
     edge_t *e, *e0, *e1, *ea, *eb, *le0, *le1, **edges;
     path *P;
     spline_info_t sd;
-#ifndef WITH_CGRAPH
-    int et = EDGE_TYPE(g);
-#else /* WITH_CGRAPH */
     int et = EDGE_TYPE(g);
+#ifdef WITH_CGRAPH
+    fwdedgea.out.base.data = (Agrec_t*)&fwdedgeai;
+    fwdedgeb.out.base.data = (Agrec_t*)&fwdedgebi;
 #endif /* WITH_CGRAPH */
 
     if (et == ET_NONE) return; 
@@ -387,8 +396,13 @@ static void _dot_splines(graph_t * g, int normalize)
 	ea = (ED_tail_port(e0).defined
 	      || ED_head_port(e0).defined) ? e0 : le0;
 	if (ED_tree_index(ea) & BWDEDGE) {
+#ifndef WITH_CGRAPH
 	    MAKEFWDEDGE(&fwdedgea, ea);
 	    ea = &fwdedgea;
+#else
+	    MAKEFWDEDGE(&fwdedgea.out, ea);
+	    ea = &fwdedgea.out;
+#endif
 	}
 	for (cnt = 1; i < n_edges; cnt++, i++) {
 	    if (le0 != (le1 = getmainedge((e1 = edges[i]))))
@@ -397,8 +411,13 @@ static void _dot_splines(graph_t * g, int normalize)
 	    eb = (ED_tail_port(e1).defined
 		  || ED_head_port(e1).defined) ? e1 : le1;
 	    if (ED_tree_index(eb) & BWDEDGE) {
+#ifndef WITH_CGRAPH
 		MAKEFWDEDGE(&fwdedgeb, eb);
 		eb = &fwdedgeb;
+#else
+		MAKEFWDEDGE(&fwdedgeb.out, eb);
+		eb = &fwdedgeb.out;
+#endif
 	    }
 	    if (portcmp(ED_tail_port(ea), ED_tail_port(eb)))
 		break;
@@ -465,10 +484,18 @@ finish :
 	for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
 	    if (E_headlabel) {
 		for (e = agfstin(g, n); e; e = agnxtin(g, e))
+#ifndef WITH_CGRAPH
 		    if (ED_head_label(e)) {
 			if (place_portlabel(e, TRUE))
 			    updateBB(g, ED_head_label(e));
 		    }
+#else
+		    if (ED_head_label(AGMKOUT(e))) {
+			place_portlabel(AGMKOUT(e), TRUE);
+			updateBB(g, ED_head_label(AGMKOUT(e)));
+		    }
+#endif
+
 	    }
 	    if (E_taillabel) {
 		for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
@@ -569,10 +596,20 @@ setflags(edge_t *e, int hint1, int hint2, int f3)
  */
 static int edgecmp(edge_t** ptr0, edge_t** ptr1)
 {
+#ifndef WITH_CGRAPH
     edge_t fwdedgea, fwdedgeb, *e0, *e1, *ea, *eb, *le0, *le1;
+#else
+    Agedgeinfo_t fwdedgeai, fwdedgebi;
+    Agedgepair_t fwdedgea, fwdedgeb;
+    edge_t *e0, *e1, *ea, *eb, *le0, *le1;
+#endif
     int et0, et1, v0, v1, rv;
     double t0, t1;
 
+#ifdef WITH_CGRAPH
+    fwdedgea.out.base.data = (Agrec_t*)&fwdedgeai;
+    fwdedgeb.out.base.data = (Agrec_t*)&fwdedgebi;
+#endif
     e0 = (edge_t *) * ptr0;
     e1 = (edge_t *) * ptr1;
     et0 = ED_tree_index(e0) & EDGETYPEMASK;
@@ -603,13 +640,23 @@ static int edgecmp(edge_t** ptr0, edge_t** ptr1)
 
     ea = (ED_tail_port(e0).defined || ED_head_port(e0).defined) ? e0 : le0;
     if (ED_tree_index(ea) & BWDEDGE) {
+#ifndef WITH_CGRAPH
 	MAKEFWDEDGE(&fwdedgea, ea);
 	ea = &fwdedgea;
+#else
+	MAKEFWDEDGE(&fwdedgea.out, ea);
+	ea = &fwdedgea.out;
+#endif
     }
     eb = (ED_tail_port(e1).defined || ED_head_port(e1).defined) ? e1 : le1;
     if (ED_tree_index(eb) & BWDEDGE) {
+#ifndef WITH_CGRAPH
 	MAKEFWDEDGE(&fwdedgeb, eb);
 	eb = &fwdedgeb;
+#else
+	MAKEFWDEDGE(&fwdedgeb.out, eb);
+	eb = &fwdedgeb.out;
+#endif
     }
     if ((rv = portcmp(ED_tail_port(ea), ED_tail_port(eb))))
 	return rv;
@@ -657,14 +704,11 @@ cloneGraph (graph_t* g)
     auxg = agopen ("auxg", AG_IS_DIRECTED(g)?AGDIGRAPH:AGRAPH);
     agraphattr(auxg, "rank", "");
 #else /* WITH_CGRAPH */
-//    auxg = agopen ("auxg", AG_IS_DIRECTED(g)?AGDIGRAPH:AGRAPH);
-
-	if (agisdirected(g))
-		auxg = agopen ("auxg",Agdirected, NIL(Agdisc_t *));
-	else
-		auxg = agopen ("auxg",Agundirected, NIL(Agdisc_t *));
-
-
+    if (agisdirected(g))
+	auxg = agopen ("auxg",Agdirected, NIL(Agdisc_t *));
+    else
+	auxg = agopen ("auxg",Agundirected, NIL(Agdisc_t *));
+    agbindrec(auxg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
     agattr(auxg, AGRAPH, "rank", "");
 #endif /* WITH_CGRAPH */
     GD_drawing(auxg) = NEW(layout_t);
@@ -1440,7 +1484,13 @@ static void
 make_flat_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt, int et)
 {
     node_t *tn, *hn;
+#ifndef WITH_CGRAPH
     edge_t fwdedge, *e;
+#else
+    Agedgeinfo_t fwdedgei;
+    Agedgepair_t fwdedge;
+    edge_t *e;
+#endif
     int j, i, r;
     double stepx, stepy, vspace;
     int tside, hside, pn;
@@ -1448,11 +1498,20 @@ make_flat_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt, i
     pathend_t tend, hend;
     graph_t* g;
 
+#ifdef WITH_CGRAPH
+    fwdedge.out.base.data = (Agrec_t*)&fwdedgei;
+#endif
+
     /* Get sample edge; normalize to go from left to right */
     e = edges[ind];
     if (ED_tree_index(e) & BWDEDGE) {
+#ifndef WITH_CGRAPH
 	MAKEFWDEDGE(&fwdedge, e);
 	e = &fwdedge;
+#else
+	MAKEFWDEDGE(&fwdedge.out, e);
+	e = &fwdedge.out;
+#endif
     }
     if (ED_adjacent(edges[ind])) {
 	make_flat_adj_edges (P, edges, ind, cnt, e, et);
@@ -1635,7 +1694,13 @@ make_regular_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt
 {
     graph_t *g;
     node_t *tn, *hn;
+#ifndef WITH_CGRAPH
     edge_t fwdedgea, fwdedgeb, fwdedge, *e, *fe, *le, *segfirst;
+#else
+    Agedgeinfo_t fwdedgeai, fwdedgebi, fwdedgei;
+    Agedgepair_t fwdedgea, fwdedgeb, fwdedge;
+    edge_t *e, *fe, *le, *segfirst;
+#endif /* WITH_CGRAPH */
     pointf *ps;
     pathend_t tend, hend;
     boxf b;
@@ -1646,6 +1711,12 @@ make_regular_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt
     static int numpts2;
     int pointn;
 
+#ifdef WITH_CGRAPH
+    fwdedgea.out.base.data = (Agrec_t*)&fwdedgeai;
+    fwdedgeb.out.base.data = (Agrec_t*)&fwdedgebi;
+    fwdedge.out.base.data = (Agrec_t*)&fwdedgei;
+#endif /* WITH_CGRAPH */
+
     if (!pointfs) {
 	pointfs = N_GNEW(NUMPTS, pointf);
    	pointfs2 = N_GNEW(NUMPTS, pointf);
@@ -1657,22 +1728,32 @@ make_regular_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt
     g = agraphof(agtail(e));
     hackflag = FALSE;
     if (ABS(ND_rank(agtail(e)) - ND_rank(aghead(e))) > 1) {
+#ifndef WITH_CGRAPH
 	fwdedgea = *e;
+#else /* WITH_CGRAPH */
+	fwdedgeai = *(Agedgeinfo_t*)e->base.data;
+	fwdedgea.out = *e;
+	fwdedgea.out.base.data = (Agrec_t*)&fwdedgeai;
+#endif /* WITH_CGRAPH */
 	if (ED_tree_index(e) & BWDEDGE) {
-	    MAKEFWDEDGE(&fwdedgeb, e);
 #ifndef WITH_CGRAPH
+	    MAKEFWDEDGE(&fwdedgeb, e);
 	    fwdedgea.tail = aghead(e);
 	    fwdedgea.u.tail_port = ED_head_port(e);
 #else /* WITH_CGRAPH */
-	    agtail(&fwdedgea) = aghead(e);
-	    ED_tail_port(&fwdedgea) = ED_head_port(e);
+	    MAKEFWDEDGE(&fwdedgeb.out, e);
+	    agtail(&fwdedgea.out) = aghead(e);
+	    ED_tail_port(&fwdedgea.out) = ED_head_port(e);
 #endif /* WITH_CGRAPH */
 	} else {
-	    fwdedgeb = *e;
 #ifndef WITH_CGRAPH
+	    fwdedgeb = *e;
 	    fwdedgea.tail = e->tail;
 #else /* WITH_CGRAPH */
-	    agtail(&fwdedgea) = agtail(e);
+	    fwdedgebi = *(Agedgeinfo_t*)e->base.data;
+	    fwdedgeb.out = *e;
+	    fwdedgeb.out.base.data = (Agrec_t*)&fwdedgebi;
+	    agtail(&fwdedgea.out) = agtail(e);
 #endif /* WITH_CGRAPH */
 	}
 	le = getmainedge(e);
@@ -1684,19 +1765,25 @@ make_regular_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt
 	fwdedgea.u.edge_type = VIRTUAL;
 	fwdedgea.u.head_port.p.x = fwdedgea.u.head_port.p.y = 0;
 	fwdedgea.u.to_orig = e;
+	e = &fwdedgea;
 #else /* WITH_CGRAPH */
-	aghead(&fwdedgea) = aghead(le);
-	ED_head_port(&fwdedgea).defined = FALSE;
-	ED_edge_type(&fwdedgea) = VIRTUAL;
-	ED_head_port(&fwdedgea).p.x = ED_head_port(&fwdedgea).p.y = 0;
-	ED_to_orig(&fwdedgea) = e;
+	aghead(&fwdedgea.out) = aghead(le);
+	ED_head_port(&fwdedgea.out).defined = FALSE;
+	ED_edge_type(&fwdedgea.out) = VIRTUAL;
+	ED_head_port(&fwdedgea.out).p.x = ED_head_port(&fwdedgea.out).p.y = 0;
+	ED_to_orig(&fwdedgea.out) = e;
+	e = &fwdedgea.out;
 #endif /* WITH_CGRAPH */
-	e = &fwdedgea;
 	hackflag = TRUE;
     } else {
 	if (ED_tree_index(e) & BWDEDGE) {
+#ifndef WITH_CGRAPH
 	    MAKEFWDEDGE(&fwdedgea, e);
 	    e = &fwdedgea;
+#else
+	    MAKEFWDEDGE(&fwdedgea.out, e);
+	    e = &fwdedgea.out;
+#endif
 	}
     }
     fe = e;
@@ -1786,8 +1873,11 @@ make_regular_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt
 	}
 	boxes[boxn++] = rank_box(sp, g, ND_rank(tn));
 	b = hend.nb = maximal_bbox(sp, hn, e, NULL);
-	endpath(P, hackflag ? &fwdedgeb : e, REGULAREDGE, &hend,
-	        spline_merge(aghead(e)));
+#ifndef WITH_CGRAPH
+	endpath(P, hackflag ? &fwdedgeb : e, REGULAREDGE, &hend, spline_merge(aghead(e)));
+#else
+	endpath(P, hackflag ? &fwdedgeb.out : e, REGULAREDGE, &hend, spline_merge(aghead(e)));
+#endif
 	b.UR.y = hend.boxes[hend.boxn - 1].UR.y;
 	b.LL.y = hend.boxes[hend.boxn - 1].LL.y;
 	b = makeregularend(b, TOP,
@@ -1817,7 +1907,11 @@ make_regular_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt
 	    pointfs[pointn++] = ps[i];
 	}
 	recover_slack(segfirst, P);
+#ifndef WITH_CGRAPH
 	hn = hackflag ? aghead(&fwdedgeb) : aghead(e);
+#else
+	hn = hackflag ? aghead(&fwdedgeb.out) : aghead(e);
+#endif
     }
 
     /* make copies of the spline points, one per multi-edge */
@@ -1840,8 +1934,13 @@ make_regular_edge(spline_info_t* sp, path * P, edge_t ** edges, int ind, int cnt
     for (j = 1; j < cnt; j++) {
 	e = edges[ind + j];
 	if (ED_tree_index(e) & BWDEDGE) {
+#ifndef WITH_CGRAPH
 	    MAKEFWDEDGE(&fwdedge, e);
 	    e = &fwdedge;
+#else
+	    MAKEFWDEDGE(&fwdedge.out, e);
+	    e = &fwdedge.out;
+#endif
 	}
 	for (i = 1; i < pointn - 1; i++)
 	    pointfs[i].x += sp->Multisep;
diff --git a/lib/dotgen/fastgr.c b/lib/dotgen/fastgr.c
index f883ac803..2eb380fac 100644
--- a/lib/dotgen/fastgr.c
+++ b/lib/dotgen/fastgr.c
@@ -166,8 +166,11 @@ edge_t *new_virtual_edge(node_t * u, node_t * v, edge_t * orig)
 #ifndef WITH_CGRAPH
     e = NEW(edge_t);
 #else /* WITH_CGRAPH */
-    e=agedge(agraphof(orig),u,v,"",1);
-    agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE);	//graph custom data
+    Agedgepair_t* e2 = NEW(Agedgepair_t);
+    AGTYPE(&(e2->in)) = AGINEDGE;
+    AGTYPE(&(e2->out)) = AGOUTEDGE;
+    e2->out.base.data = NEW(Agedgeinfo_t);
+    e = &(e2->out);
 #endif /* WITH_CGRAPH */
     agtail(e) = u;
     aghead(e) = v;
@@ -175,6 +178,9 @@ edge_t *new_virtual_edge(node_t * u, node_t * v, edge_t * orig)
 
     if (orig) {
 	AGID(e) = AGID(orig);
+#ifdef WITH_CGRAPH
+	AGID(&(e2->in)) = AGID(orig);
+#endif
 	ED_count(e) = ED_count(orig);
 	ED_xpenalty(e) = ED_xpenalty(orig);
 	ED_weight(e) = ED_weight(orig);
@@ -247,6 +253,9 @@ node_t *virtual_node(graph_t * g)
     n->graph = g;
 #else /* WITH_CGRAPH */
 //  agnameof(n) = "virtual";
+    AGTYPE(n) = AGNODE;
+    n->root = g;
+    n->base.data = NEW(Agnodeinfo_t);
     n->root = g;
 #endif /* WITH_CGRAPH */
     ND_node_type(n) = VIRTUAL;
diff --git a/lib/dotgen/mincross.c b/lib/dotgen/mincross.c
index 7d23f8d7a..3d9327c31 100644
--- a/lib/dotgen/mincross.c
+++ b/lib/dotgen/mincross.c
@@ -742,6 +742,9 @@ static void cleanup2(graph_t * g, int nc)
 		for (j = 0; (e = ND_flat_out(v).list[j]); j++)
 		    if (ED_edge_type(e) == FLATORDER) {
 			delete_flat_edge(e);
+#ifdef WITH_CGRAPH
+			free(e->base.data);
+#endif
 			free(e);
 			j--;
 		    }
diff --git a/lib/dotgen/position.c b/lib/dotgen/position.c
index ab0b0ddf9..3e5c9c922 100644
--- a/lib/dotgen/position.c
+++ b/lib/dotgen/position.c
@@ -172,7 +172,16 @@ edge_t *make_aux_edge(node_t * u, node_t * v, double len, int wt)
 {
     edge_t *e;
 
+#ifndef WITH_CGRAPH
     e = NEW(edge_t);
+#else
+    Agedgepair_t* e2 = NEW(Agedgepair_t);
+    AGTYPE(&(e2->in)) = AGINEDGE;
+    AGTYPE(&(e2->out)) = AGOUTEDGE;
+    e2->out.base.data = NEW(Agedgeinfo_t);
+    e = &(e2->out);
+#endif /* WITH_CGRAPH */
+
     agtail(e) = u;
     aghead(e) = v;
     if (len > USHRT_MAX)
@@ -543,8 +552,12 @@ static void remove_aux_edges(graph_t * g)
     edge_t *e;
 
     for (n = GD_nlist(g); n; n = ND_next(n)) {
-	for (i = 0; (e = ND_out(n).list[i]); i++)
+	for (i = 0; (e = ND_out(n).list[i]); i++) {
+#ifdef WITH_CGRAPH
+	    free(e->base.data);
+#endif
 	    free(e);
+	}
 	free_list(ND_out(n));
 	free_list(ND_in(n));
 	ND_out(n) = ND_save_out(n);
@@ -559,6 +572,9 @@ static void remove_aux_edges(graph_t * g)
 		ND_next(nprev) = nnext;
 	    else
 		GD_nlist(g) = nnext;
+#ifdef WITH_CGRAPH
+	    free(n->base.data);
+#endif
 	    free(n);
 	} else
 	    nprev = n;
@@ -1119,10 +1135,15 @@ static void do_leaves(graph_t * g, node_t * leader)
 	n = aghead(ND_out(leader).list[0]);
 	j = ND_order(leader) + 1;
 	for (e = agfstin(g, n); e; e = agnxtin(g, e)) {
-	    if ((agtail(e) != leader) && (UF_find(agtail(e)) == leader)) {
-		lbound = place_leaf(agtail(e), lbound, j++);
-		unmerge_oneway(e);
-		elist_append(e, ND_in(aghead(e)));
+#ifndef WITH_CGRAPH
+	    edge_t *e1 = e;
+#else
+	    edge_t *e1 = AGMKOUT(e);
+#endif
+	    if ((agtail(e1) != leader) && (UF_find(agtail(e1)) == leader)) {
+		lbound = place_leaf(agtail(e1), lbound, j++);
+		unmerge_oneway(e1);
+		elist_append(e1, ND_in(aghead(e1)));
 	    }
 	}
     } else {			/* out edge leaves */
diff --git a/lib/dotgen/rank.c b/lib/dotgen/rank.c
index 6cf5d812d..7d9d9219b 100644
--- a/lib/dotgen/rank.c
+++ b/lib/dotgen/rank.c
@@ -61,6 +61,7 @@ cleanup1(graph_t * g)
 	     */
 	    if (f && (e == ED_to_orig(f))) {
 		edge_t *e1, *f1;
+#ifndef WITH_CGRAPH
 		for (e1 = agfstout(g, n); e1; e1 = agnxtout(g, e1)) {
 		    if (e != e1) {
 			f1 = ED_to_virt(e1);
@@ -69,6 +70,20 @@ cleanup1(graph_t * g)
 			}
 		    }
 		}
+#else
+		node_t *n1;
+		for (n1 = agfstnode(g); n1; n1 = agnxtnode(g, n1)) {
+		    for (e1 = agfstout(g, n1); e1; e1 = agnxtout(g, e1)) {
+			if (e != e1) {
+			    f1 = ED_to_virt(e1);
+			    if (f1 && (f == f1)) {
+				ED_to_virt(e1) = NULL;
+			    }
+			}
+		    }
+		}
+		free(f->base.data);
+#endif
 		free(f);
 	    }
 	    ED_to_virt(e) = NULL;
@@ -637,7 +652,11 @@ collapse_leaves(graph_t * g)
 	    continue;
 	if (agfstout(g, n) == NULL) {
 	    if ((e = agfstin(g, n)) && (agnxtin(g, e) == NULL)) {
+#ifndef WITH_CGRAPH
 		potential_leaf(g, e, n);
+#else
+		potential_leaf(g, AGMKOUT(e), n);
+#endif
 		continue;
 	    }
 	}
diff --git a/lib/dotgen/sameport.c b/lib/dotgen/sameport.c
index 56e59414d..5adc75273 100644
--- a/lib/dotgen/sameport.c
+++ b/lib/dotgen/sameport.c
@@ -57,7 +57,7 @@ void dot_sameports(graph_t * g)
 #ifndef WITH_CGRAPH
 		(id = agxget(e, E_samehead->index))[0])
 #else /* WITH_CGRAPH */
-	        (id = agxget(e, E_sametail))[0])
+	        (id = agxget(e, E_samehead))[0])
 #endif /* WITH_CGRAPH */
 		sameedge(same, n, e, id);
 	    else if (agtail(e) == n && E_sametail &&
diff --git a/lib/fdpgen/comp.c b/lib/fdpgen/comp.c
index 046acd40d..bea7b6f9c 100644
--- a/lib/fdpgen/comp.c
+++ b/lib/fdpgen/comp.c
@@ -89,7 +89,7 @@ graph_t **findCComp(graph_t * g, int *cnt, int *pinned)
 	subg = agsubg(g, name);
 #else /* WITH_CGRAPH */
 	subg = agsubg(g, name,1);
-	agbindrec(subg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);	//node custom data
+	agbindrec(subg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
 #endif /* WITH_CGRAPH */
 	GD_alg(subg) = (void *) NEW(gdata);
 	PORTS(subg) = pp;
@@ -114,7 +114,7 @@ graph_t **findCComp(graph_t * g, int *cnt, int *pinned)
 	    subg = agsubg(g, name);
 #else /* WITH_CGRAPH */
 	    subg = agsubg(g, name,1);
-		agbindrec(subg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);	//node custom data
+		agbindrec(subg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
 #endif /* WITH_CGRAPH */
 	    GD_alg(subg) = (void *) NEW(gdata);
 	}
diff --git a/lib/fdpgen/fdpinit.c b/lib/fdpgen/fdpinit.c
index cdc3bfd71..ca56716ca 100644
--- a/lib/fdpgen/fdpinit.c
+++ b/lib/fdpgen/fdpinit.c
@@ -149,7 +149,7 @@ static void cleanup_subgs(graph_t * g)
 #ifndef WITH_CGRAPH
 	memset(&(g->u), 0, sizeof(Agraphinfo_t));
 #else /* WITH_CGRAPH */
-	agclean(g, AGRAPH , "Agraphinfo_t");				
+	agdelrec(g, "Agraphinfo_t");				
 #endif /* WITH_CGRAPH */
 }
 
diff --git a/lib/fdpgen/layout.c b/lib/fdpgen/layout.c
index 6e5ed5215..b15e74973 100644
--- a/lib/fdpgen/layout.c
+++ b/lib/fdpgen/layout.c
@@ -205,6 +205,9 @@ static void freeDeriveNode(node_t * n)
 {
     free(ND_alg(n));
     free(ND_pos(n));
+#ifdef WITH_CGRAPH
+    agdelrec(n, "Agnodeinfo_t");
+#endif
 }
 
 static void freeGData(graph_t * g)
@@ -221,14 +224,23 @@ static void freeDerivedGraph(graph_t * g, graph_t ** cc)
 
     while ((cg = *cc++)) {
 	freeGData(cg);
+#ifdef WITH_CGRAPH
+	agdelrec(cg, "Agraphinfo_t");
+#endif
     }
     if (PORTS(g))
 	free(PORTS(g));
     freeGData(g);
+#ifdef WITH_CGRAPH
+    agdelrec(dg, "Agraphinfo_t");
+#endif
     for (dn = agfstnode(g); dn; dn = dnxt) {
 	dnxt = agnxtnode(g, dn);
 	for (e = agfstout(g, dn); e; e = agnxtout(g, e)) {
 	    free (ED_to_virt(e));
+#ifdef WITH_CGRAPH
+	    agdelrec(e, "Agedgeinfo_t");
+#endif
 	}
 	freeDeriveNode(dn);
     }
@@ -473,7 +485,7 @@ static graph_t *deriveGraph(graph_t * g, layout_info * infop)
     dg = agopen(name, AGRAPHSTRICT);
 #else /* WITH_CGRAPH */
     dg = agopen("derived", Agstrictdirected,NIL(Agdisc_t *));
-    agbindrec(dg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);	//node custom data
+    agbindrec(dg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
 #endif /* WITH_CGRAPH */
     GD_alg(dg) = (void *) NEW(gdata);	/* freed in freeDeriveGraph */
 #ifdef DEBUG
@@ -570,7 +582,7 @@ static graph_t *deriveGraph(graph_t * g, layout_info * infop)
 		de = agedge(dg, hd, tl);
 #else /* WITH_CGRAPH */
 		de = agedge(dg, hd, tl, NULL,1);
-		agbindrec(de, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE);	//node custom data
+	    agbindrec(de, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE);
 #endif /* WITH_CGRAPH */
 	    ED_dist(de) = ED_dist(e);
 	    ED_factor(de) = ED_factor(e);
@@ -612,6 +624,7 @@ static graph_t *deriveGraph(graph_t * g, layout_info * infop)
 		    de = agedge(dg, dn, m);
 #else /* WITH_CGRAPH */
 		    de = agedge(dg, dn, m, NULL,1);
+		agbindrec(de, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE);
 #endif /* WITH_CGRAPH */
 		ED_dist(de) = ED_dist(pp->e);
 		ED_factor(de) = ED_factor(pp->e);
@@ -1100,10 +1113,8 @@ mkClusters (graph_t * g, clist_t* pclist, graph_t* parent)
 
     for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg))
 	{
-//	for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) {
-//	mn = aghead(me);
-//	subg = agusergraph(mn);
 	if (!strncmp(agnameof(subg), "cluster", 7)) {
+	    agbindrec(subg, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE);
 #endif /* WITH_CGRAPH */
 	    GD_alg(subg) = (void *) NEW(gdata);	/* freed in cleanup_subgs */
 	    GD_ndim(subg) = GD_ndim(parent);
-- 
2.40.0