]> granicus.if.org Git - graphviz/commitdiff
Fix memory leak in traversal by free stack/queue;
authorerg <devnull@localhost>
Wed, 1 Jun 2005 22:53:47 +0000 (22:53 +0000)
committererg <devnull@localhost>
Wed, 1 Jun 2005 22:53:47 +0000 (22:53 +0000)
add bfs traversal.

cmd/gvpr/gprdata
cmd/gvpr/gprstate.h
cmd/gvpr/gvpr.1
cmd/gvpr/gvpr.c

index 824a20361146fd72167ab8acb2dfed41401cd5ae..74b22af3b1686f9e3411715452ba18241cb2ea66 100644 (file)
@@ -83,6 +83,7 @@ F_get       "aget"      FUNCTION S|A(1,O)|A(2,S)
 F_set       "aset"      FUNCTION I|A(1,O)|A(2,S)|A(3,S)
 C_flat      "TV_flat"   CONSTANT T_tvtyp
 C_dfs       "TV_dfs"    CONSTANT T_tvtyp
+C_bfs       "TV_bfs"    CONSTANT T_tvtyp
 C_fwd       "TV_fwd"    CONSTANT T_tvtyp
 C_rev       "TV_rev"    CONSTANT T_tvtyp
 C_ne        "TV_ne"     CONSTANT T_tvtyp
index 6c7133bbef2d9a02b964adcb640eb419b990693e..dd63aa835f791a5d91bbc98c5559dd639c5f809e 100644 (file)
@@ -26,7 +26,7 @@ extern "C" {
 #include <ast.h>
 #include <vmalloc.h>
 
-    typedef enum { TV_flat, TV_dfs, TV_fwd, TV_rev, TV_ne,
+    typedef enum { TV_flat, TV_bfs, TV_dfs, TV_fwd, TV_rev, TV_ne,
            TV_en } trav_type;
 
     typedef struct {
index c589378055e72675f7d105446bf9838fca7825ff..ca2a3810b5a1902e59ec95427b16eeb53b906289 100644 (file)
@@ -687,7 +687,8 @@ The default value is \fBNULL\fP for each input graph.
 \fB$tvtype\fP : \fBtvtype_t\fP
 indicates how \fBgvpr\fP traverses a graph. At present, it can only take
 one of six values: \fBTV_flat\fP, \fBTV_dfs\fP, \fBTV_fwd\fP,
-\fBTV_ref\fP, \fBTV_ne\fP, and \fBTV_en\fP. \fBTV_flat\fP is the default.
+\fBTV_ref\fP, \fBTV_bfs\fP, \fBTV_ne\fP, and \fBTV_en\fP. 
+\fBTV_flat\fP is the default.
 The meaning of these values is discussed below.
 .TP
 \fBARGC\fP : \fBint\fP
@@ -733,6 +734,11 @@ if \fB$tvroot\fP is \fBNULL\fP, the traversal will stop. Note that using
 \fBTV_fwd\fR : \fItvtype_t\fR
 a traversal of the graph using a depth-first search on the
 graph following only forward arcs. In
+.TP
+\fBTV_bfs\fR : \fItvtype_t\fR
+a traversal of the graph using a bread-first search on the
+graph ignoring edge directions. See the item on \fBTV_dfs\fR above
+for the role of \fB$tvroot\fP.
 .IR libagraph (3),
 edges in undirected graphs are given an arbitrary direction, which is
 used for this traversal. The choice of roots for the traversal is the
index f01e71ab8d2f61ff7458821b02c173b065685625..396f874bb4034063efaa1b5f302171a805dde4d2 100644 (file)
@@ -324,17 +324,53 @@ static trav_fns DFSfns = { agfstedge, agnxtedge };
 static trav_fns FWDfns = { agfstout, (nxttedgefn_t) agnxtout };
 static trav_fns REVfns = { agfstin, (nxttedgefn_t) agnxtin };
 
+static void travBFS(Gpr_t * state, comp_prog * xprog)
+{
+    nodestream nodes;
+    queue *q;
+    ndata *nd;
+    Agnode_t *n;
+    Agedge_t *cure;
+
+    q = mkQueue();
+    nodes.oldroot = 0;
+    nodes.prev = 0;
+    while ((n = nextNode(state, &nodes))) {
+       nd = nData(n);
+       if (MARKED(nd))
+           continue;
+       PUSH(nd);
+       push (q,n);
+       while ((n = pull(q))) {
+           nd = nData(n);
+           MARK(nd);
+           POP(nd);
+           evalNode(state, xprog, n);
+           for (cure = agfstedge(n); cure; cure = agnxtedge(cure, n)) {
+               nd = nData(cure->node);
+               if (MARKED(nd)) continue;
+               evalEdge(state, xprog, cure);
+               if (!ONSTACK(nd)) {
+                   push(q, cure->node);
+                   PUSH(nd);
+               }
+           }
+       }
+    }
+    freeQ (q);
+}
+
 static void travDFS(Gpr_t * state, comp_prog * xprog, trav_fns * fns)
 {
     Agnode_t *n;
     queue *stk;
-    Agedgepair_t seed;
     Agnode_t *curn;
     Agedge_t *cure;
     Agedge_t *entry;
     int more;
     ndata *nd;
     nodestream nodes;
+    Agedgepair_t seed;
 
     stk = mkStack();
     nodes.oldroot = 0;
@@ -386,6 +422,7 @@ static void travDFS(Gpr_t * state, comp_prog * xprog, trav_fns * fns)
            }
        }
     }
+    freeQ (stk);
 }
 
 static void travNodes(Gpr_t * state, comp_prog * xprog)
@@ -444,6 +481,9 @@ static void traverse(Gpr_t * state, comp_prog * xprog)
     case TV_flat:
        travFlat(state, xprog);
        break;
+    case TV_bfs:
+       travBFS(state, xprog);
+       break;
     case TV_dfs:
        travDFS(state, xprog, &DFSfns);
        break;