49 sp->
data = (gv_stack_t){0};
81 while ((n =
pop(stk))) {
85 if ((other =
agtail(e)) == n)
111 if (v < 0)
return ND_mark(n) != 0;
266#define GRECNAME "ccgraphinfo"
267#define NRECNAME "ccgnodeinfo"
268#define GD_cc_subg(g) (((ccgraphinfo_t*)aggetrec(g, GRECNAME, 0))->cc_subg)
276 fprintf (stderr,
"nodeinfo undefined\n");
285#define dnodeOf(v) (((ccgnodeinfo_t*)aggetrec(v, NRECNAME, 0))->ptr.n)
286#define dnodeSet(v,w) (((ccgnodeinfo_t*)aggetrec(v, NRECNAME, 0))->ptr.n=w)
289#define ptrOf(np) (((ccgnodeinfo_t*)((np)->base.data))->ptr.v)
290#define nodeOf(np) (((ccgnodeinfo_t*)((np)->base.data))->ptr.n)
291#define clustOf(np) (((ccgnodeinfo_t*)((np)->base.data))->ptr.g)
292#define clMark(n) (((ccgnodeinfo_t*)(n->base.data))->mark)
312 fprintf (stderr,
"Error: node \"%s\" belongs to two non-nested clusters \"%s\" and \"%s\"\n",
389 if (v < 0)
return clMark(n) != 0;
400#define ORIG_REC "orig"
433 if (!proj && inCluster) {
462 if ((proj =
projectG(subg, g, inCluster))) {
486 size_t n_cnt, c_cnt, e_cnt;
507 size_t ccs_length = (size_t)
agnnodes(dg);
517 char *name_str =
agxbuse(&name);
518 dout =
agsubg(dg, name_str, 1);
522 n_cnt =
dfs(dg, dn, dout, &stk);
540 " edges\n", c_cnt, n_cnt, e_cnt);
545 fprintf(stderr,
" %7d nodes %7d edges %7" PRISIZE_T " components %s\n",
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 size_t agxbput(agxbuf *xb, const char *s)
append string s into xb
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static char * agxbuse(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
static void * gv_calloc(size_t nmemb, size_t size)
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 int isLegal(const char *p)
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 void initStk(stk_t *sp, void(*actionfn)(Agnode_t *, void *), bool(*markfn)(Agnode_t *, int))
Agraph_t * mapClust(Agraph_t *cl)
support for connected components
#define PRISIZE_T
PRIu64 alike for printing size_t
Implementation of a dynamically expanding stack data structure.
static void stack_push(gv_stack_t *stack, void *item)
static void * stack_pop(gv_stack_t *stack)
static void stack_reset(gv_stack_t *stack)
static bool stack_is_empty(const gv_stack_t *stack)
implementation of Agrec_t
union ccgnodeinfo_t::@103 ptr
void(* actionfn)(Agnode_t *, void *)
bool(* markfn)(Agnode_t *, int)