Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
gvtool_tred.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11
12/*
13 * Written by Stephen North
14 * Updated by Emden Gansner
15 * Adapted to gvToolTred(g) by John Ellson
16 */
17
18/*
19 * performs an inplace transitive reduction on a graph
20 */
21
22#include "config.h"
23#include <stdio.h>
24#include <cgraph/cgraph.h>
25#include <gvc/gvc.h>
26
27typedef struct {
29 int mark;
31
32#define MARK(n) (((Agmarknodeinfo_t*)(n->base.data))->mark)
33
34#define agrootof(n) ((n)->root)
35
36static int dfs(Agnode_t * n, Agedge_t * link, int warn)
37{
38 Agedge_t *e;
39 Agedge_t *f;
40 Agraph_t *g = agrootof(n);
41
42 MARK(n) = 1;
43
44 for (e = agfstin(g, n); e; e = f) {
45 f = agnxtin(g, e);
46 if (e == link)
47 continue;
48 if (MARK(agtail(e)))
49 agdelete(g, e);
50 }
51
52 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
53 if (MARK(aghead(e))) {
54 if (!warn) {
55 warn++;
56 fprintf(stderr,
57 "warning: %s has cycle(s), transitive reduction not unique\n",
58 agnameof(g));
59 fprintf(stderr, "cycle involves edge %s -> %s\n",
61 }
62 } else
63 warn = dfs(aghead(e), AGOUT2IN(e), warn);
64 }
65
66 MARK(n) = 0;
67 return warn;
68}
69
71{
72 Agnode_t *n;
73 int warn = 0;
74
75 if (agisdirected(g)) {
76 aginit(g, AGNODE, "info", sizeof(Agmarknodeinfo_t), true);
77 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
78 warn = dfs(n, NULL, warn);
79 }
80 agclean(g, AGNODE, "info");
81 } else {
82 fprintf(stderr, "warning: %s is not a directed graph, not attempting tred\n",
83 agnameof(g));
84 }
85 return 0; // FIXME - return proper errors
86}
abstract graph C library, Cgraph API
node NULL
Definition grammar.y:163
Agedge_t * agnxtin(Agraph_t *g, Agedge_t *e)
Definition edge.c:69
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:24
#define agtail(e)
Definition cgraph.h:880
#define aghead(e)
Definition cgraph.h:881
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:39
Agedge_t * agfstin(Agraph_t *g, Agnode_t *n)
Definition edge.c:55
#define AGOUT2IN(outedge)
Agedgepair_s.out -> Agedgepair_s.in/*#end#*‍/.
Definition cgraph.h:870
int agisdirected(Agraph_t *g)
Definition graph.c:190
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:158
int agdelete(Agraph_t *g, void *obj)
deletes object. Equivalent to agclose, agdelnode, and agdeledge for obj being a graph,...
Definition obj.c:20
@ AGNODE
Definition cgraph.h:207
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
Definition rec.c:170
void agclean(Agraph_t *g, int kind, char *rec_name)
calls agdelrec for all objects of the same class in an entire graph
Definition rec.c:202
int gvToolTred(Agraph_t *g)
Definition gvtool_tred.c:70
Graphviz context library.
static int dfs(Agnode_t *n, Agedge_t *link, int warn)
Definition gvtool_tred.c:36
#define agrootof(n)
Definition gvtool_tred.c:34
#define MARK(n)
Definition gvtool_tred.c:32
graph or subgraph
Definition cgraph.h:425
implementation of Agrec_t
Definition cgraph.h:172