]> granicus.if.org Git - graphviz/commitdiff
various bits for on-demand plugin loading - currently disabled
authorellson <devnull@localhost>
Sat, 2 Apr 2005 23:55:21 +0000 (23:55 +0000)
committerellson <devnull@localhost>
Sat, 2 Apr 2005 23:55:21 +0000 (23:55 +0000)
configure.ac
graphviz.spec.in
lib/common/emit.c
lib/common/input.c
lib/gvc/Makefile.am
lib/gvc/gvc.h
lib/gvc/gvconfig.c
lib/gvc/gvplugin.c
tclpkg/gv/gv.cpp
tclpkg/tcldot/tcldot.c

index b395fafed8459a4de437b7ed58bd3e96876e6c31..4b2c5ce9eaac26ab693e04cee529d726dc07209b 100644 (file)
@@ -3,11 +3,16 @@ AC_INIT(graphviz, 2.3)
 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
index 9558782af09993c7f0132f22339f721da5a8c4fb..4bc46d53b4b0c57e7a668cfe0e8a09db92caa662 100644 (file)
@@ -51,7 +51,7 @@ of graphs (as in nodes and edges, not as in barcharts).
 %{_libdir}/%{name}/*.pm
 %{_libdir}/%{name}/*.py
 %{_libdir}/%{name}/*.java
-%{_libdir}/%{name}/*.cs
+#%{_libdir}/%{name}/*.cs
 %{_mandir}/man1/*.1*
 %dir %{_datadir}/%{name}
 %{_datadir}/%{name}/lefty
index 16b095126bfe7173395083a38945511daf949157..9eeb9f0a57ec9af373f23bf9e907a9d24b3ae183 100644 (file)
@@ -1624,7 +1624,10 @@ void emit_jobs (GVC_t * gvc, graph_t * g)
             }
         }
         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);
index 41375e2a3dc51484c6630cf37d13dc0311e75015..f5e12441a831ef054d848f24fc0706df7102f3de 100644 (file)
 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 =
@@ -152,10 +146,8 @@ void dotneato_initialize(GVC_t * gvc, int argc, char **argv)
     /* 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);
index 2e226af0888f9787131e90c0e0db7ff6c68cc01e..a9168c0f54e917b38a739d9404f8950adf6eaed3 100644 (file)
@@ -5,11 +5,9 @@ AM_CPPFLAGS = \
        -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 
index 0802303b7a084a4076214c623850a50ae4f18f6b..ccf6b324119a133a476b68ef396d3356e1d3aef6 100644 (file)
@@ -33,7 +33,7 @@ extern "C" {
 
 /* configuration */
 
-    extern void gvconfig(GVC_t * gvc, char *config);
+    extern void gvconfig(GVC_t * gvc);
 
 /* plugins */
 
index a879c448360095b633d49c3f76d261c612ebdfc0..611e81a872c158775ee2b80ac8cdc058c6f4c8b1 100644 (file)
 #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
 
@@ -119,33 +124,77 @@ static char *token(int *nest, char **tokens)
 /*
   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);
index 69550818b3d4be4b2696aaded1c87a3190df8531..7a93ec03b12e9c6fe8aad62d3aac57824c8bb3c8 100644 (file)
 #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
@@ -109,10 +112,41 @@ gv_plugin_t *gvplugin_load(GVC_t * gvc, api_t api, char *str)
        }
        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);
 }
 
@@ -159,8 +193,8 @@ const char *gvplugin_list(GVC_t * gvc, api_t api, char *str)
     /* 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 */
index 82ea050340816875ab8f7f22b2c2d6d0cc635044..553121568dab2100e04c4e762220a2bd6bd1d4f6 100644 (file)
@@ -30,10 +30,8 @@ static void gvinit()
     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)
index 58fa7daa9923b952dbb7cd8f6dddbab29eab6cd0..0129c948a9bedeabda04e82cd812e8225d0b091d 100644 (file)
@@ -1647,14 +1647,12 @@ int Tcldot_Init(Tcl_Interp * interp)
     /* 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,