From 1820246baf7580f9649532ff868da0c99d93df29 Mon Sep 17 00:00:00 2001 From: ellson Date: Tue, 14 Oct 2008 04:17:44 +0000 Subject: [PATCH] plugin graph generator --- lib/gvc/gvconfig.c | 25 +++++--- lib/gvc/gvcontext.c | 2 +- lib/gvc/gvcproc.h | 2 +- lib/gvc/gvplugin.c | 153 +++++++++++++++++++++++++++++++++++++++----- lib/gvc/gvrender.c | 2 +- 5 files changed, 154 insertions(+), 30 deletions(-) diff --git a/lib/gvc/gvconfig.c b/lib/gvc/gvconfig.c index 586724bd2..73ffdbe17 100644 --- a/lib/gvc/gvconfig.c +++ b/lib/gvc/gvconfig.c @@ -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 */ diff --git a/lib/gvc/gvcontext.c b/lib/gvc/gvcontext.c index 390d706c1..132a864f3 100644 --- a/lib/gvc/gvcontext.c +++ b/lib/gvc/gvcontext.c @@ -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); diff --git a/lib/gvc/gvcproc.h b/lib/gvc/gvcproc.h index 25d36ebe7..2b24c63c1 100644 --- a/lib/gvc/gvcproc.h +++ b/lib/gvc/gvcproc.h @@ -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); diff --git a/lib/gvc/gvplugin.c b/lib/gvc/gvplugin.c index fd113cf49..c462662b9 100644 --- a/lib/gvc/gvplugin.c +++ b/lib/gvc/gvplugin.c @@ -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 : ""); + rv->package->path ? rv->package->path : ""); } } @@ -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; } diff --git a/lib/gvc/gvrender.c b/lib/gvc/gvrender.c index f15614ef8..7d3b4bf8a 100644 --- a/lib/gvc/gvrender.c +++ b/lib/gvc/gvrender.c @@ -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; -- 2.40.0