txt_DATA = $(txt)
html_DATA = $(html)
-#SUBDIRS = libltdl lib plugin cmd tclpkg doc contrib graphs
-SUBDIRS = lib plugin cmd tclpkg doc contrib graphs
+# $(subdirs) contains the list from: AC_CONFIG_SUBDIRS
+SUBDIRS = $(subdirs) lib plugin cmd tclpkg doc contrib graphs
doxygen:
doxygen
dot_SOURCES = dot.c args.c
+if ENABLE_LTDL
+dot_LDADD = \
+ $(top_builddir)/lib/graph/libgraph.la \
+ $(top_builddir)/lib/common/libcommon.la \
+ $(top_builddir)/lib/gvc/libgvc.la @LIBGEN_LIBS@
+else
dot_LDADD = \
$(top_builddir)/lib/common/libcommon.la \
$(top_builddir)/lib/gvc/libgvc.la \
- $(top_builddir)/plugin/libplugins.la @LIBGEN_LIBS@
+ $(top_builddir)/plugin/libplugins.la
+endif
install-data-hook:
(cd $(DESTDIR)$(man1dir); for i in $(linkedman); do rm -f $$i; $(LN_S) dot.1 $$i; done;)
#include "render.h"
#include "tlayout.h"
+/* Default layout values, possibly set via command line; -1 indicates unset */
+fdpParms_t fdp_parms_default = {
+ 1, /* useGrid */
+ 1, /* useNew */
+ -1, /* numIters */
+ 50, /* unscaled */
+ 0.0, /* C */
+ 1.0, /* Tfact */
+ -1.0, /* K - set in initParams; used in init_edge */
+ -1.0, /* T0 */
+};
+
+
static int
neato_extra_args(GVC_t *gvc, int argc, char** argv)
{
char* arg;
int cnt = 1;
+ fdp_parms = fdp_parms_default;
+
for (i = 1; i < argc; i++) {
arg = argv[i];
if (arg && (*arg == '-') && (*(arg+1) == 'L')) {
#include "types.h"
#include "macros.h"
#include "gvc.h"
-gvplugin_t *builtins[] = {
+gvplugin_library_t *builtins[] = {
NULL
};
AC_CONFIG_SRCDIR(configure.ac)
AC_CONFIG_AUX_DIR(config)
-#AC_CONFIG_SUBDIRS(libltdl)
-#AC_LIBTOOL_DLOPEN
-#AC_LIBLTDL_CONVENIENCE
-
-HAVE_LTDL=0
+AC_CONFIG_SUBDIRS(libltdl)
+AC_LIBTOOL_DLOPEN
+AC_LIBLTDL_CONVENIENCE
+HAVE_LTDL=1
AC_SUBST(INCLTDL)
AC_SUBST(LIBLTDL)
AC_DEFINE_UNQUOTED(HAVE_LTDL,$HAVE_LTDL,Define if to use libltdl dynamic loading of plugins.)
-I$(top_srcdir)/lib/gvc \
-I$(top_srcdir)/lib/pathplan \
-I$(top_srcdir)/lib/graph \
- -I$(top_srcdir)/lib/cdt \
- @GD_INCLUDES@ @EXPAT_INCLUDES@ @CAIRO_CFLAGS@ @Z_INCLUDES@
+ -I$(top_srcdir)/lib/cdt @GD_INCLUDES@ @EXPAT_INCLUDES@ @Z_INCLUDES@
pkginclude_HEADERS = const.h globals.h htmllex.h htmltable.h macros.h \
pointset.h render.h renderprocs.h types.h utils.h colortbl.h
pkglib_LTLIBRARIES = libcommon.la
if !DISABLE_CODEGENS
-CODEGENS = diagen.c figgen.c gdgen.c hpglgen.c mapgen.c mifgen.c mpgen.c \
+CODEGENS = diagen.c figgen.c hpglgen.c gdgen.c mapgen.c mifgen.c mpgen.c \
picgen.c psgen.c svggen.c vrmlgen.c vtxgen.c ps.txt xdgen.c color_names
endif
-libcommon_la_SOURCES = arrows.c colxlate.c fontmetrics.c gdtextsize.c \
- gdusershape.c globals.c htmllex.c htmlparse.y htmltable.c input.c \
+libcommon_la_SOURCES = arrows.c colxlate.c fontmetrics.c \
+ gdtextsize.c gdusershape.c \
+ globals.c htmllex.c htmlparse.y htmltable.c input.c \
pointset.c postproc.c psusershape.c routespl.c splines.c \
svgusershape.c timing.c labels.c ns.c shapes.c utils.c \
output.c emit.c $(CODEGENS)
-libcommon_la_LIBADD = \
- @GD_LIBS@ @CAIRO_LIBS@ @EXPAT_LIBS@ @Z_LIBS@
+libcommon_la_LIBADD = $(top_builddir)/lib/pathplan/libpathplan.la @GD_LIBS@ @EXPAT_LIBS@ @Z_LIBS@
psgen.o psgen.lo : ps.h
*E_labelfontsize, *E_labelfontname, *E_labelfontcolor,
*E_labeldistance, *E_labelangle,
*E_tailclip, *E_headclip;
+
+ EXTERN fdpParms_t fdp_parms;
+
#undef external
#ifdef __cplusplus
#define ED_weight(e) (e)->u.weight
#define ED_xpenalty(e) (e)->u.xpenalty
+ typedef struct {
+ int useGrid; /* use grid for speed up */
+ int useNew; /* encode x-K into attractive force */
+ int numIters; /* actual iterations in layout */
+ int unscaled; /* % of iterations used in pass 1 */
+ double C; /* Repulsion factor in xLayout */
+ double Tfact; /* scale temp from default expression */
+ double K; /* spring constant; ideal distance */
+ double T0; /* initial temperature */
+ } fdpParms_t;
+
#ifdef __cplusplus
}
#endif
#include "tlayout.h"
#include "globals.h"
- /* Default layout values, possibly set via command line; -1 indicates unset */
-fdpParms_t fdp_parms = {
- 1, /* useGrid */
- 1, /* useNew */
- -1, /* numIters */
- 50, /* unscaled */
- 0.0, /* C */
- 1.0, /* Tfact */
- -1.0, /* K - set in initParams; used in init_edge */
- -1.0, /* T0 */
-};
-
#define D_useGrid (fdp_parms.useGrid)
#define D_useNew (fdp_parms.useNew)
#define D_numIters (fdp_parms.numIters)
seed_unset, seed_val, seed_time, seed_regular
} seedMode;
- typedef struct {
- int useGrid; /* use grid for speed up */
- int useNew; /* encode x-K into attractive force */
- int numIters; /* actual iterations in layout */
- int unscaled; /* % of iterations used in pass 1 */
- double C; /* Repulsion factor in xLayout */
- double Tfact; /* scale temp from default expression */
- double K; /* spring constant; ideal distance */
- double T0; /* initial temperature */
- } fdpParms_t;
-
extern fdpParms_t fdp_parms;
extern void fdp_initParams(graph_t *);
-I$(top_srcdir)/lib/common \
-I$(top_srcdir)/lib/pathplan \
-I$(top_srcdir)/lib/graph \
- -I$(top_srcdir)/lib/cdt $(INCLTDL)
+ -I$(top_srcdir)/lib/cdt $(INCLTDL) \
+ -DGVLIBDIR=\"$(pkglibdir)\"
LIBS = $(LIBLTDL)
char *typestr, int quality, char *path,
gvplugin_type_t * typeptr);
extern gv_plugin_t *gvplugin_load(GVC_t * gvc, api_t api, char *type);
+ extern gvplugin_library_t *gvplugin_library_load(char *path);
extern const char *gvplugin_list(GVC_t * gvc, api_t api, char *str);
extern void gvplugin_builtins(GVC_t * gvc);
extern api_t gvplugin_api(char *str);
+ extern char * gvplugin_api_name(api_t api);
/* job */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <glob.h>
#include "config.h"
#include "types.h"
api_t gv_api;
int quality;
int nest = 0;
- int sz, rc;
+ int sz, rc, i, j;
+ struct stat config_st, libdir_st;
FILE *f;
char *config_path, *home, *config;
- char *dot_graphviz_config = "/.graphviz/config";
+ glob_t globbuf;
+ gvplugin_library_t *library;
+ gvplugin_api_t *apis;
+ gvplugin_type_t *types;
+
+ char *dot_graphviz = "/.graphviz";
+ char *libdir = GVLIBDIR;
#define SZ_CONFIG 1000
#endif
gvplugin_builtins(gvc);
+
+ /* see if there are any new plugins */
+
+ rc = stat(libdir, &libdir_st);
+ if (rc == -1) { /* if we fail to stat it then it probably doesn't exist
+ so just fail silently, clean up and return */
+ return;
+ }
+
home = getenv ("HOME");
if (!home) {
return;
}
- config_path = malloc(strlen(home) + strlen(dot_graphviz_config) + 1);
+ config_path = malloc(strlen(home) + strlen(dot_graphviz) + 1);
strcpy(config_path, home);
- strcat(config_path, dot_graphviz_config);
+ strcat(config_path, dot_graphviz);
+
+ rc = stat(config_path, &config_st);
+
+ if (rc == -1 || libdir_st.st_mtime > config_st.st_mtime) {
+ f = fopen(config_path,"w");
+ if (!f) {
+ fprintf(stderr,"failed to open %s for write.\n", config_path);
+ free(config_path);
+ return;
+ }
+
+ rc = glob("/home/ellson/FIX/Linux.x86_64/lib/graphviz/libgvplugin*.so",
+ GLOB_NOSORT, NULL, &globbuf);
+
+ if (rc == 0) {
+ for (j = 0; j < globbuf.gl_pathc; j++) {
+ library = gvplugin_library_load(globbuf.gl_pathv[j]);
+ if (library) {
+ fputs (globbuf.gl_pathv[j], f);
+ fputs (" {\n", f);
+ for (apis = library->apis; (types = apis->types); apis++) {
+ fputs ("\t", f);
+ fputs (gvplugin_api_name(apis->api), f);
+ fputs (" {\n", f);
+ for (i = 0; types[i].type; i++) {
+ /* might as well install it since its already loaded */
+ gvplugin_install(gvc, apis->api, types[i].type,
+ types[i].quality, library->name, &types[i]);
+
+ fprintf(f, "\t\t%s %d\n",
+ types[i].type, types[i].quality);
+ }
+ fputs ("\t}\n", f);
+ }
+ fputs ("}\n", f);
+ }
+ }
+ }
+ globfree(&globbuf);
+
+ fclose(f);
+ return; /* all plugins have been installed */
+ }
+
+ /* load in the cached plugin library data */
f = fopen(config_path,"r");
if (!f) { /* if we fail to open it then it probably doesn't exists
* inititialized here by redefining ELEM and reinvoking APIS.
*/
#define ELEM(x) #x,
-static char *apis[] = { APIS }; /* "render", "layout", ... */
+static char *api_names[] = { APIS }; /* "render", "layout", ... */
#undef ELEM
/* translate a string api name to its type, or -1 on error */
{
int api;
- for (api = 0; api < ARRAY_SIZE(apis); api++) {
- if (strcmp(str, apis[api]) == 0)
+ for (api = 0; api < ARRAY_SIZE(api_names); api++) {
+ if (strcmp(str, api_names[api]) == 0)
return (api_t)api;
}
return -1; /* invalid api */
}
+/* translate api_t into string name, or NULL */
+char *gvplugin_api_name(api_t api)
+{
+ if (api < 0 || api >= ARRAY_SIZE(api_names))
+ return NULL;
+ return api_names[api];
+}
+
/* install a plugin description into the list of available plugins */
/* list is alpha sorted by type, the quality sorted within the type,
then, if qualities are the same, last install wins */
return TRUE;
}
+gvplugin_library_t *gvplugin_library_load(char *path)
+{
+#if HAVE_LTDL
+ lt_dlhandle hndl;
+ lt_ptr ptr;
+ char *s, *sym;
+
+ char *suffix = "_LTX_library";
+
+ if (lt_dlinit()) {
+ fprintf(stderr,"failed to init libltdl\n");
+ return NULL;
+ }
+ hndl = lt_dlopen (path);
+ if (!hndl) {
+ fprintf(stderr,"failed to dlopen %s\n", path);
+ return NULL;
+ }
+
+ s = strrchr(path, '/');
+ sym = malloc(strlen(s) + strlen(suffix) + 1);
+ strcpy(sym, s+4); /* strip leading "/lib" */
+ s = strchr(sym, '.'); /* strip trailing ".so" */
+ strcpy(s,"_LTX_library"); /* append "_LTX_library" */
+
+ ptr = lt_dlsym (hndl, sym);
+ if (!ptr) {
+ fprintf(stderr,"failed to resolve %s in %s\n", sym, path);
+ free(sym);
+ return NULL;
+ }
+ free(sym);
+ return (gvplugin_library_t *)(ptr);
+#else
+ fprintf(stderr,"dynamic loading not available\n");
+ return NULL;
+#endif
+}
+
+
/* load a plugin of type=str where str can optionally contain a ":path" modifier */
gv_plugin_t *gvplugin_load(GVC_t * gvc, api_t api, char *str)
{
- gv_plugin_t **pnext;
+ gv_plugin_t **pnext, *rv;
+ gvplugin_library_t *library;
+ gvplugin_api_t *apis;
+ gvplugin_type_t *types;
char *s, *p;
+ int i;
+
/* check for valid apis[] index */
if (api < 0)
return NULL;
- /* point to the beginning of the linked list of plugins for this api */
- pnext = &(gvc->apis[api]);
-
/* does str have a :path modifier? */
s = strdup(str);
p = strchr(s, ':');
if (p)
*p++ = '\0';
+ /* point to the beginning of the linked list of plugins for this api */
+ pnext = &(gvc->apis[api]);
+
while (*pnext) {
if (strcmp(s, (*pnext)->typestr) == 0) {
if (p) {
if (strcmp(p, (*pnext)->path) == 0)
break;
- } else
+ }
+ else
break;
}
pnext = &((*pnext)->next);
}
- free(s);
- if ((*pnext) && (*pnext)->typeptr == NULL) {
-#if HAVE_LTDL
- /* dynamically load required plugin library */
-
- lt_dlhandle hndl;
- lt_ptr ptr;
-
- if (lt_dlinit()) {
- fprintf(stderr,"failed to init libltdl\n");
- return NULL;
- }
- hndl = lt_dlopen ((*pnext)->path);
- if (!hndl) {
- fprintf(stderr,"failed to dlopen %s\n", (*pnext)->path);
- return NULL;
- }
- ptr = lt_dlsym (hndl, "gvplugin_cairo_LTX_plugin");
- if (!ptr) {
- fprintf(stderr,"failed to resolve %s in %s\n", "gvplugin_cairo_LTX_plugin", (*pnext)->path);
- return NULL;
- }
-#if 0
- /* FIXME */
- (*pnext)->typeptr =
-#else
- fprintf(stderr,"dynamic loading not implemented\n");
- return NULL;
-#endif
-#else
- fprintf(stderr,"dynamic loading not available\n");
- return NULL;
-#endif
+ rv = *pnext;
+ if ((*pnext) && (*pnext)->typeptr == NULL) {
+ rv = NULL;
+ library = gvplugin_library_load((*pnext)->path);
+ if (library) {
+
+ /*
+ * FIXME - would be cleaner to here remove the entries from the
+ * config data for the uninstalled library - i.e. the entries
+ * without type ptrs. It works without because the real library
+ * data is inserted ahead of, and so supercedes, the config data.
+ */
+
+ /* Now reinsert the library with real type ptrs */
+ for (apis = library->apis; (types = apis->types); apis++) {
+ for (i = 0; types[i].type; i++) {
+ gvplugin_install(gvc, apis->api, types[i].type,
+ types[i].quality, library->name, &types[i]);
+ }
+ }
+
+ /* Now search again for the specific plugin type */
+ pnext = &(gvc->apis[api]);
+ while (*pnext) {
+ if (strcmp(s, (*pnext)->typestr) == 0) {
+ if (p) {
+ if (strcmp(p, (*pnext)->path) == 0)
+ break;
+ }
+ else
+ break;
+ }
+ pnext = &((*pnext)->next);
+ }
+ rv = *pnext;
+ }
}
- return (gvc->api[api] = *pnext);
+ /* one last check for succesfull load */
+ if ((*pnext) && (*pnext)->typeptr == NULL)
+ rv = NULL;
+ free(s);
+ gvc->api[api] = rv;
+ return rv;
}
/* string buffer management - FIXME - must have 20 solutions for this same thing */
return buf;
}
-extern gvplugin_t *builtins[];
+#ifndef HAVE_LTDL
+extern gvplugin_library_t *builtins[];
+#endif
void gvplugin_builtins(GVC_t * gvc)
{
- gvplugin_t **plugin;
+#ifndef HAVE_LTDL
+ gvplugin_library_t **library;
gvplugin_api_t *apis;
gvplugin_type_t *types;
int i;
- for (plugin = builtins; *plugin; plugin++) {
- for (apis = (*plugin)->apis; (types = apis->types); apis++) {
+ for (library = builtins; *library; library++) {
+ for (apis = (*library)->apis; (types = apis->types); apis++) {
for (i = 0; types[i].type; i++) {
gvplugin_install(gvc, apis->api,
types[i].type, types[i].quality,
- (*plugin)->name, &types[i]);
+ (*library)->name, &types[i]);
}
}
}
+#endif
}
typedef struct {
char *name; /* used instead of a file pathname
- when this plugin is builtin */
+ when this plugin is loaded */
gvplugin_api_t *apis;
- } gvplugin_t;
+ } gvplugin_library_t;
#ifdef __cplusplus
}