37#define ON_STACK(ninfo, n) (ninfo[AGSEQ(n)].on_stack)
38#define DISTANCE(ninfo, n) (ninfo[AGSEQ(n)].dist)
39#define agrootof(n) ((n)->root)
41static unsigned char uchar_min(
unsigned char a,
unsigned char b) {
115 gv_stack_t estk = {0};
116 push(&estk, &dummy.
out, ninfo);
119 while ((link =
top(&estk))) {
125 for (; next; next =
agnxtout(g, next)) {
135 "warning: %s has cycle(s), transitive reduction not unique\n",
137 fprintf(
opts->err,
"cycle involves edge %s -> %s\n",
agnameof(v),
141 }
else if (
DISTANCE(ninfo, hd) == 0) {
144 }
else if (
DISTANCE(ninfo, hd) == 1) {
149 push(&estk, next, ninfo);
156 for (e =
agfstout(g, n); e; e = f) {
169 fprintf(
opts->err,
"removed edge: %s: \"%s\" -> \"%s\"\n",
agnameof(g),
186 time_t total_secs = 0;
194 fprintf(stderr,
"Processing graph %s\n",
agnameof(g));
196 memset(ninfo, 0, infosize);
197 const time_t start = time(
NULL);
198 warn =
dfs(n, ninfo, warn,
opts);
200 secs = time(
NULL) - start;
204 fprintf(
opts->err,
"[%d]\n",
cnt);
209 fprintf(
opts->err,
"Finished graph %s: %lld.00 secs.\n",
agnameof(g),
210 (
long long)total_secs);
Memory allocation wrappers that exit on failure.
static void * gv_alloc(size_t size)
static int cnt(Dict_t *d, Dtlink_t **set)
int agnnodes(Agraph_t *g)
void graphviz_tred(Agraph_t *g, const graphviz_tred_options_t *opts)
programmatic access to tred - transitive reduction
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
int agwrite(Agraph_t *g, void *chan)
Return 0 on success, EOF on failure.
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
char * agnameof(void *)
returns a string descriptor for the object.
int agdelete(Agraph_t *g, void *obj)
deletes object. Equivalent to agclose, agdelnode, and agdeledge for obj being a graph,...
static Agedge_t * top(gv_stack_t *sp)
static int dfs(Agnode_t *n, nodeinfo_t *ninfo, int warn, const graphviz_tred_options_t *opts)
static unsigned char uchar_min(unsigned char a, unsigned char b)
static void push(gv_stack_t *sp, Agedge_t *ep, nodeinfo_t *ninfo)
#define ON_STACK(ninfo, n)
#define DISTANCE(ninfo, n)
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_top(gv_stack_t *stack)
static void stack_reset(gv_stack_t *stack)
static bool stack_is_empty(const gv_stack_t *stack)
Agtag_t tag
access with AGTAG
unsigned objtype
access with AGTYPE
options for passing to graphviz_tred