AC_CONFIG_SRCDIR(configure.ac)
AC_CONFIG_AUX_DIR(config)
-# AC_CONFIG_SUBDIRS(libltdl)
+#AC_CONFIG_SUBDIRS(libltdl)
#AC_LIBTOOL_DLOPEN
#AC_LIBLTDL_CONVENIENCE
-#AC_SUBST(INCLTDL)
-#AC_SUBST(LIBLTDL)
+
+HAVE_LTDL=0
+
+AC_SUBST(INCLTDL)
+AC_SUBST(LIBLTDL)
+AC_DEFINE_UNQUOTED(HAVE_LTDL,$HAVE_LTDL,Define if to use libltdl dynamic loading of plugins.)
+AM_CONDITIONAL(ENABLE_LTDL, [test "x$HAVE_LTDL" = "x1"])
# Checks for system type
AC_CANONICAL_TARGET
%{_libdir}/%{name}/*.pm
%{_libdir}/%{name}/*.py
%{_libdir}/%{name}/*.java
-%{_libdir}/%{name}/*.cs
+#%{_libdir}/%{name}/*.cs
%{_mandir}/man1/*.1*
%dir %{_datadir}/%{name}
%{_datadir}/%{name}/lefty
}
}
job->output_lang = gvrender_select(gvc, job->output_langname);
- assert(job->output_lang != NO_SUPPORT); /* should have been verified already */
+ if (job->output_lang == NO_SUPPORT) {
+ fprintf(stderr,"renderer for %s is unavailable\n", job->output_langname);
+ return;
+ }
if (strcmp(job->output_langname,prev_langname) != 0) {
prev_langname = job->output_langname;
gvrender_initialize(gvc);
codegen_t *Output_codegen;
#endif
-#if 0
-static char *CONFIG = "cairo {renderer {svg svgz x11 png ps}}";
-#else
-static char *CONFIG = "";
-#endif
-
char *Gvfilepath;
static char *usageFmt =
/* establish Gvfilepath, if any */
Gvfilepath = getenv("GV_FILE_PATH");
- /* configure codegens */
- config_codegen_builtins(gvc);
- gvplugin_builtins(gvc);
- gvconfig(gvc, CONFIG);
+ /* configure for available plugins and codegens */
+ gvconfig(gvc);
CmdName = basename(argv[0]);
i = gvlayout_select(gvc, CmdName);
-I$(top_srcdir)/lib/common \
-I$(top_srcdir)/lib/pathplan \
-I$(top_srcdir)/lib/graph \
- -I$(top_srcdir)/lib/cdt
+ -I$(top_srcdir)/lib/cdt $(INCLTDL)
-#@INCLTDL@
-
-#LIBS = @LIBLTDL@
+LIBS = $(LIBLTDL)
pkginclude_HEADERS = gvc.h gvcint.h gvplugin.h \
gvplugin_render.h gvplugin_layout.h gvplugin_text.h
/* configuration */
- extern void gvconfig(GVC_t * gvc, char *config);
+ extern void gvconfig(GVC_t * gvc);
/* plugins */
#include "macros.h"
#include "gvc.h"
+#ifndef DISABLE_CODEGENS
+extern void config_codegen_builtins(GVC_t *gvc);
+#endif
+
/*
A config for gvrender is a text file containing a
- tcl-like-syntax list of plugins and their capabilities.
+ list of plugins and their capabilities using a tcl-like
+ syntax
Lines beginning with '#' are ignored as comments
/*
gvconfig - parse a config file and install the identified plugins
*/
-void gvconfig(GVC_t * gvc, char *config)
+void gvconfig(GVC_t * gvc)
{
char *s, *path, *api, *type;
+ api_t gv_api;
int quality;
int nest = 0;
+ int sz, rc;
+ FILE *f;
+ char *config_path, *home, *config;
+ char *dot_graphviz_config = "/.graphviz/config";
+
+#define SZ_CONFIG 1000
+
+#ifndef DISABLE_CODEGENS
+ config_codegen_builtins(gvc);
+#endif
+ gvplugin_builtins(gvc);
+
+ home = getenv ("HOME");
+ if (!home) {
+ return;
+ }
- s = strdup(config);
- /* this copy is never free'd because the config uses pointers
- into it for string values */
+ config_path = malloc(strlen(home) + strlen(dot_graphviz_config) + 1);
+ strcpy(config_path, home);
+ strcat(config_path, dot_graphviz_config);
+ f = fopen(config_path,"r");
+ if (!f) { /* if we fail to open it then it probably doesn't exists
+ so just fail silently, clean up and return */
+ free(config_path);
+ return;
+ }
+ config = malloc(SZ_CONFIG);
+ config[0] = '\0';
+ sz = fread(config, 1, SZ_CONFIG, f);
+ if (sz == 0) {
+ fprintf(stderr,"%s is zero sized, or other read error.\n", config_path);
+ free(config_path);
+ free(config);
+ return;
+ }
+ if (sz == SZ_CONFIG) {
+ fprintf(stderr,"%s is bigger than I can handle.\n", config_path);
+ free(config_path);
+ free(config);
+ return;
+ }
+ fclose(f);
+ free(config_path); /* not needed now that we've slurped in the contents */
+
+ s = config;
separator(&nest, &s);
while (*s) {
path = token(&nest, &s);
do {
api = token(&nest, &s);
+ gv_api = gvplugin_api(api);
+ if (gv_api == -1) {
+ fprintf(stderr, "invalid api in config: %s %s\n", path, api);
+ return;
+ }
do {
type = token(&nest, &s);
if (nest == 2)
quality = atoi(token(&nest, &s));
else
quality = 0;
- if (!
- (gvplugin_install
- (gvc, gvplugin_api(api), type, quality, path,
- NULL))) {
- fprintf(stderr, "config error: %s %s %s\n", api, type,
- path);
+ rc = gvplugin_install (gvc, gv_api, type, quality, path, NULL);
+ if (!rc) {
+ fprintf(stderr, "config error: %s %s %s\n", path, api, type);
return;
}
} while (nest == 2);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
#include "config.h"
#include "types.h"
#include "macros.h"
#include "gvc.h"
+#if HAVE_LTDL
+#include <ltdl.h>
+#endif
+
/*
* Define an apis array of name strings using an enumerated api_t as index.
* The enumerated type is defined gvplugin.h. The apis array is
}
pnext = &((*pnext)->next);
}
- if ((*pnext)->typeptr == NULL) {
- /* FIXME - load dll here */
- }
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
+ }
return (gvc->api[api] = *pnext);
}
/* point to the beginning of the linked list of plugins for this api */
plugin = &(gvc->apis[api]);
- if (p) { /* if str contains a ':', and if we find a match for the type,
- then just list teh alternative paths for the plugin */
+ if (p) { /* if str contains a ':', and if we find a match for the type,
+ then just list teh alternative paths for the plugin */
pnext = plugin;
while (*pnext) {
/* list only the matching type */
agnodeattr(NULL, "label", NODENAME_ESC);
gvc = gvNEWcontext(Info, username());
- /* configure codegens */
- config_codegen_builtins(gvc);
- gvplugin_builtins(gvc);
-// gvconfig(gvc, CONFIG);
+ /* configure for available plugins and codegens */
+ gvconfig(gvc);
}
Agraph_t *digraph(char *name)
/* create a GraphViz Context and pass a pointer to it in clientdata */
gvc = gvNEWcontext(Info, username());
- /* configure codegens */
- config_codegen_builtins(gvc);
+ /* configure for available plugins and codegens */
+ gvconfig(gvc);
/* additional codegens */
for (p = cg; p->name; ++p)
gvplugin_install(gvc, API_render, p->name, 0, "cg",
(gvplugin_type_t *) p);
- gvplugin_builtins(gvc);
-// gvconfig(gvc, CONFIG);
#ifndef TCLOBJ
Tcl_CreateCommand(interp, "dotnew", dotnew,