]> granicus.if.org Git - graphviz/commitdiff
plugin graph generator
authorellson <devnull@localhost>
Tue, 14 Oct 2008 04:17:44 +0000 (04:17 +0000)
committerellson <devnull@localhost>
Tue, 14 Oct 2008 04:17:44 +0000 (04:17 +0000)
lib/gvc/gvconfig.c
lib/gvc/gvcontext.c
lib/gvc/gvcproc.h
lib/gvc/gvplugin.c
lib/gvc/gvrender.c

index 586724bd2dfc8f8e44f0c2988fded8b192067745..73ffdbe17bbc669f966b8f01676180fe95d6a125 100644 (file)
@@ -160,11 +160,11 @@ static char *token(int *nest, char **tokens)
     return t;
 }
 
-static gvplugin_package_t * gvplugin_package_record(GVC_t * gvc, char *path, char *packagename)
+static gvplugin_package_t * gvplugin_package_record(GVC_t * gvc, char *path, char *name)
 {
     gvplugin_package_t *package = gmalloc(sizeof(gvplugin_package_t));
-    package->path = strdup(path);
-    package->packagename = strdup(packagename);
+    package->path = (path) ? strdup(path) : NULL;
+    package->name = strdup(name);
     package->next = gvc->packages;
     gvc->packages = package;
     return package;
@@ -172,7 +172,7 @@ static gvplugin_package_t * gvplugin_package_record(GVC_t * gvc, char *path, cha
 
 static int gvconfig_plugin_install_from_config(GVC_t * gvc, char *s)
 {
-    char *path, *packagename, *api;
+    char *path, *name, *api;
     const char *type;
     api_t gv_api;
     int quality, rc;
@@ -183,10 +183,10 @@ static int gvconfig_plugin_install_from_config(GVC_t * gvc, char *s)
     while (*s) {
        path = token(&nest, &s);
        if (nest == 0)
-           packagename = token(&nest, &s);
+           name = token(&nest, &s);
         else
-           packagename = "x";
-        package = gvplugin_package_record(gvc, path, packagename);
+           name = "x";
+        package = gvplugin_package_record(gvc, path, name);
        do {
            api = token(&nest, &s);
            gv_api = gvplugin_api(api);
@@ -202,7 +202,7 @@ static int gvconfig_plugin_install_from_config(GVC_t * gvc, char *s)
                    else
                        quality = 0;
                    rc = gvplugin_install (gvc, gv_api,
-                                   type, quality, packagename, path, NULL);
+                                   type, quality, package, NULL);
                    if (!rc) {
                        agerr(AGERR, "config error: %s %s %s\n", path, api, type);
                        return 0;
@@ -219,12 +219,14 @@ static void gvconfig_plugin_install_from_library(GVC_t * gvc, char *path, gvplug
 {
     gvplugin_api_t *apis;
     gvplugin_installed_t *types;
+    gvplugin_package_t *package;
     int i;
 
+    package = gvplugin_package_record(gvc, path, library->packagename);
     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->packagename, path, &types[i]);
+                       types[i].quality, package, &types[i]);
         }
     }
 }
@@ -492,9 +494,12 @@ void gvconfig(GVC_t * gvc, boolean rescan)
 #ifdef WITH_CODEGENS
     codegen_info_t *p;
 
+    gvplugin_package_t *package;
+
+    package = gvplugin_package_record(gvc, NULL, "cg");
     for (p = cg; p->name; ++p)
         gvplugin_install(gvc, API_device, p->name, 0,
-                        "cg", NULL, (gvplugin_installed_t *) p);
+               package, (gvplugin_installed_t *) p);
 #endif
 
     /* builtins don't require LTDL */
index 390d706c113730e925e94b525cd5b00f07efefa8..132a864f3dccf6cdaa0caeade930d067e6bbf07e 100644 (file)
@@ -71,7 +71,7 @@ int gvFreeContext(GVC_t * gvc)
     while ((package = package_next)) {
        package_next = package->next;
        free(package->path);
-       free(package->packagename);
+       free(package->name);
        free(package);
     }
     gvjobs_delete(gvc);
index 25d36ebe72419aa9c08fc5513c3925e47d3ae320..2b24c63c1a499a94018f87b906f324018c9d4feb 100644 (file)
@@ -34,7 +34,7 @@ extern "C" {
 /* plugins */
 
     extern boolean gvplugin_install(GVC_t * gvc, api_t api,
-                   const char *typestr, int quality, char *packagename, char *path,
+                   const char *typestr, int quality, gvplugin_package_t *package,
                    gvplugin_installed_t * typeptr);
     extern gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, const char *type);
     extern gvplugin_library_t *gvplugin_library_load(GVC_t *gvc, char *path);
index fd113cf492ca3c69d6b2186814f937c218e5634d..c462662b981cb08648905467ba5e55833521a89f 100644 (file)
@@ -69,9 +69,9 @@ char *gvplugin_api_name(api_t api)
  * quality sorted within the type, then, if qualities are the same,
  * last install wins.
  */
-boolean gvplugin_install(GVC_t * gvc, api_t api,
-                const char *typestr, int quality, char *packagename, char *path,
-                gvplugin_installed_t * typeptr)
+boolean gvplugin_install(GVC_t * gvc, api_t api, const char *typestr,
+       int quality, gvplugin_package_t *package,
+       gvplugin_installed_t * typeptr)
 {
     gvplugin_available_t *plugin, **pnext;
 #define TYPSIZ 63
@@ -114,8 +114,7 @@ boolean gvplugin_install(GVC_t * gvc, api_t api,
     *pnext = plugin;
     plugin->typestr = typestr;
     plugin->quality = quality;
-    plugin->packagename = packagename; /* packagename,  all packages */
-    plugin->path = path;       /* filepath for .so, or NULL for builtins */
+    plugin->package = package;
     plugin->typeptr = typeptr; /* null if not loaded */
 
     return TRUE;
@@ -129,7 +128,7 @@ boolean gvplugin_install(GVC_t * gvc, api_t api,
  * manually changed in the config file.
  */
 static boolean gvplugin_activate(GVC_t * gvc, api_t api,
-                const char *typestr, char *packagename, char *path,
+                const char *typestr, char *name, char *path,
                 gvplugin_installed_t * typeptr)
 {
     gvplugin_available_t **pnext;
@@ -143,8 +142,8 @@ static boolean gvplugin_activate(GVC_t * gvc, api_t api,
 
     while (*pnext) {
        if ( (strcasecmp(typestr, (*pnext)->typestr) == 0)
-         && (strcasecmp(packagename, (*pnext)->packagename) == 0)
-         && (strcasecmp(path, (*pnext)->path) == 0)) {
+         && (strcasecmp(name, (*pnext)->package->name) == 0)
+         && (strcasecmp(path, (*pnext)->package->path) == 0)) {
            (*pnext)->typeptr = typeptr;
            return TRUE;
        }
@@ -298,7 +297,7 @@ gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, const char *str)
            continue;  /* dependencies not empty, but mismatched */
        if (! reqpkg)
            break; /* found with no packagename constraints */
-       if (strcmp(reqpkg, (*pnext)->packagename) == 0)
+       if (strcmp(reqpkg, (*pnext)->package->name) == 0)
            break;  /* found with required matching packagname */
     }
     rv = *pnext;
@@ -308,7 +307,7 @@ gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, const char *str)
            rv = NULL;
 
     if (rv && rv->typeptr == NULL) {
-       library = gvplugin_library_load(gvc, rv->path);
+       library = gvplugin_library_load(gvc, rv->package->path);
        if (library) {
 
             /* Now activate the library with real type ptrs */
@@ -320,13 +319,13 @@ gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, const char *str)
                                apis->api,
                                types[i].type,
                                library->packagename,
-                               rv->path,
+                               rv->package->path,
                                &types[i]);
                }
             }
            if (gvc->common.verbose >= 1)
                fprintf(stderr, "Activated plugin library: %s\n",
-                       rv->path ? rv->path : "<builtin>");
+                       rv->package->path ? rv->package->path : "<builtin>");
         }
     }
 
@@ -338,7 +337,7 @@ gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, const char *str)
        fprintf(stderr, "Using %s: %s:%s\n",
                api_names[api],
                rv->typestr,
-               rv->packagename
+               rv->package->name
                );
 
     gvc->api[api] = rv;
@@ -399,7 +398,7 @@ char *gvplugin_list(GVC_t * gvc, api_t api, const char *str)
            if (!s[0] || strcasecmp(s, q) == 0) {
                /* list each member of the matching type as "type:path" */
                append_buf(' ', (*pnext)->typestr, new);
-               buf = append_buf(':', (*pnext)->packagename, FALSE);
+               buf = append_buf(':', (*pnext)->package->name, FALSE);
                new = FALSE;
            }
            free(q);
@@ -459,15 +458,135 @@ void gvplugin_write_status(GVC_t * gvc)
 
 Agraph_t * gvplugin_graph(GVC_t * gvc)
 {
-    Agraph_t *g;
-    Agnode_t *n;
+    Agraph_t *g, *sg, *ssg;
+    Agnode_t *n, *m;
+    Agedge_t *e;
+    Agsym_t *a;
+    gvplugin_package_t *package;
+    gvplugin_available_t **pnext;
+    char buf[100], *p, *q;
+    int api, found;
 
     aginit();
     /* set persistent attributes here */
     agnodeattr(NULL, "label", NODENAME_ESC);
+    agraphattr(NULL, "label", "");
+    agraphattr(NULL, "rankdir", "");
+    agraphattr(NULL, "rank", "");
 
     g = agopen("G", AGDIGRAPH);
-    n = agnode(g, "plugins graph under-construction");
+
+    a = agfindattr(g, "rankdir");
+    agxset(g, a->index, "LR");
+
+    a = agfindattr(g, "label");
+    agxset(g, a->index, "\nPlugins");
+
+    for (package = gvc->packages; package; package = package->next) {
+        strcpy(buf, "cluster_");
+        strcat(buf, package->name); 
+       sg = agsubg(g, buf);
+        a = agfindattr(sg, "label");
+       agxset(sg, a->index, package->name);
+
+       for (api = 0; api < ARRAY_SIZE(api_names); api++) {
+           found = 0;
+           strcpy(buf, package->name);
+           strcat(buf, "_");
+           strcat(buf, api_names[api]);
+           ssg = agsubg(sg, buf);
+            a = agfindattr(ssg, "rank");
+           agxset(ssg, a->index, "same");
+           for (pnext = &(gvc->apis[api]); *pnext; pnext = &((*pnext)->next)) {
+               if ((*pnext)->package == package) {
+                   found++;
+                   q = strdup((*pnext)->typestr);
+                   if ((p = strchr(q, ':'))) *p++ = '\0';
+                   switch (api) {
+                   case API_device:
+                   case API_loadimage:
+                   case API_render:
+                       strcpy(buf, api_names[api]);
+                       strcat(buf, "_");
+                       strcat(buf, q);
+                       n = agnode(ssg, buf);
+                        a = agfindattr(n, "label");
+                       agxset(n, a->index, q);
+                       break;
+                   default:
+                       break;
+                   }
+                   free(q);
+               }
+           }
+           if (!found)
+               agdelete(ssg->meta_node->graph, ssg->meta_node);
+       }
+    }
+
+    for (package = gvc->packages; package; package = package->next) {
+        strcpy(buf, "cluster_");
+        strcat(buf, package->name); 
+       sg = agfindsubg(g, buf);
+       for (api = 0; api < ARRAY_SIZE(api_names); api++) {
+           strcpy(buf, package->name);
+           strcat(buf, "_");
+           strcat(buf, api_names[api]);
+           ssg = agfindsubg(sg, buf);
+           for (pnext = &(gvc->apis[api]); *pnext; pnext = &((*pnext)->next)) {
+               if ((*pnext)->package == package) {
+                   q = strdup((*pnext)->typestr);
+                   if ((p = strchr(q, ':'))) *p++ = '\0';
+                   switch (api) {
+                   case API_device:
+                       strcpy(buf, api_names[api]);
+                       strcat(buf, "_");
+                       strcat(buf, q);
+                       n = agfindnode(ssg, buf);
+                       strcpy(buf, "o_");
+                       strcat(buf, q);
+                       m = agfindnode(g, buf);
+                       if (!m) {
+                           m = agnode(g, buf);
+                            a = agfindattr(m, "label");
+                           agxset(m, a->index, q);
+                       }
+                       e = agedge(g, n, m);
+                       if (p && *p) {
+                           strcpy(buf, "render_");
+                           strcat(buf, p);
+                           m = agfindnode(g, buf);
+                           if (m)
+                               agedge(g, m, n);
+                       }
+                       break;
+                   case API_loadimage:
+                       strcpy(buf, api_names[api]);
+                       strcat(buf, "_");
+                       strcat(buf, q);
+                       n = agfindnode(ssg, buf);
+                       strcpy(buf, "i_");
+                       strcat(buf, q);
+                       m = agfindnode(g, buf);
+                       if (!m) {
+                           m = agnode(g, buf);
+                            a = agfindattr(m, "label");
+                           agxset(m, a->index, q);
+                       }
+                       e = agedge(g, m, n);
+                       strcpy(buf, "render_");
+                       strcat(buf, p);
+                       m = agfindnode(g, buf);
+                       agedge(g, n, m);
+                       break;
+                   default:
+                       break;
+                   }
+                   free(q);
+               }
+           }
+       }
+    }
 
     return g;
 }
index f15614ef80e5aaec83d1b2167bf6a170996c4030..7d3b4bf8a14c88f6c5a46c027e936695b66d9fe6 100644 (file)
@@ -68,7 +68,7 @@ int gvrender_select(GVJ_t * job, const char *str)
     plugin = gvc->api[API_device];
     if (plugin) {
 #ifdef WITH_CODEGENS
-       if (strcmp(plugin->packagename, "cg") == 0) {
+       if (strcmp(plugin->package->name, "cg") == 0) {
            cg_info = (codegen_info_t *) (plugin->typeptr);
            job->codegen = cg_info->cg;
            job->render.engine = NULL;