Graphviz 2.29.20120208.0545
cmd/dot/dot.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 /*
00015  * Written by Stephen North and Eleftherios Koutsofios.
00016  */
00017 
00018 #ifdef HAVE_CONFIG_H
00019 #include "config.h"
00020 #endif
00021 
00022 #include "gvc.h"
00023 #include "gvio.h"
00024 
00025 #ifndef WIN32_DLL
00026 #ifdef GVDLL
00027 __declspec(dllimport) boolean MemTest;
00028 #else
00029 #include "globals.h"
00030 #endif
00031 #endif
00032 
00033 #ifdef WIN32_DLL
00034 __declspec(dllimport) boolean MemTest;
00035 /*gvc.lib cgraph.lib*/
00036 #ifdef WITH_CGRAPH
00037     #pragma comment( lib, "cgraph.lib" )
00038 #else
00039     #pragma comment( lib, "graph.lib" )
00040 #endif
00041     #pragma comment( lib, "gvc.lib" )
00042 #endif
00043 
00044 #include <stdlib.h>
00045 #include <time.h>
00046 #ifdef HAVE_UNISTD_H
00047 #include <unistd.h>
00048 #endif
00049 
00050 #if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
00051 /* _GNU_SOURCE is needed for feenableexcept to be defined in fenv.h on GNU
00052  * systems.   Presumably it will do no harm on other systems. */
00053 #ifndef _GNU_SOURCE
00054 #define _GNU_SOURCE
00055 #endif
00056 # include <fenv.h>
00057 #elif HAVE_FPU_CONTROL_H
00058 # include <fpu_control.h>
00059 #elif HAVE_SYS_FPU_H
00060 # include <sys/fpu.h>
00061 #endif
00062 
00063 static GVC_t *Gvc;
00064 static graph_t * G;
00065 
00066 #ifndef WIN32
00067 static void intr(int s)
00068 {
00069 /* if interrupted we try to produce a partial rendering before exiting */
00070     if (G)
00071         gvRenderJobs(Gvc, G);
00072 /* Note that we don't call gvFinalize() so that we don't start event-driven
00073  * devices like -Tgtk or -Txlib */
00074     exit (gvFreeContext(Gvc));
00075 }
00076 
00077 #ifndef NO_FPERR
00078 static void fperr(int s)
00079 {
00080     fprintf(stderr, "caught SIGFPE %d\n", s);
00081     /* signal (s, SIG_DFL); raise (s); */
00082     exit(1);
00083 }
00084 
00085 static void fpinit(void)
00086 {
00087 #if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
00088     int exc = 0;
00089 # ifdef FE_DIVBYZERO
00090     exc |= FE_DIVBYZERO;
00091 # endif
00092 # ifdef FE_OVERFLOW
00093     exc |= FE_OVERFLOW;
00094 # endif
00095 # ifdef FE_INVALID
00096     exc |= FE_INVALID;
00097 # endif
00098     feenableexcept(exc);
00099 
00100 #ifdef HAVE_FESETENV
00101 #ifdef FE_NONIEEE_ENV
00102     fesetenv (FE_NONIEEE_ENV);
00103 #endif
00104 #endif
00105 
00106 #elif  HAVE_FPU_CONTROL_H
00107     /* On s390-ibm-linux, the header exists, but the definitions
00108      * of the masks do not.  I assume this is temporary, but until
00109      * there's a real implementation, it's probably safest to not
00110      * adjust the FPU on this platform.
00111      */
00112 # if defined(_FPU_MASK_IM) && defined(_FPU_MASK_DM) && defined(_FPU_MASK_ZM) && defined(_FPU_GETCW)
00113     fpu_control_t fpe_flags = 0;
00114     _FPU_GETCW(fpe_flags);
00115     fpe_flags &= ~_FPU_MASK_IM; /* invalid operation */
00116     fpe_flags &= ~_FPU_MASK_DM; /* denormalized operand */
00117     fpe_flags &= ~_FPU_MASK_ZM; /* zero-divide */
00118     /*fpe_flags &= ~_FPU_MASK_OM;        overflow */
00119     /*fpe_flags &= ~_FPU_MASK_UM;        underflow */
00120     /*fpe_flags &= ~_FPU_MASK_PM;        precision (inexact result) */
00121     _FPU_SETCW(fpe_flags);
00122 # endif
00123 #endif
00124 }
00125 #endif
00126 #endif
00127 
00128 static graph_t *create_test_graph(void)
00129 {
00130 #define NUMNODES 5
00131 
00132     Agnode_t *node[NUMNODES];
00133     Agraph_t *g;
00134     Agraph_t *sg;
00135     int j, k;
00136     char name[10];
00137 
00138     /* Create a new graph */
00139 #ifndef WITH_CGRAPH
00140     aginit();
00141     agsetiodisc(NULL, gvfwrite, gvferror);
00142     g = agopen("new_graph", AGDIGRAPH);
00143 #else /* WITH_CGRAPH */
00144     g = agopen("new_graph", Agdirected,NIL(Agdisc_t *));
00145 #endif /* WITH_CGRAPH */
00146 
00147     /* Add nodes */
00148     for (j = 0; j < NUMNODES; j++) {
00149         sprintf(name, "%d", j);
00150 #ifndef WITH_CGRAPH
00151         node[j] = agnode(g, name);
00152 #else /* WITH_CGRAPH */
00153         node[j] = agnode(g, name, 1);
00154         agbindrec(node[j], "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data
00155 
00156 #endif /* WITH_CGRAPH */
00157     }
00158 
00159     /* Connect nodes */
00160     for (j = 0; j < NUMNODES; j++) {
00161         for (k = j + 1; k < NUMNODES; k++) {
00162 #ifndef WITH_CGRAPH
00163             agedge(g, node[j], node[k]);
00164 #else /* WITH_CGRAPH */
00165             agedge(g, node[j], node[k], NULL, 1);
00166 #endif /* WITH_CGRAPH */
00167         }
00168     }
00169 
00170 #ifndef WITH_CGRAPH
00171     sg = agsubg (g, "cluster1");
00172     aginsert (sg, node[0]);
00173 #else /* WITH_CGRAPH */
00174     sg = agsubg (g, "cluster1", 1);
00175     agsubnode (sg, node[0], 1);
00176 #endif /* WITH_CGRAPH */
00177 
00178     return g;
00179 }
00180 
00181 int main(int argc, char **argv)
00182 {
00183     graph_t *prev = NULL;
00184     int r, rc = 0;
00185 #ifndef WITH_CGRAPH
00186 #endif /* WITH_CGRAPH */
00187 
00188     Gvc = gvContextPlugins(lt_preloaded_symbols, DEMAND_LOADING);
00189     GvExitOnUsage = 1;
00190     gvParseArgs(Gvc, argc, argv);
00191 #ifndef WIN32
00192     signal(SIGUSR1, gvToggle);
00193     signal(SIGINT, intr);
00194 #ifndef NO_FPERR
00195     fpinit();
00196     signal(SIGFPE, fperr);
00197 #endif
00198 #endif
00199 
00200     if (MemTest) {
00201         while (MemTest--) {
00202             /* Create a test graph */
00203             G = create_test_graph();
00204 
00205             /* Perform layout and cleanup */
00206             gvLayoutJobs(Gvc, G);  /* take layout engine from command line */
00207             gvFreeLayout(Gvc, G);
00208             agclose (G);
00209         }
00210     }
00211     else if ((G = gvPluginsGraph(Gvc))) {
00212             gvLayoutJobs(Gvc, G);  /* take layout engine from command line */
00213             gvRenderJobs(Gvc, G);
00214     }
00215     else {
00216         while ((G = gvNextInputGraph(Gvc))) {
00217 #ifdef WITH_CGRAPH
00218 
00219 
00220 #endif /* WITH_CGRAPH */
00221             if (prev) {
00222                 gvFreeLayout(Gvc, prev);
00223                 agclose(prev);
00224             }
00225             gvLayoutJobs(Gvc, G);  /* take layout engine from command line */
00226             gvRenderJobs(Gvc, G);
00227             r = agreseterrors();
00228             rc = MAX(rc,r);
00229             prev = G;
00230         }
00231     }
00232     gvFinalize(Gvc);
00233     
00234 
00235     r = gvFreeContext(Gvc);
00236     return (MAX(rc,r));
00237 }