48#define GD_cc_subg(g) (((graphinfo_t*)(g->base.data))->cc_subg)
49#define Node_mark(n) (((nodeinfo_t*)(n->base.data))->mark)
50#define ND_ptr(n) (((nodeinfo_t*)(n->base.data))->ptr)
51#define ND_dn(n) ((Agnode_t*)ND_ptr(n))
52#define Node_clust(n) ((Agraph_t*)ND_ptr(n))
91 "Usage: ccomps [-svenCx?] [-X[#%]s[-f]] [-o<out template>] <files>\n\
94 -X - extract component\n\
96 -e - do not induce edges\n\
97 -n - do not induce subgraphs\n\
99 -o - output file template\n\
100 -z - sort by size, largest first\n\
102If no files are specified, stdin is used\n";
104static void usage(
int v)
110static void split(
void) {
116 size_t size = (size_t)(sfx -
outfile);
123static void init(
int argc,
char *argv[])
130 while ((c = getopt(argc, argv,
":zo:xCX:nesv?")) != -1) {
152 if (*optarg ==
'#' || *optarg ==
'%') {
153 char *p = optarg + 1;
157 x_index = (int)strtol (p, &endp, 10);
166 "ccomps: final index %d < start index %d in -X%s flag - ignored\n",
173 "ccomps: number expected in -X%s flag - ignored\n",
181 "ccomps: number expected in -X%s flag - ignored\n",
196 "ccomps: option -%c missing argument - ignored\n", optopt);
199 if (optopt ==
'\0' || optopt ==
'?')
203 "ccomps: option -%c unrecognized\n", optopt);
254 while ((n =
pop())) {
259 if ((other =
agtail(e)) == n)
294 outf = fopen(name,
"w");
296 fprintf(stderr,
"Could not open %s for writing\n", name);
327 if (!proj && inCluster) {
352 if ((proj =
projectG(subg, g, inCluster))) {
366#define PFX2 "%s_cc_%ld"
386 fprintf (stderr,
"Error: node \"%s\" belongs to two non-nested clusters \"%s\" and \"%s\"\n",
460static int cmp(
const void *x,
const void *y) {
465#pragma GCC diagnostic push
466#pragma GCC diagnostic ignored "-Wcast-qual"
471#pragma GCC diagnostic pop
502 "ccomps: component %d not found in graph %s - ignored\n",
509 if (endi >= c_cnt) endi = c_cnt-1;
523 for (i = 0; i < c_cnt ; i++) {
534 else for (i = 0; i < c_cnt; i++) {
561 fprintf(stderr,
"ccomps: node %s not found in graph %s\n",
569 dout =
agsubg(dg, name, 1);
576 n_cnt =
dfs(dg, dn, dout);
585 fprintf(stderr,
" %7ld nodes %7" PRISIZE_T " edges\n", n_cnt,
598 dout =
agsubg(dg, name, 1);
604 n_cnt =
dfs(dg, dn, dout);
638 fprintf(stderr,
"(%4ld) %7ld nodes %7" PRISIZE_T " edges\n",
639 c_cnt, n_cnt, e_cnt);
644 "ccomps: component %d not found in graph %s - ignored\n",
655 fprintf(stderr,
" %7d nodes %7d edges %7ld components %s\n",
660 return (c_cnt ? 1 : 0);
694 "ccomps: node %s not found in graph %s - ignored\n",
714 fprintf(stderr,
" %7ld nodes %7" PRISIZE_T " edges\n", n_cnt,
763 fprintf(stderr,
"(%4ld) %7ld nodes %7" PRISIZE_T " edges\n",
764 c_cnt, n_cnt, e_cnt);
769 "ccomps: component %d not found in graph %s - ignored\n",
780 fprintf(stderr,
" %7d nodes %7d edges %7ld components %s\n",
802 if (*
s !=
'%')
return s;
808int main(
int argc,
char *argv[])
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)
static char * agxbdisown(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
static char * gv_strndup(const char *original, size_t length)
abstract graph C library, Cgraph API
bool is_a_cluster(Agraph_t *g)
static NORETURN void graphviz_exit(int status)
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
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.
#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,...
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 * 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_isdigit(int c)
static const char * usage
Agraph_t * nextGraph(ingraph_state *sp)
ingraph_state * newIngraph(ingraph_state *sp, char **files)
supports user-supplied data
#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)
a generic header of Agraph_s, Agnode_s and Agedge_s
implementation of Agrec_t