43 sp->
data = (node_stack_t){0};
52 node_stack_push_back(&sp->
data, np);
56 if (node_stack_is_empty(&sp->
data)) {
60 return node_stack_pop_back(&sp->
data);
69 while ((n =
pop(stk))) {
74 if ((other =
agtail(e)) == n)
153 Agraphs_append(&ccs,
out);
169 Agraphs_append(&ccs,
out);
173 *ncc = Agraphs_size(&ccs);
175 return Agraphs_detach(&ccs);
212 Agraphs_append(&ccs,
out);
216 *ncc = Agraphs_size(&ccs);
217 return Agraphs_detach(&ccs);
235#define GRECNAME "ccgraphinfo"
236#define NRECNAME "ccgnodeinfo"
237#define GD_cc_subg(g) (((ccgraphinfo_t *)aggetrec(g, GRECNAME, 0))->cc_subg)
243 fprintf(stderr,
"nodeinfo undefined\n");
250#define dnodeOf(v) (((ccgnodeinfo_t *)aggetrec(v, NRECNAME, 0))->ptr.n)
251#define dnodeSet(v, w) (((ccgnodeinfo_t *)aggetrec(v, NRECNAME, 0))->ptr.n = w)
254#define ptrOf(np) (((ccgnodeinfo_t *)((np)->base.data))->ptr.v)
255#define nodeOf(np) (((ccgnodeinfo_t *)((np)->base.data))->ptr.n)
256#define clustOf(np) (((ccgnodeinfo_t *)((np)->base.data))->ptr.g)
257#define clMark(n) (((ccgnodeinfo_t *)(n->base.data))->mark)
277 "Error: node \"%s\" belongs to two non-nested clusters "
278 "\"%s\" and \"%s\"\n",
364#define ORIG_REC "orig"
394 if (!proj && inCluster) {
421 if ((proj =
projectG(subg, g, inCluster))) {
462 size_t ccs_length = (size_t)
agnnodes(dg);
464 Agraphs_reserve(&ccs, ccs_length);
472 char *name_str =
agxbuse(&name);
473 dout =
agsubg(dg, name_str, 1);
477 n_cnt =
dfs(dg, dn, dout, &stk);
481 Agraphs_append(&ccs,
out);
486 Agraphs_size(&ccs) - 1, n_cnt, e_cnt);
491 " %7d nodes %7d edges %7" PRISIZE_T " components %s\n",
499 *ncc = Agraphs_size(&ccs);
500 return Agraphs_detach(&ccs);
static void out(agerrlevel_t level, const char *fmt, va_list args)
Report messages using a user-supplied or default write function.
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)
Memory allocation wrappers that exit on failure.
abstract graph C library, Cgraph API
bool is_a_cluster(Agraph_t *g)
static int cnt(Dict_t *d, Dtlink_t **set)
int agnedges(Agraph_t *g)
int agnnodes(Agraph_t *g)
size_t graphviz_node_induce(Agraph_t *g, Agraph_t *edgeset)
int agcopyattr(void *oldobj, void *newobj)
copies all of the attributes from one object to another
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
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
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.
#define AGTYPE(obj)
returns AGRAPH, AGNODE, or AGEDGE depending on the type of the object
int agdelete(Agraph_t *g, void *obj)
deletes object. Equivalent to agclose, agdelnode, and agdeledge for obj being a graph,...
Agrec_t * aggetrec(void *obj, const char *name, int move_to_front)
find record in circular list and do optional move-to-front and lock
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
void agclean(Agraph_t *g, int kind, char *rec_name)
calls agdelrec for all objects of the same class in an entire graph
Agraph_t * agfstsubg(Agraph_t *g)
Agraph_t * agnxtsubg(Agraph_t *subg)
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
replacements for ctype.h functions
static bool gv_isalnum(int c)
static void unmark(const stk_t *stk, Agnode_t *n)
unset a mark on n
static bool marked(const stk_t *stk, Agnode_t *n)
does n have a mark set?
static void freeStk(stk_t *sp)
Agraph_t ** pccomps(Agraph_t *g, size_t *ncc, char *pfx, bool *pinned)
static void setPrefix(agxbuf *xb, const char *pfx)
static void mark(const stk_t *stk, Agnode_t *n)
set a mark on n
static void insertFn(Agnode_t *n, void *state)
static bool markFn(Agnode_t *n, int v)
Agraph_t ** ccomps(Agraph_t *g, size_t *ncc, char *pfx)
int isConnected(Agraph_t *g)
Agraph_t ** cccomps(Agraph_t *g, size_t *ncc, char *pfx)
static bool clMarkFn(Agnode_t *n, int v)
static bool isLegal(const char *p)
static void initStk(stk_t *sp, void(*actionfn)(Agnode_t *, void *), bool(*markfn)(Agnode_t *, int))
Agraph_t * mapClust(Agraph_t *cl)
#define DEFINE_LIST(name, type)
support for connected components
#define PRISIZE_T
PRIu64 alike for printing size_t
implementation of Agrec_t
union ccgnodeinfo_t::@100 ptr
void(* actionfn)(Agnode_t *, void *)
bool(* markfn)(Agnode_t *, int)