"lib/circogen/circular.c",
"lib/circogen/circular.h",
"lib/circogen/circularinit.c",
- "lib/circogen/deglist.c",
- "lib/circogen/deglist.h",
"lib/circogen/edgelist.c",
"lib/circogen/edgelist.h",
"lib/circogen/nodelist.c",
circo.h
circpos.h
circular.h
- deglist.h
edgelist.h
nodelist.h
circpos.c
circular.c
circularinit.c
- deglist.c
edgelist.c
nodelist.c
)
endif
noinst_HEADERS = block.h blockpath.h blocktree.h circo.h \
- circpos.h circular.h deglist.h edgelist.h nodelist.h
+ circpos.h circular.h edgelist.h nodelist.h
noinst_LTLIBRARIES = libcircogen_C.la
libcircogen_C_la_SOURCES = circularinit.c nodelist.c block.c edgelist.c \
- circular.c deglist.c blocktree.c blockpath.c \
+ circular.c blocktree.c blockpath.c \
circpos.c
EXTRA_DIST = gvcircogen.vcxproj*
* Contributors: Details at https://graphviz.org
*************************************************************************/
+#include <cgraph/list.h>
#include <cgraph/alloc.h>
#include <circogen/blockpath.h>
#include <circogen/edgelist.h>
-#include <circogen/deglist.h>
#include <stddef.h>
#include <stdbool.h>
return clone;
}
+DEFINE_LIST(deglist, Agnode_t*)
+
+/// comparison function for sorting nodes by degree, descending
+static int cmpDegree(const Agnode_t **a, const Agnode_t **b) {
+// Suppress Clang/GCC -Wcast-qual warnings. `DEGREE` does not modify the
+// underlying data, but uses casts that make it look like it does.
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+ if (DEGREE(*a) < DEGREE(*b)) {
+ return 1;
+ }
+ if (DEGREE(*a) > DEGREE(*b)) {
+ return -1;
+ }
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+ return 0;
+}
+
/* fillList:
- * Add nodes to deg_list, which stores them by degree.
+ * Add nodes to deg_list, storing them by descending degree.
*/
-static deglist_t *getList(Agraph_t * g)
-{
- deglist_t *dl = mkDeglist();
+static deglist_t getList(Agraph_t *g) {
+ deglist_t dl = {0};
Agnode_t *n;
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
- insertDeglist(dl, n);
+ deglist_append(&dl, n);
}
+ deglist_sort(&dl, cmpDegree);
return dl;
}
int nodeCount;
Agraph_t *outg;
Agraph_t *g;
- deglist_t *dl;
Agnode_t *currnode, *adjNode;
Agedge_t *e;
outg = clone_graph(ing, &g);
nodeCount = agnnodes(g);
- dl = getList(g);
+ deglist_t dl = getList(g);
while (counter < (nodeCount - 3)) {
- currnode = firstDeglist(dl);
+ currnode = deglist_is_empty(&dl) ? NULL : deglist_pop(&dl);
/* Remove all adjacent nodes since they have to be reinserted */
for (e = agfstedge(g, currnode); e; e = agnxtedge(g, e, currnode)) {
adjNode = aghead(e);
if (currnode == adjNode)
adjNode = agtail(e);
- removeDeglist(dl, adjNode);
+ deglist_remove(&dl, adjNode);
}
find_pair_edges(g, currnode, outg);
adjNode = agtail(e);
DEGREE(adjNode)--;
- insertDeglist(dl, adjNode);
+ deglist_append(&dl, adjNode);
}
+ deglist_sort(&dl, cmpDegree);
agdelete(g, currnode);
}
agclose(g);
- freeDeglist(dl);
+ deglist_free(&dl);
return outg;
}
+++ /dev/null
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
-
-#include <cgraph/alloc.h>
-#include <circogen/deglist.h>
-#include <circogen/circular.h>
-#include <circogen/blockpath.h>
-#include <assert.h>
-
-typedef struct {
- Dtlink_t link;
- int deg;
- Agnode_t *np; /* linked list of nodes of same degree */
-} degitem;
-
-static degitem *mkItem(Dt_t * d, degitem * obj, Dtdisc_t * disc)
-{
- (void)d;
- (void)disc;
-
- degitem *ap = gv_alloc(sizeof(degitem));
-
- ap->np = NULL;
- ap->deg = obj->deg;
- return ap;
-}
-
-static void freeItem(Dt_t * d, degitem * obj, Dtdisc_t * disc)
-{
- (void)d;
- (void)disc;
-
- free(obj);
-}
-
-static int cmpDegree(Dt_t * d, int *key1, int *key2, Dtdisc_t * disc)
-{
- (void)d;
- (void)disc;
-
- if (*key1 < *key2) {
- return -1;
- }
- if (*key1 > *key2) {
- return 1;
- }
- return 0;
-}
-
-static Dtdisc_t nodeDisc = {
- offsetof(degitem, deg), /* key */
- sizeof(int), /* size */
- offsetof(degitem, link), /* link */
- (Dtmake_f) mkItem,
- (Dtfree_f) freeItem,
- (Dtcompar_f) cmpDegree,
- (Dthash_f) 0,
- (Dtmemory_f) 0,
- (Dtevent_f) 0
-};
-
-/* mkDeglist:
- * Create an empty list of nodes.
- */
-deglist_t *mkDeglist(void)
-{
- deglist_t *s = dtopen(&nodeDisc, Dtoset);
- return s;
-}
-
-/* freeDeglist:
- * Delete the node list.
- * Nodes are not deleted.
- */
-void freeDeglist(deglist_t * s)
-{
- dtclose(s);
-}
-
-/* insertDeglist:
- * Add a node to the node list.
- * Nodes are kept sorted by DEGREE, smallest degrees first.
- */
-void insertDeglist(deglist_t * ns, Agnode_t * n)
-{
- degitem key;
- degitem *kp;
-
- key.deg = DEGREE(n);
- kp = dtinsert(ns, &key);
- ND_next(n) = kp->np;
- kp->np = n;
-}
-
-/* removeDeglist:
- * Remove n from list, if it is in the list.
- */
-void removeDeglist(deglist_t * list, Agnode_t * n)
-{
- degitem key;
- degitem *ip;
- Agnode_t *np;
- Agnode_t *prev;
-
- key.deg = DEGREE(n);
- ip = dtsearch(list, &key);
- assert(ip);
- if (ip->np == n) {
- ip->np = ND_next(n);
- if (ip->np == NULL)
- dtdelete(list, ip);
- } else {
- prev = ip->np;
- np = ND_next(prev);
- while (np && (np != n)) {
- prev = np;
- np = ND_next(np);
- }
- if (np)
- ND_next(prev) = ND_next(np);
- }
-}
-
-/* firstDeglist:
- * Return the first node in the list (smallest degree)
- * Remove from list.
- * If the list is empty, return NULL
- */
-Agnode_t *firstDeglist(deglist_t * list)
-{
- degitem *ip;
- Agnode_t *np;
-
- ip = dtfirst(list);
- if (ip) {
- np = ip->np;
- ip->np = ND_next(np);
- if (ip->np == NULL)
- dtdelete(list, ip);
- return np;
- } else
- return 0;
-}
-
-#ifdef DEBUG
-void printDeglist(deglist_t * dl)
-{
- degitem *ip;
- node_t *np;
- fprintf(stderr, " dl:\n");
- for (ip = dtfirst(dl); ip; ip = dtnext(dl, ip)) {
- np = ip->np;
- if (np)
- fprintf(stderr, " (%d)", ip->deg);
- for (; np; np = ND_next(np)) {
- fprintf(stderr, " %s", agnameof(np));
- }
- fprintf(stderr, "\n");
- }
-
-}
-#endif
+++ /dev/null
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* List of nodes sorted by increasing degree */
-
-#include <render.h>
-
- typedef Dt_t deglist_t;
-
- extern deglist_t *mkDeglist(void);
- extern void freeDeglist(deglist_t * list);
- extern void insertDeglist(deglist_t * list, Agnode_t * n);
- extern void removeDeglist(deglist_t * list, Agnode_t * n);
- extern Agnode_t *firstDeglist(deglist_t *);
-
-#ifdef DEBUG
- extern void printDeglist(deglist_t *);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
<ClInclude Include="circo.h" />
<ClInclude Include="circpos.h" />
<ClInclude Include="circular.h" />
- <ClInclude Include="deglist.h" />
<ClInclude Include="edgelist.h" />
<ClInclude Include="nodelist.h" />
</ItemGroup>
<ClCompile Include="circpos.c" />
<ClCompile Include="circular.c" />
<ClCompile Include="circularinit.c" />
- <ClCompile Include="deglist.c" />
<ClCompile Include="edgelist.c" />
<ClCompile Include="nodelist.c" />
</ItemGroup>
<ClInclude Include="circular.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="deglist.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="edgelist.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClCompile Include="circularinit.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="deglist.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="edgelist.c">
<Filter>Source Files</Filter>
</ClCompile>