Graphviz  2.39.20141222.0545
dot.c
Go to the documentation of this file.
1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 /*
15  * Written by Stephen North and Eleftherios Koutsofios.
16  */
17 
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 
22 #include "gvc.h"
23 #include "gvio.h"
24 
25 #ifdef WIN32_DLL
26 __declspec(dllimport) boolean MemTest;
27 __declspec(dllimport) int GvExitOnUsage;
28 /*gvc.lib cgraph.lib*/
29  #pragma comment( lib, "cgraph.lib" )
30  #pragma comment( lib, "gvc.lib" )
31 #else /* not WIN32_DLL */
32 #include "globals.h"
33 #endif
34 
35 #include <stdlib.h>
36 #include <time.h>
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40 
41 #if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
42 /* _GNU_SOURCE is needed for feenableexcept to be defined in fenv.h on GNU
43  * systems. Presumably it will do no harm on other systems. */
44 #ifndef _GNU_SOURCE
45 #define _GNU_SOURCE
46 #endif
47 # include <fenv.h>
48 #elif HAVE_FPU_CONTROL_H
49 # include <fpu_control.h>
50 #elif HAVE_SYS_FPU_H
51 # include <sys/fpu.h>
52 #endif
53 
54 static GVC_t *Gvc;
55 static graph_t * G;
56 
57 #ifndef WIN32
58 static void intr(int s)
59 {
60 /* if interrupted we try to produce a partial rendering before exiting */
61  if (G)
62  gvRenderJobs(Gvc, G);
63 /* Note that we don't call gvFinalize() so that we don't start event-driven
64  * devices like -Tgtk or -Txlib */
65  exit (gvFreeContext(Gvc));
66 }
67 
68 #ifndef NO_FPERR
69 static void fperr(int s)
70 {
71  fprintf(stderr, "caught SIGFPE %d\n", s);
72  /* signal (s, SIG_DFL); raise (s); */
73  exit(1);
74 }
75 
76 static void fpinit(void)
77 {
78 #if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
79  int exc = 0;
80 # ifdef FE_DIVBYZERO
81  exc |= FE_DIVBYZERO;
82 # endif
83 # ifdef FE_OVERFLOW
84  exc |= FE_OVERFLOW;
85 # endif
86 # ifdef FE_INVALID
87  exc |= FE_INVALID;
88 # endif
89  feenableexcept(exc);
90 
91 #ifdef HAVE_FESETENV
92 #ifdef FE_NONIEEE_ENV
93  fesetenv (FE_NONIEEE_ENV);
94 #endif
95 #endif
96 
97 #elif HAVE_FPU_CONTROL_H
98  /* On s390-ibm-linux, the header exists, but the definitions
99  * of the masks do not. I assume this is temporary, but until
100  * there's a real implementation, it's probably safest to not
101  * adjust the FPU on this platform.
102  */
103 # if defined(_FPU_MASK_IM) && defined(_FPU_MASK_DM) && defined(_FPU_MASK_ZM) && defined(_FPU_GETCW)
104  fpu_control_t fpe_flags = 0;
105  _FPU_GETCW(fpe_flags);
106  fpe_flags &= ~_FPU_MASK_IM; /* invalid operation */
107  fpe_flags &= ~_FPU_MASK_DM; /* denormalized operand */
108  fpe_flags &= ~_FPU_MASK_ZM; /* zero-divide */
109  /*fpe_flags &= ~_FPU_MASK_OM; overflow */
110  /*fpe_flags &= ~_FPU_MASK_UM; underflow */
111  /*fpe_flags &= ~_FPU_MASK_PM; precision (inexact result) */
112  _FPU_SETCW(fpe_flags);
113 # endif
114 #endif
115 }
116 #endif
117 #endif
118 
119 static graph_t *create_test_graph(void)
120 {
121 #define NUMNODES 5
122 
124  Agedge_t *e;
125  Agraph_t *g;
126  Agraph_t *sg;
127  int j, k;
128  char name[10];
129 
130  /* Create a new graph */
131  g = agopen("new_graph", Agdirected,NIL(Agdisc_t *));
132 
133  /* Add nodes */
134  for (j = 0; j < NUMNODES; j++) {
135  sprintf(name, "%d", j);
136  node[j] = agnode(g, name, 1);
137  agbindrec(node[j], "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data
138  }
139 
140  /* Connect nodes */
141  for (j = 0; j < NUMNODES; j++) {
142  for (k = j + 1; k < NUMNODES; k++) {
143  e = agedge(g, node[j], node[k], NULL, 1);
144  agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //edge custom data
145  }
146  }
147  sg = agsubg (g, "cluster1", 1);
148  agsubnode (sg, node[0], 1);
149 
150  return g;
151 }
152 
153 int main(int argc, char **argv)
154 {
155  graph_t *prev = NULL;
156  int r, rc = 0;
157 
158  Gvc = gvContextPlugins(lt_preloaded_symbols, DEMAND_LOADING);
159  GvExitOnUsage = 1;
160  gvParseArgs(Gvc, argc, argv);
161 #ifndef WIN32
162  signal(SIGUSR1, gvToggle);
163  signal(SIGINT, intr);
164 #ifndef NO_FPERR
165  fpinit();
166  signal(SIGFPE, fperr);
167 #endif
168 #endif
169 
170  if (MemTest) {
171  while (MemTest--) {
172  /* Create a test graph */
173  G = create_test_graph();
174 
175  /* Perform layout and cleanup */
176  gvLayoutJobs(Gvc, G); /* take layout engine from command line */
177  gvFreeLayout(Gvc, G);
178  agclose (G);
179  }
180  }
181  else if ((G = gvPluginsGraph(Gvc))) {
182  gvLayoutJobs(Gvc, G); /* take layout engine from command line */
183  gvRenderJobs(Gvc, G);
184  }
185  else {
186  while ((G = gvNextInputGraph(Gvc))) {
187  if (prev) {
188  gvFreeLayout(Gvc, prev);
189  agclose(prev);
190  }
191  gvLayoutJobs(Gvc, G); /* take layout engine from command line */
192  gvRenderJobs(Gvc, G);
193  r = agreseterrors();
194  rc = MAX(rc,r);
195  prev = G;
196  }
197  }
198  gvFinalize(Gvc);
199 
200  r = gvFreeContext(Gvc);
201  return (MAX(rc,r));
202 }
#define MAX(a, b)
Definition: agerror.c:17
int gvParseArgs(GVC_t *gvc, int argc, char **argv)
Definition: args.c:272
int agreseterrors()
Definition: agerror.c:168
unsigned char boolean
Definition: types.h:25
graph_t * gvPluginsGraph(GVC_t *gvc)
Definition: input.c:212
EXTERN int GvExitOnUsage
Definition: globals.h:94
int agclose(Agraph_t *g)
Definition: graph.c:93
int gvRenderJobs(GVC_t *gvc, graph_t *g)
Definition: emit.c:4005
int gvFreeLayout(GVC_t *gvc, graph_t *g)
Definition: gvlayout.c:102
void gvFinalize(GVC_t *gvc)
Definition: gvcontext.c:67
Agnode_t * agsubnode(Agraph_t *g, Agnode_t *n, int createflag)
Definition: node.c:254
EXTERN int MemTest
Definition: globals.h:75
Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
Definition: node.c:142
graph_t * gvNextInputGraph(GVC_t *gvc)
Definition: input.c:532
int gvLayoutJobs(GVC_t *gvc, graph_t *g)
Definition: gvlayout.c:56
#define NIL(t)
Definition: dthdr.h:20
lt_symlist_t lt_preloaded_symbols[]
Definition: dot_builtins.c:38
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition: subg.c:52
Definition: gvcint.h:70
Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
Definition: graph.c:44
void gvToggle(int s)
Definition: utils.c:608
GVC_t * gvContextPlugins(const lt_symlist_t *builtins, int demand_loading)
Definition: gvc.c:48
Agdesc_t Agdirected
Definition: graph.c:276
Definition: grammar.c:79
#define NULL
Definition: logic.h:50
Agnode_t * node(Agraph_t *g, char *name)
Definition: gv.cpp:103
int gvFreeContext(GVC_t *gvc)
Definition: gvcontext.c:74
#define NUMNODES
void * agbindrec(void *obj, char *name, unsigned int size, int move_to_front)
Definition: rec.c:86
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Definition: edge.c:281
int main(int argc, char **argv)
Definition: dot.c:153
#define TRUE
Definition: cgraph.h:27