static block_t *makeBlock(Agraph_t * g, circ_state * state) { Agraph_t *subg = makeBlockGraph(g, state); block_t *bp = mkBlock(subg); return bp; }
static void dfs(Agraph_t * g, Agnode_t * u, bcstate * stp, Agnode_t * parent) { Agnode_t *v; Agedge_t *e; Agedge_t *ep; Agraph_t *sg; stp->count++; Low(u) = N(u) = stp->count; for (e = agfstedge(g, u); e; e = agnxtedge(g, e, u)) { if ((v = aghead(e)) == u) v = agtail(e); if (v == u) continue; if (N(v) == 0) { push(&stp->stk, e); dfs(g, v, stp, u); Low(u) = min(Low(u), Low(v)); if (Low(v) >= N(u)) { /* u is an articulation point */ Cut(u) = 1; sg = mkBlock(g, stp); do { ep = pop(&stp->stk); agsubnode(sg, aghead(ep), 1); agsubnode(sg, agtail(ep), 1); } while (ep != e); } } else if (parent != v) { Low(u) = min(Low(u), N(v)); if (N(v) < N(u)) push(&stp->stk, e); } } }
static block_t* createOneBlock(Agraph_t * g, circ_state * state) { Agraph_t *subg; char name[SMALLBUF]; block_t *bp; Agnode_t* n; sprintf(name, "_block_%d", state->blockCount++); subg = agsubg(g, name, 1); bp = mkBlock(subg); for (n = agfstnode(g); n; n = agnxtnode(g,n)) { agsubnode(bp->sub_graph, n, 1); BLOCK(n) = bp; } return bp; }
/* find_blocks: */ static void find_blocks(Agraph_t * g, circ_state * state) { Agnode_t *n; Agnode_t *root = NULL; block_t *rootBlock = NULL; blocklist_t ublks; #ifdef USER_BLOCKS graph_t *clust_subg; graph_t *mg; edge_t *me; node_t *mm; int isRoot; #endif initBlocklist(&ublks); /* check to see if there is a node which is set to be the root */ if (state->rootname) { root = agfindnode(g, state->rootname); } if (!root && state->N_root) { for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (late_bool(ORIGN(n), state->N_root, 0)) { root = n; break; } } } #ifdef USER_BLOCKS /* process clusters first */ /* by construction, all subgraphs are blocks and are non-empty */ mm = g->meta_node; mg = mm->graph; for (me = agfstout(mg, mm); me; me = agnxtout(mg, me)) { block_t *block; clust_subg = agusergraph(me->head); isRoot = 0; block = mkBlock(clust_subg); /* block = makeBlock(g, state); */ for (n = agfstnode(clust_subg); n; n = agnxtnode(clust_subg, n)) { if (!BCDONE(n)) { /* test not necessary if blocks disjoint */ SET_BCDONE(n); BLOCK(n) = block; if (n == root) isRoot = 1; } } if (isRoot) { /* Assume blocks are disjoint, so don't check if rootBlock is * already assigned. */ rootBlock = block; insertBlock(&state->bl, block); } else { appendBlock(&state->bl, block); } } ublks.first = state->bl.first; ublks.last = state->bl.last; #endif if (!root) root = agfstnode(g); dfs(g, root, state, !rootBlock); #ifdef USER_BLOCKS /* If g has user-supplied blocks, it may be disconnected. * We then fall into the following ugly loop. * We are guaranteed !VISITED(n) and PARENT(n) has been * set to a visited node. */ if (ublks.first) { while (n = findUnvisited(&ublks)) { dfs(g, n, state, 0); } } #endif }