Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
acyclic.c
Go to the documentation of this file.
1
6/*************************************************************************
7 * Copyright (c) 2011 AT&T Intellectual Property
8 * All rights reserved. This program and the accompanying materials
9 * are made available under the terms of the Eclipse Public License v1.0
10 * which accompanies this distribution, and is available at
11 * https://www.eclipse.org/legal/epl-v10.html
12 *
13 * Contributors: Details at https://graphviz.org
14 *************************************************************************/
15
16
17/*
18 * Written by Stephen North
19 * Updated by Emden Gansner
20 */
21
22#include <stdbool.h>
23#include <stdio.h>
24
25#include <stdlib.h>
26#include <cgraph/cgraph.h>
27#include "openFile.h"
28#include <util/exit.h>
29#include <util/prisize_t.h>
30#include <util/unreachable.h>
31
32#define graphName(g) (agnameof(g))
33
34#include <getopt.h>
35
36static FILE *inFile;
37
39
40static char *cmd;
41
42static char *useString = "Usage: %s [-nv?] [-o outfile] <file>\n\
43 -o <file> - put output in <file>\n\
44 -n - do not output graph\n\
45 -v - verbose\n\
46 -? - print usage\n";
47
48static void usage(int v)
49{
50 fprintf(stderr, useString, cmd);
52}
53
54static void init(opts_t *opts, int argc, char *argv[]) {
55 int c;
56
57 cmd = argv[0];
58 opterr = 0;
59 while ((c = getopt(argc, argv, ":vno:")) != -1)
60 switch (c) {
61 case 'o':
62 if (opts->outFile != NULL)
63 fclose(opts->outFile);
64 opts->outFile = openFile(argv[0], optarg, "w");
65 break;
66 case 'n':
67 opts->doWrite = false;
68 break;
69 case 'v':
70 opts->Verbose = true;
71 break;
72 case '?':
73 if (optopt == '?')
74 usage(0);
75 else {
76 fprintf(stderr, "%s: option -%c unrecognized\n", cmd,
77 optopt);
78 usage(-1);
79 }
80 break;
81 case ':':
82 fprintf(stderr, "%s: missing argument for option -%c\n",
83 cmd, optopt);
84 usage(-1);
85 break;
86 default:
88 }
89 if (optind < argc) {
90 inFile = openFile(argv[0], argv[optind], "r");
91 } else
92 inFile = stdin;
93 if (!opts->outFile)
94 opts->outFile = stdout;
95}
96
97int main(int argc, char *argv[])
98{
99 Agraph_t *g;
100 int rv = 0;
101 opts_t opts = {.doWrite = true};
102 size_t num_rev = 0;
103
104 init(&opts, argc, argv);
105
106 if ((g = agread(inFile, NULL)) != NULL) {
107 if (agisdirected (g)) {
108 rv |= graphviz_acyclic(g, &opts, &num_rev);
109 if (opts.Verbose) {
110 if (rv)
111 fprintf(stderr, "Graph \"%s\" has cycles; %" PRISIZE_T " reversed edges\n",
112 graphName(g), num_rev);
113 else
114 fprintf(stderr, "Graph \"%s\" is acyclic\n", graphName(g));
115 }
116 } else {
117 rv = -1;
118 if (opts.Verbose)
119 fprintf(stderr, "Graph \"%s\" is undirected\n", graphName(g));
120 }
121 graphviz_exit(rv);
122 } else
123 graphviz_exit(-1);
124}
abstract graph C library, Cgraph API
static void init(opts_t *opts, int argc, char *argv[])
Definition acyclic.c:54
graphviz_acyclic_options_t opts_t
Definition acyclic.c:38
static char * cmd
Definition acyclic.c:40
static FILE * inFile
Definition acyclic.c:36
#define graphName(g)
Definition acyclic.c:32
static char * useString
Definition acyclic.c:42
static NORETURN void graphviz_exit(int status)
Definition exit.h:23
node NULL
Definition grammar.y:163
bool graphviz_acyclic(Agraph_t *g, const graphviz_acyclic_options_t *opts, size_t *num_rev)
Definition acyclic.c:86
int agisdirected(Agraph_t *g)
Definition graph.c:190
Agraph_t * agread(void *chan, Agdisc_t *disc)
constructs a new graph
Definition grammar.c:2292
static opts_t opts
Definition gvgen.c:394
static const char * usage
Definition gvpr.c:51
static FILE * openFile(const char *argv0, const char *name, const char *mode)
Definition openFile.h:8
#define PRISIZE_T
PRIu64 alike for printing size_t
Definition prisize_t.h:27
graph or subgraph
Definition cgraph.h:425
options for passing to graphviz_acyclic
Definition cgraph.h:919
int Verbose
Definition gvgen.c:43
int main()
#define UNREACHABLE()
Definition unreachable.h:30