00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #define FDP_PRIVATE 1
00028
00029 #include <fdp.h>
00030 #include <comp.h>
00031 #include <pack.h>
00032 #include <assert.h>
00033
00034 #define MARK(n) (marks[ND_id(n)])
00035
00036 static void dfs(Agraph_t * g, Agnode_t * n, Agraph_t * out, char *marks)
00037 {
00038 Agedge_t *e;
00039 Agnode_t *other;
00040
00041 MARK(n) = 1;
00042 aginsert(out, n);
00043 for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) {
00044 if ((other = e->tail) == n)
00045 other = e->head;
00046 if (!MARK(other))
00047 dfs(g, other, out, marks);
00048 }
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static int C_cnt = 0;
00063 graph_t **findCComp(graph_t * g, int *cnt, int *pinned)
00064 {
00065 node_t *n;
00066 graph_t *subg;
00067 char name[128];
00068 int c_cnt = 0;
00069 char *marks;
00070 bport_t *pp;
00071 graph_t **comps;
00072 graph_t **cp;
00073 graph_t *mg;
00074 edge_t *me;
00075 node_t *mn;
00076 int pinflag = 0;
00077
00078
00079 marks = N_NEW(agnnodes(g), char);
00080
00081
00082 subg = 0;
00083 if ((pp = PORTS(g))) {
00084 sprintf(name, "cc%s_%d", g->name, c_cnt++ + C_cnt);
00085 subg = agsubg(g, name);
00086 GD_alg(subg) = (void *) NEW(gdata);
00087 PORTS(subg) = pp;
00088 NPORTS(subg) = NPORTS(g);
00089 for (; pp->n; pp++) {
00090 if (MARK(pp->n))
00091 continue;
00092 dfs(g, pp->n, subg, marks);
00093 }
00094 }
00095
00096
00097
00098 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00099 if (MARK(n))
00100 continue;
00101 if (ND_pinned(n) != P_PIN)
00102 continue;
00103 if (!subg) {
00104 sprintf(name, "cc%s_%d", g->name, c_cnt++ + C_cnt);
00105 subg = agsubg(g, name);
00106 GD_alg(subg) = (void *) NEW(gdata);
00107 }
00108 pinflag = 1;
00109 dfs(g, n, subg, marks);
00110 }
00111 if (subg)
00112 nodeInduce(subg);
00113
00114
00115 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00116 if (MARK(n))
00117 continue;
00118 sprintf(name, "cc%s+%d", g->name, c_cnt++ + C_cnt);
00119 subg = agsubg(g, name);
00120 GD_alg(subg) = (void *) NEW(gdata);
00121 dfs(g, n, subg, marks);
00122 nodeInduce(subg);
00123 }
00124 free(marks);
00125 C_cnt += c_cnt;
00126
00127 if (cnt)
00128 *cnt = c_cnt;
00129 if (pinned)
00130 *pinned = pinflag;
00131
00132 comps = cp = N_NEW(c_cnt + 1, graph_t *);
00133 mg = g->meta_node->graph;
00134 for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) {
00135 mn = me->head;
00136 *cp++ = agusergraph(mn);
00137 c_cnt--;
00138 }
00139 assert(c_cnt == 0);
00140 *cp = 0;
00141
00142 return comps;
00143 }