17 #include <sys/types.h>
22 #include <compat_unistd.h>
40 #ifndef HAVE_STRCASECMP
45 #define strdup(x) _strdup(x)
54 static char *api_names[] = {
APIS };
63 for (api = 0; api <
ARRAY_SIZE(api_names); api++) {
64 if (strcmp(str, api_names[api]) == 0)
75 return api_names[api];
90 strncpy(pins, typestr,
TYPSIZ);
91 if ((p = strchr(pins,
':')))
95 pnext = &(gvc->
apis[api]);
99 strncpy(pnxt, (*pnext)->typestr,
TYPSIZ);
100 if ((p = strchr(pnxt,
':')))
102 if (strcmp(pins, pnxt) <= 0)
104 pnext = &((*pnext)->next);
109 strncpy(pnxt, (*pnext)->typestr,
TYPSIZ);
110 if ((p = strchr(pnxt,
':')))
112 if (strcmp(pins, pnxt) != 0)
114 if (quality >= (*pnext)->quality)
116 pnext = &((*pnext)->next);
120 plugin->
next = *pnext;
143 pnext = &(gvc->
apis[api]);
146 if ((
strcasecmp(typestr, (*pnext)->typestr) == 0)
147 && (
strcasecmp(name, (*pnext)->package->name) == 0)
148 && ((*pnext)->package->path != 0)
149 && (
strcasecmp(path, (*pnext)->package->path) == 0)) {
153 pnext = &((*pnext)->next);
168 char *suffix =
"_LTX_library";
175 len = strlen(libdir) + 1 + strlen(path) + 1;
184 if (path[1] ==
':') {
186 if (path[0] ==
'/') {
201 if ((stat(p, &sb)) == 0) {
202 agerr(
AGWARN,
"Could not load \"%s\" - %s\n", p,
"It was found, so perhaps one of its dependents was not. Try ldd.");
205 agerr(
AGWARN,
"Could not load \"%s\" - %s\n", p, (
char *) lt_dlerror());
210 fprintf(stderr,
"Loading %s\n", p);
212 s = strrchr(p,
DIRSEP[0]);
214 #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
215 if (len < strlen(
"/gvplugin_x")) {
217 if (len < strlen(
"/libgvplugin_x")) {
219 agerr(
AGERR,
"invalid plugin path \"%s\"\n", p);
222 sym =
gmalloc(len + strlen(suffix) + 1);
223 #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
228 #if defined(__CYGWIN__) || defined(__MINGW32__)
229 s = strchr(sym,
'-');
231 s = strchr(sym,
'.');
235 ptr = lt_dlsym(hndl, sym);
237 agerr(
AGERR,
"failed to resolve %s in %s\n", sym, p);
244 agerr(
AGERR,
"dynamic loading not available\n");
270 char *reqdep, *dep =
NULL, *reqpkg;
274 if (api == API_device || api == API_loadimage)
281 reqdep = strchr(reqtyp,
':');
284 reqpkg = strchr(reqdep,
':');
291 for (pnext = &(gvc->
apis[api]); *pnext; pnext = &((*pnext)->next)) {
292 strncpy(typ, (*pnext)->typestr,
TYPBUFSIZ - 1);
293 dep = strchr(typ,
':');
296 if (strcmp(typ, reqtyp))
298 if (dep && reqdep && strcmp(dep, reqdep))
300 if (!reqpkg || strcmp(reqpkg, (*pnext)->package->name) == 0) {
303 if (dep && (apidep != api))
316 for (apis = library->
apis; (types = apis->
types); apis++) {
317 for (i = 0; types[i].
type; i++) {
344 static int first = 1;
347 char *s, *p, *q, *typestr_last;
367 plugin = &(gvc->
apis[api]);
371 for (pnext = plugin; *pnext; pnext = &((*pnext)->next)) {
372 q = strdup((*pnext)->typestr);
373 if ((p = strchr(q,
':')))
379 agxbput(&xb, (*pnext)->typestr);
381 agxbput(&xb, (*pnext)->package->name);
391 for (pnext = plugin; *pnext; pnext = &((*pnext)->next)) {
393 q = strdup((*pnext)->typestr);
394 if ((p = strchr(q,
':')))
396 if (!typestr_last ||
strcasecmp(typestr_last, q) != 0) {
433 char *p, *q, *typestr_last;
437 for (api = 0; api <
ARRAY_SIZE(api_names); api++) {
442 agerr(
AGERR,
"unrecognized api name \"%s\"\n", kind);
447 plugin = &(gvc->
apis[api]);
449 for (pnext = plugin; *pnext; pnext = &((*pnext)->next)) {
451 q = strdup((*pnext)->typestr);
452 if ((p = strchr(q,
':')))
454 if (!typestr_last ||
strcasecmp(typestr_last, q) != 0) {
455 list =
RALLOC(cnt + 1, list,
char *);
471 fprintf(stderr,
"The plugin configuration file:\n\t%s\n", gvc->
config_path);
473 fprintf(stderr,
"\t\twas successfully loaded.\n");
475 fprintf(stderr,
"\t\twas not found or not usable. No on-demand plugins.\n");
477 fprintf(stderr,
"Demand loading of plugins is disabled.\n");
481 for (api = 0; api <
ARRAY_SIZE(api_names); api++) {
483 fprintf(stderr,
" %s\t: %s\n", api_names[api],
gvplugin_list(gvc, api,
":"));
485 fprintf(stderr,
" %s\t: %s\n", api_names[api],
gvplugin_list(gvc, api,
"?"));
493 Agnode_t *n, *m, *loadimage_n, *renderer_n, *device_n, *textlayout_n, *layout_n;
498 char bufa[100], *buf1, *buf2, bufb[100], *p, *q, *lq, *t;
499 int api, neededge_loadimage, neededge_device;
521 for (package = gvc->
packages; package; package = package->
next) {
522 loadimage_n = renderer_n = device_n = textlayout_n = layout_n =
NULL;
523 neededge_loadimage = neededge_device = 0;
524 strcpy(bufa,
"cluster_");
525 strcat(bufa, package->
name);
529 strcpy(bufa, package->
name);
531 buf1 = bufa + strlen(bufa);
532 for (api = 0; api <
ARRAY_SIZE(api_names); api++) {
533 strcpy(buf1, api_names[api]);
534 ssg =
agsubg(sg, bufa, 1);
538 buf2 = bufa + strlen(bufa);
539 for (pnext = &(gvc->
apis[api]); *pnext; pnext = &((*pnext)->next)) {
540 if ((*pnext)->package == package) {
541 t = q = strdup((*pnext)->typestr);
542 if ((p = strchr(q,
':')))
555 if (!strncmp(q,
"jp", 2)) {
557 lq =
"jpeg\\njpe\\njpg";
559 else if (!strncmp(q,
"tif", 3)) {
563 else if (!strcmp(q,
"x11") || !strcmp(q,
"xlib")) {
567 else if (!strcmp(q,
"dot") || !strcmp(q,
"gv")) {
579 if (api == API_device) {
588 strcpy(bufb,
"render_cg");
600 strcpy(bufb, api_names[api]);
603 renderer_n = n =
agnode(ssg, bufb, 1);
610 strcpy(bufb, api_names[api]);
613 textlayout_n = n =
agnode(ssg, bufb, 1);
615 agxset(n, a,
"invtriangle");
621 strcpy(bufb, api_names[api]);
624 layout_n = n =
agnode(ssg, bufb, 1);
638 if (api == API_loadimage && !loadimage_n) {
639 neededge_loadimage = 1;
640 strcpy(buf2,
"invis");
641 loadimage_n = n =
agnode(ssg, bufa, 1);
649 strcpy(buf2,
"invis_src");
660 if (api == API_render && !renderer_n) {
661 neededge_loadimage = 1;
663 strcpy(buf2,
"invis");
664 renderer_n = n =
agnode(ssg, bufa, 1);
670 if (api == API_device && !device_n) {
672 strcpy(buf2,
"invis");
673 device_n = n =
agnode(ssg, bufa, 1);
682 if (neededge_loadimage) {
683 e =
agedge(sg, loadimage_n, renderer_n,
NULL, 1);
687 if (neededge_device) {
688 e =
agedge(sg, renderer_n, device_n,
NULL, 1);
693 e =
agedge(sg, loadimage_n, textlayout_n,
NULL, 1);
698 e =
agedge(sg, loadimage_n, layout_n,
NULL, 1);
704 ssg =
agsubg(g,
"output_formats", 1);
707 for (package = gvc->
packages; package; package = package->
next) {
708 strcpy(bufa, package->
name);
710 buf1 = bufa + strlen(bufa);
711 for (api = 0; api <
ARRAY_SIZE(api_names); api++) {
712 strcpy(buf1, api_names[api]);
714 buf2 = bufa + strlen(bufa);
715 for (pnext = &(gvc->
apis[api]); *pnext; pnext = &((*pnext)->next)) {
716 if ((*pnext)->package == package) {
717 t = q = strdup((*pnext)->typestr);
718 if ((p = strchr(q,
':')))
726 if (!strncmp(q,
"jp", 2)) {
728 lq =
"jpeg\\njpe\\njpg";
730 else if (!strncmp(q,
"tif", 3)) {
734 else if (!strcmp(q,
"x11") || !strcmp(q,
"xlib")) {
738 else if (!strcmp(q,
"dot") || !strcmp(q,
"gv")) {
747 strcpy(bufb,
"output_");
761 strcpy(bufb,
"render_");
774 strcpy(bufb,
"input_");
787 strcpy(bufb,
"render_");
void s1(graph_t *, node_t *)
char * gvconfig_libdir(GVC_t *gvc)
CGRAPH_API Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
#define RALLOC(size, ptr, type)
CGRAPH_API Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
Agsym_t * agattr(Agraph_t *g, int kind, char *name, char *value)
void * grealloc(void *ptr, size_t size)
gvplugin_package_t * next
int agxset(void *obj, Agsym_t *sym, char *value)
gvplugin_available_t * next
size_t agxbput(agxbuf *xb, const char *s)
void * gmalloc(size_t nbytes)
gvplugin_available_t * api[APIS]
int agerr(agerrlevel_t level, const char *fmt,...)
gvplugin_available_t * gvplugin_load(GVC_t *gvc, api_t api, const char *type)
char ** gvPluginList(GVC_t *gvc, const char *kind, int *sz, char *)
char * gvplugin_api_name(api_t api)
CGRAPH_API Agdesc_t Agdirected
CGRAPH_API Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
gvplugin_package_t * packages
Agraph_t * gvplugin_graph(GVC_t *gvc)
#define agfindedgeattr(g, a)
void gvplugin_write_status(GVC_t *gvc)
void agxbinit(agxbuf *xb, unsigned int hint, unsigned char *init)
boolean gvplugin_install(GVC_t *gvc, api_t api, const char *typestr, int quality, gvplugin_package_t *package, gvplugin_installed_t *typeptr)
#define agfindgraphattr(g, a)
int strcasecmp(const char *s1, const char *s2)
char * gvplugin_list(GVC_t *gvc, api_t api, const char *str)
CGRAPH_API Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
#define agfindedge(g, t, h)
gvplugin_available_t * apis[APIS]
gvplugin_installed_t * types
gvplugin_library_t * gvplugin_library_load(GVC_t *gvc, char *path)
api_t gvplugin_api(char *str)
gvplugin_installed_t * typeptr
#define agfindnodeattr(g, a)
gvplugin_package_t * package