/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/dotgen/decomp.c

Go to the documentation of this file.
00001 /* $Id: decomp.c,v 1.2 2005/03/08 23:34:10 erg 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 
00018 /* 
00019  * Decompose finds the connected components of a graph.
00020  * It searches the temporary edges and ignores non-root nodes.
00021  * The roots of the search are the real nodes of the graph,
00022  * but any virtual nodes discovered are also included in the
00023  * component.
00024  */
00025 
00026 #include "dot.h"
00027 
00028 
00029 static graph_t *G;
00030 static node_t *Last_node;
00031 static char Cmark;
00032 
00033 static void 
00034 begin_component(void)
00035 {
00036     Last_node = GD_nlist(G) = NULL;
00037 }
00038 
00039 static void 
00040 add_to_component(node_t * n)
00041 {
00042     GD_n_nodes(G)++;
00043     ND_mark(n) = Cmark;
00044     if (Last_node) {
00045         ND_prev(n) = Last_node;
00046         ND_next(Last_node) = n;
00047     } else {
00048         ND_prev(n) = NULL;
00049         GD_nlist(G) = n;
00050     }
00051     Last_node = n;
00052     ND_next(n) = NULL;
00053 }
00054 
00055 static void 
00056 end_component(void)
00057 {
00058     int i;
00059 
00060     i = GD_comp(G).size++;
00061     GD_comp(G).list = ALLOC(GD_comp(G).size, GD_comp(G).list, node_t *);
00062     GD_comp(G).list[i] = GD_nlist(G);
00063 }
00064 
00065 static void
00066 search_component(graph_t * g, node_t * n)
00067 {
00068     int c, i;
00069     elist vec[4];
00070     node_t *other;
00071     edge_t *e;
00072 
00073     add_to_component(n);
00074     vec[0] = ND_out(n);
00075     vec[1] = ND_in(n);
00076     vec[2] = ND_flat_out(n);
00077     vec[3] = ND_flat_in(n);
00078 
00079     for (c = 0; c <= 3; c++) {
00080         if (vec[c].list)
00081             for (i = 0; (e = vec[c].list[i]); i++) {
00082                 if ((other = e->head) == n)
00083                     other = e->tail;
00084                 if ((ND_mark(other) != Cmark) && (other == UF_find(other)))
00085                     search_component(g, other);
00086             }
00087     }
00088 }
00089 
00090 void decompose(graph_t * g, int pass)
00091 {
00092     graph_t *subg;
00093     node_t *n, *v;
00094 
00095     G = g;
00096     if (++Cmark == 0)
00097         Cmark = 1;
00098     GD_n_nodes(g) = GD_comp(g).size = 0;
00099     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00100         v = n;
00101         if ((pass > 0) && (subg = ND_clust(v)))
00102             v = GD_rankleader(subg)[ND_rank(v)];
00103         else if (v != UF_find(v))
00104             continue;
00105         if (ND_mark(v) != Cmark) {
00106             begin_component();
00107             search_component(g, v);
00108             end_component();
00109         }
00110     }
00111 }

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