1
/* $Id: ccomps.c,v 1.5 2007/08/08 23:00:58 erg Exp $ $Revision: 1.5 $ */
1
/* $Id: ccomps.c,v 1.6 2008/01/09 20:50:35 erg Exp $ $Revision: 1.6 $ */
2
2
/* vim:set shiftwidth=4 ts=8: */
4
4
/**********************************************************
44
#define GD_cc_subg(g) (((Agraphinfo_t*)(g->base.data))->cc_subg)
45
#define ND_mark(n) (((Agnodeinfo_t*)(n->base.data))->mark)
46
#define ND_ptr(n) (((Agnodeinfo_t*)(n->base.data))->ptr)
47
#define ND_dn(n) ((Agnode_t*)ND_ptr(n))
48
#define ND_clust(n) ((Agraph_t*)ND_ptr(n))
49
#define agfindnode(G,N) (agnode(G, N, 0))
41
63
#define GD_cc_subg(g) (g)->u.cc_subg
42
64
#define ND_mark(n) (n)->u.mark
43
65
#define ND_ptr(n) (n)->u.ptr
67
#define agnameof(x) (agobjkind(x) == AGNODE ? ((Agnode_t*)(x))->name : ((Agraph_t*)(x))->name)
68
#define agtail(e) ((e)->tail)
69
#define aghead(e) ((e)->head)
45
72
#ifdef HAVE_GETOPT_H
46
73
#include <getopt.h>
117
142
static int isCluster(Agraph_t * g)
119
return (strncmp(g->name, "cluster", 7) == 0);
144
return (strncmp(agnameof(g), "cluster", 7) == 0);
122
147
static void init(int argc, char *argv[])
127
154
while ((c = getopt(argc, argv, ":o:xCX:nsv?")) != -1) {
214
agsubnode(out, n, 1);
186
216
aginsert(out, n);
187
218
for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) {
188
if ((other = e->tail) == n)
219
if ((other = agtail(e)) == n)
190
221
if (ND_mark(other) == 0)
191
222
cnt = dfs(g, other, out, cnt);
228
* Using the edge set of eg, add to g any edges
229
* with both endpoints in g.
196
231
static int nodeInduce(Agraph_t * g, Agraph_t * eg)
202
237
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
203
238
for (e = agfstout(eg, n); e; e = agnxtout(eg, e)) {
204
if (agcontains(g, e->head)) {
240
if (agsubnode(g, aghead(e), 0)) {
243
if (agcontains(g, aghead(e))) {
255
* Copy the attributes of g2 to g1.
257
static void copyAttr(Agraph_t * g1, Agraph_t * g2)
264
n = dtsize(dict->dict);
265
for (i = 0; i < n; i++) {
267
agxset(g1, a->index, agxget(g2, a->index));
272
295
* Return pointer to buffer containing at least n bytes.
306
329
for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) {
307
if ((m = agfindnode(g, n->name))) {
330
if ((m = agfindnode(g, agnameof(n)))) {
309
name = getBuf(strlen(subg->name) + pfxlen + 2);
310
sprintf(name, "%s_%s", subg->name, pfx);
332
name = getBuf(strlen(agnameof(subg)) + pfxlen + 2);
333
sprintf(name, "%s_%s", agnameof(subg), pfx);
335
proj = agsubg(g, name, 1);
311
337
proj = agsubg(g, name);
341
agsubnode(proj, m, 1);
313
343
aginsert(proj, m);
316
347
if (!proj && inCluster) {
317
name = getBuf(strlen(subg->name) + pfxlen + 2);
318
sprintf(name, "%s_%s", subg->name, pfx);
348
name = getBuf(strlen(agnameof(subg)) + pfxlen + 2);
349
sprintf(name, "%s_%s", agnameof(subg), pfx);
351
proj = agsubg(g, name, 1);
319
353
proj = agsubg(g, name);
322
357
nodeInduce(proj, subg);
323
copyAttr(proj, subg);
358
agcopyattr(subg, proj);
330
365
* Project subgraphs of root graph on subgraph.
331
366
* If non-empty, add to subgraph.
370
subgInduce(Agraph_t * root, Agraph_t * g, char *pfx, int pfxlen,
377
/* fprintf (stderr, "subgInduce %s inCluster %d\n", agnameof(root), inCluster); */
378
for (subg = agfstsubg(root); subg; subg = agnxtsubg(subg)) {
379
if (GD_cc_subg(subg))
381
if ((proj = projectG(subg, g, pfx, pfxlen, inCluster))) {
382
in_cluster = inCluster || (useClusters && isCluster(subg));
383
subgInduce(subg, proj, pfx, pfxlen, in_cluster);
389
subGInduce(Agraph_t* g, Agraph_t * out)
391
subgInduce(g, out, agnameof(out), strlen(agnameof(out)), 0);
334
395
subgInduce(Agraph_t * root, Agraph_t * g, char *pfx, int pfxlen,
363
426
* top-level nodes and there is an edge in dg if there is an edge in g
364
427
* between any nodes in the respective clusters.
430
static Agraph_t *deriveGraph(Agraph_t * g)
437
dg = agopen("dg", Agstrictundirected, (Agdisc_t *) 0);
439
for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) {
440
if (!strncmp(agnameof(subg), "cluster", 7)) {
441
dn = agnode(dg, agnameof(subg), 1);
442
ND_ptr(dn) = (Agobj_t*)subg;
443
for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) {
444
ND_ptr(n) = (Agobj_t*)dn;
449
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
452
dn = agnode(dg, agnameof(n), 1);
453
ND_ptr(dn) = (Agobj_t*)n;
454
ND_ptr(n) = (Agobj_t*)dn;
457
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
460
Agnode_t *tl = ND_dn(n);
461
for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
462
hd = ND_dn(aghead(e));
466
agedge(dg, tl, hd, 0, 1);
468
agedge(dg, hd, tl, 0, 1);
366
475
static Agraph_t *deriveGraph(Agraph_t * g)
391
500
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
392
501
if (ND_ptr(n).dn)
394
dn = agnode(dg, n->name);
503
dn = agnode(dg, agnameof(n));
395
504
ND_ptr(dn).clust = (Agraph_t *) n;
396
505
ND_ptr(n).dn = dn;
426
536
for (dn = agfstnode(dg); dn; dn = agnxtnode(dg, dn)) {
538
if (AGTYPE(ND_ptr(dn)) == AGNODE) {
539
agsubnode(g, ND_dn(dn), 1);
541
clust = ND_clust(dn);
542
for (n = agfstnode(clust); n; n = agnxtnode(clust, n))
427
546
clust = ND_ptr(dn).clust;
428
547
if (clust->tag == TAG_NODE) {
429
548
n = (Agnode_t *) clust;
454
574
n = agfindnode(g, x_node);
456
576
fprintf(stderr, "ccomps: node %s not found in graph %s\n",
577
x_node, agnameof(g));
460
name = getBuf(sizeof(PFX1) + strlen(g->name));
461
sprintf(name, PFX1, g->name);
580
name = getBuf(sizeof(PFX1) + strlen(agnameof(g)));
581
sprintf(name, PFX1, agnameof(g));
583
dout = agsubg(dg, name, 1);
584
out = agsubg(g, name, 1);
462
586
dout = agsubg(dg, name);
463
587
out = agsubg(g, name);
464
589
GD_cc_subg(out) = 1;
465
593
dn = ND_ptr(n).dn;
466
595
n_cnt = dfs(dg, dn, dout, 0);
467
596
unionNodes(dout, out);
468
597
e_cnt = nodeInduce(out, out->root);
470
602
subgInduce(g, out, out->name, strlen(out->name), 0);
473
606
fprintf(stderr, " %7ld nodes %7ld edges\n", n_cnt, e_cnt);
478
611
for (dn = agfstnode(dg); dn; dn = agnxtnode(dg, dn)) {
481
name = getBuf(sizeof(PFX2) + strlen(g->name) + 32);
482
sprintf(name, "%s_component_%ld", g->name, c_cnt);
614
name = getBuf(sizeof(PFX2) + strlen(agnameof(g)) + 32);
615
sprintf(name, "%s_component_%ld", agnameof(g), c_cnt);
617
dout = agsubg(dg, name, 1);
618
out = agsubg(g, name, 1);
483
620
dout = agsubg(dg, name);
484
621
out = agsubg(g, name);
485
623
GD_cc_subg(out) = 1;
486
624
n_cnt = dfs(dg, dn, dout, 0);
487
625
unionNodes(dout, out);
488
626
e_cnt = nodeInduce(out, out->root);
489
627
if (printMode == EXTERNAL) {
491
632
subgInduce(g, out, out->name, strlen(out->name), 0);
493
635
} else if (printMode == EXTRACT) {
494
636
if (x_index == c_cnt) {
496
641
subgInduce(g, out, out->name, strlen(out->name), 0);
520
666
fprintf(stderr, " %7d nodes %7d edges %7ld components %s\n",
521
agnnodes(g), agnedges(g), c_cnt, g->name);
667
agnnodes(g), agnedges(g), c_cnt, agnameof(g));
685
aginit(g, AGNODE, "nodeinfo", sizeof(Agnodeinfo_t), TRUE);
686
aginit(g, AGRAPH, "graphinfo", sizeof(Agraphinfo_t), TRUE);
539
690
return processClusters(g);
545
696
"ccomps: node %s not found in graph %s - ignored\n",
697
x_node, agnameof(g));
549
name = getBuf(sizeof(PFX1) + strlen(g->name));
550
sprintf(name, PFX1, g->name);
700
name = getBuf(sizeof(PFX1) + strlen(agnameof(g)));
701
sprintf(name, PFX1, agnameof(g));
703
out = agsubg(g, name, 1);
551
705
out = agsubg(g, name);
552
707
GD_cc_subg(out) = 1;
553
708
n_cnt = dfs(g, n, out, 0);
554
709
e_cnt = nodeInduce(out, out->root);
556
714
subgInduce(g, out, out->name, strlen(out->name), 0);
559
718
fprintf(stderr, " %7ld nodes %7ld edges\n", n_cnt, e_cnt);
564
723
for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
567
name = getBuf(sizeof(PFX2) + strlen(g->name) + 32);
568
sprintf(name, "%s_component_%ld", g->name, c_cnt);
726
name = getBuf(sizeof(PFX2) + strlen(agnameof(g)) + 32);
727
sprintf(name, "%s_component_%ld", agnameof(g), c_cnt);
729
out = agsubg(g, name, 1);
569
731
out = agsubg(g, name);
570
733
GD_cc_subg(out) = 1;
571
734
n_cnt = dfs(g, n, out, 0);
572
735
e_cnt = nodeInduce(out, out->root);
573
736
if (printMode == EXTERNAL) {
575
741
subgInduce(g, out, out->name, strlen(out->name), 0);
577
744
} else if (printMode == EXTRACT) {
578
745
if (x_index == c_cnt) {
580
750
subgInduce(g, out, out->name, strlen(out->name), 0);
603
774
fprintf(stderr, " %7d nodes %7d edges %7ld components %s\n",
604
agnnodes(g), agnedges(g), c_cnt, g->name);
775
agnnodes(g), agnedges(g), c_cnt, agnameof(g));
605
776
return (c_cnt ? 1 : 0);
780
static Agraph_t *gread(FILE * fp)
782
return agread(fp, (Agdisc_t *) 0);
608
786
int main(int argc, char *argv[])
614
792
init(argc, argv);
794
newIngraph(&ig, Files, gread);
615
796
newIngraph(&ig, Files, agread);
617
799
while ((g = nextGraph(&ig)) != 0) {