56#define Low(n) (((Agnodeinfo_t*)(n->base.data))->low)
57#define Cut(n) (((Agnodeinfo_t*)(n->base.data))->isCut)
58#define N(n) (((Agnodeinfo_t*)(n->base.data))->val)
59#define NEXTBLK(g) (((Agraphinfo_t*)(g->base.data))->next)
97 if (ng == 0 && nb == 0)
127 outf = fopen(name,
"w");
129 fprintf(stderr,
"Could not open %s for writing\n", name);
170 edge_stack_push_back(&stp->
stk, e);
173 if (
Low(v) >=
N(u)) {
177 ep = edge_stack_pop_back(&stp->
stk);
185 edge_stack_push_back(&stp->
stk, e);
219 state.
stk = (edge_stack_t){0};
224 dfs(g, n, &state, 0);
232 gwrite(blk, gcnt, bcnt++);
251 fprintf(stderr,
"%s: %d blocks %d cutpoints\n",
agnameof(g), bcnt,
254 edge_stack_free(&state.
stk);
262 "Usage: bcomps [-stvx?] [-o<out template>] <files>\n\
263 -o - output file template\n\
264 -s - don't print components\n\
265 -t - emit block-cutpoint tree\n\
269If no files are specified, stdin is used\n";
281 sfx = strrchr(name,
'.');
283 size_t size = (size_t)(sfx - name);
291static void init(
int argc,
char *argv[])
296 while ((c = getopt(argc, argv,
":o:xstv?")) != -1) {
316 fprintf(stderr,
"bcomps: option -%c missing argument - ignored\n", optopt);
319 if (optopt ==
'\0' || optopt ==
'?')
323 "bcomps: option -%c unrecognized\n", optopt);
338int main(
int argc,
char *argv[])
static void agxbfree(agxbuf *xb)
free any malloced resources
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static WUR char * agxbuse(agxbuf *xb)
static char * agxbdisown(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static char * gv_strndup(const char *original, size_t length)
static void init(int argc, char *argv[])
static void gwrite(Agraph_t *g, int ng, int nb)
static int process(Agraph_t *g, int gcnt)
static char * blockName(agxbuf *xb, char *gname, int d)
static void dfs(Agraph_t *g, Agnode_t *u, bcstate *stp, Agnode_t *parent)
static void addCutPts(Agraph_t *tree, Agraph_t *blk)
static Agraph_t * mkBlock(Agraph_t *g, bcstate *stp)
abstract graph C library, Cgraph API
static NORETURN void graphviz_exit(int status)
size_t graphviz_node_induce(Agraph_t *g, Agraph_t *edgeset)
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Agdesc_t Agstrictundirected
strict undirected
int agclose(Agraph_t *g)
deletes a graph, freeing its associated storage
Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
creates a new graph with the given name and kind
int agwrite(Agraph_t *g, void *chan)
Return 0 on success, EOF on failure.
Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
Agnode_t * agsubnode(Agraph_t *g, Agnode_t *n, int createflag)
char * agnameof(void *)
returns a string descriptor for the object.
void aginit(Agraph_t *g, int kind, const char *rec_name, int rec_size, int move_to_front)
attach new records to objects of specified kind
void * agbindrec(void *obj, const char *name, unsigned int recsize, int move_to_front)
attaches a new record of the given size to the object
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Arithmetic helper functions.
static int imin(int a, int b)
minimum of two integers
static const char * usage
Agraph_t * nextGraph(ingraph_state *sp)
ingraph_state * newIngraph(ingraph_state *sp, char **files)
supports user-supplied data
#define DEFINE_LIST(name, type)
implementation of Agrec_t