void prData(Agnode_t * n, int pass) { char *pname; char *bname; char *tname; char *name1; char *name2; int dist1, dist2; if (PARENT(n)) pname = agnameof(PARENT(n)); else pname = "<P0>"; if (BLOCK(n)) bname = agnameof(BLOCK(n)->sub_graph); else pname = "<B0>"; fprintf(stderr, "%s: %x %s %s ", agnameof(n), FLAGS(n), pname, bname); switch (pass) { case 0: fprintf(stderr, "%d %d\n", VAL(n), LOWVAL(n)); break; case 1: if (TPARENT(n)) tname = agnameof(TPARENT(n)); else tname = "<ROOT>"; dist1 = DISTONE(n); if (dist1 > 0) name1 = agnameof(LEAFONE(n)); else name1 = "<null>"; dist2 = DISTTWO(n); if (dist2 > 0) name2 = agnameof(LEAFTWO(n)); else name2 = "<null>"; fprintf(stderr, "%s %s %d %s %d\n", tname, name1, dist1, name2, dist2); break; default: fprintf(stderr, "%d\n", POSITION(n)); break; } }
/* dfs: * * Current scheme adds articulation point to first non-trivial child * block. If none exists, it will be added to its parent's block, if * non-trivial, or else given its own block. * * FIX: * This should be modified to: * - allow user to specify which block gets a node, perhaps on per-node basis. * - if an articulation point is not used in one of its non-trivial blocks, * dummy edges should be added to preserve biconnectivity * - turn on user-supplied blocks. * */ static void dfs(Agraph_t * g, Agnode_t * n, circ_state * state, int isRoot) { Agedge_t *e; Agnode_t *curtop; LOWVAL(n) = VAL(n) = state->orderCount++; stackPush(state->bcstack, n); for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { Agnode_t *neighbor = e->head; if (neighbor == n) neighbor = e->tail; if (neighbor == PARENT(n)) continue; if (VAL(neighbor)) { LOWVAL(n) = min_value(LOWVAL(n), VAL(neighbor)); continue; } if (!stackCheck(state->bcstack, n)) { stackPush(state->bcstack, n); } PARENT(neighbor) = n; curtop = top(state->bcstack); dfs(g, neighbor, state, 0); LOWVAL(n) = min_value(LOWVAL(n), LOWVAL(neighbor)); if (LOWVAL(neighbor) >= VAL(n)) { block_t *block = NULL; Agnode_t *np; if (top(state->bcstack) != curtop) do { np = stackPop(state->bcstack); if (!BCDONE(np)) { if (!block) block = makeBlock(g, state); addNode(block, np); } } while (np != n); if (block) { /* If block != NULL, it's not empty */ if (isRoot && (BLOCK(n) == block)) insertBlock(&state->bl, block); else appendBlock(&state->bl, block); } if ((LOWVAL(n) < VAL(n)) && (!stackCheck(state->bcstack, n))) { stackPush(state->bcstack, n); } } } if ((LOWVAL(n) == VAL(n)) && !BCDONE(n)) { block_t *block = makeBlock(g, state); stackPop(state->bcstack); addNode(block, n); if (isRoot) insertBlock(&state->bl, block); else appendBlock(&state->bl, block); } }