Graphviz 14.1.2~dev.20260118.1035
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 "config.h"
23
24#include <stdbool.h>
25#include <stdio.h>
26
27#include <stdlib.h>
28#include <cgraph/cgraph.h>
29#include "openFile.h"
30#include <util/exit.h>
31#include <util/prisize_t.h>
32#include <util/unreachable.h>
33
34#define graphName(g) (agnameof(g))
35
36#include <getopt.h>
37
38static FILE *inFile;
39
41
42static char *cmd;
43
44static char *useString = "Usage: %s [-nv?] [-o outfile] <file>\n\
45 -o <file> - put output in <file>\n\
46 -n - do not output graph\n\
47 -v - verbose\n\
48 -? - print usage\n";
49
50static void usage(int v)
51{
52 fprintf(stderr, useString, cmd);
54}
55
56static void init(opts_t *opts, int argc, char *argv[]) {
57 int c;
58
59 cmd = argv[0];
60 opterr = 0;
61 while ((c = getopt(argc, argv, ":vno:")) != -1)
62 switch (c) {
63 case 'o':
64 if (opts->outFile != NULL)
65 fclose(opts->outFile);
66 opts->outFile = openFile(argv[0], optarg, "w");
67 break;
68 case 'n':
69 opts->doWrite = false;
70 break;
71 case 'v':
72 opts->Verbose = true;
73 break;
74 case '?':
75 if (optopt == '?')
76 usage(0);
77 else {
78 fprintf(stderr, "%s: option -%c unrecognized\n", cmd,
79 optopt);
80 usage(-1);
81 }
82 break;
83 case ':':
84 fprintf(stderr, "%s: missing argument for option -%c\n",
85 cmd, optopt);
86 usage(-1);
87 break;
88 default:
90 }
91 if (optind < argc) {
92 inFile = openFile(argv[0], argv[optind], "r");
93 } else
94 inFile = stdin;
95 if (!opts->outFile)
96 opts->outFile = stdout;
97}
98
99int main(int argc, char *argv[])
100{
101 Agraph_t *g;
102 int rv = 0;
103 opts_t opts = {.doWrite = true};
104 size_t num_rev = 0;
105
106 init(&opts, argc, argv);
107
108 if ((g = agread(inFile, NULL)) != NULL) {
109 if (agisdirected (g)) {
110 rv |= graphviz_acyclic(g, &opts, &num_rev);
111 if (opts.Verbose) {
112 if (rv)
113 fprintf(stderr, "Graph \"%s\" has cycles; %" PRISIZE_T " reversed edges\n",
114 graphName(g), num_rev);
115 else
116 fprintf(stderr, "Graph \"%s\" is acyclic\n", graphName(g));
117 }
118 } else {
119 rv = -1;
120 if (opts.Verbose)
121 fprintf(stderr, "Graph \"%s\" is undirected\n", graphName(g));
122 }
123 graphviz_exit(rv);
124 } else
125 graphviz_exit(-1);
126}
abstract graph C library, Cgraph API
static void init(opts_t *opts, int argc, char *argv[])
Definition acyclic.c:56
graphviz_acyclic_options_t opts_t
Definition acyclic.c:40
static char * cmd
Definition acyclic.c:42
static FILE * inFile
Definition acyclic.c:38
#define graphName(g)
Definition acyclic.c:34
static char * useString
Definition acyclic.c:44
static NORETURN void graphviz_exit(int status)
Definition exit.h:23
node NULL
Definition grammar.y:181
bool graphviz_acyclic(Agraph_t *g, const graphviz_acyclic_options_t *opts, size_t *num_rev)
Definition acyclic.c:88
int agisdirected(Agraph_t *g)
Definition graph.c:178
Agraph_t * agread(void *chan, Agdisc_t *disc)
constructs a new graph
Definition grammar.c:2052
static opts_t opts
Definition gvgen.c:415
static const char * usage
Definition gvpr.c:54
static FILE * openFile(const char *argv0, const char *name, const char *mode)
Definition openFile.h:8
#define PRISIZE_T
Definition prisize_t.h:25
graph or subgraph
Definition cgraph.h:424
options for passing to graphviz_acyclic
Definition cgraph.h:1012
int Verbose
Definition gvgen.c:45
int main()
#define UNREACHABLE()
Definition unreachable.h:30