98 pnext = &(*pnext)->
next;
109 if (quality >= (*pnext)->quality)
111 pnext = &(*pnext)->
next;
115 plugin->
next = *pnext;
133 const char *name,
const char *plugin_path,
142 if (strcasecmp(typestr, pnext->
typestr) == 0
145 && strcasecmp(plugin_path, pnext->
package->
path) == 0) {
160 char *
suffix =
"_LTX_library";
168 if (pathname[1] ==
':') {
170 if (pathname[0] ==
'/') {
178 agerrorf(
"failed to init libltdl\n");
185 if (access(p, R_OK) == 0) {
186 agwarningf(
"Could not load \"%s\" - %s\n", p,
"It was found, so perhaps one of its dependents was not. Try ldd.");
189 agwarningf(
"Could not load \"%s\" - %s\n", p, lt_dlerror());
195 fprintf(stderr,
"Loading %s\n", p);
199#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
200 if (
len < strlen(
"/gvplugin_x")) {
202 if (
len < strlen(
"/libgvplugin_x")) {
204 agerrorf(
"invalid plugin path \"%s\"\n", p);
209#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
214#if defined(__CYGWIN__) || defined(__MINGW32__)
215 s = strchr(sym,
'-');
217 s = strchr(sym,
'.');
221 ptr = lt_dlsym(hndl, sym);
223 agerrorf(
"failed to resolve %s in %s\n", sym, p);
232 agerrorf(
"dynamic loading not available\n");
259 if (api == API_device || api == API_loadimage)
271 if (reqtyp.
data[reqtyp.
size] ==
':') {
273 if (reqdep.
data[reqdep.
size] ==
':') {
281 for (pnext =
gvc->
apis[api]; pnext; pnext = pnext->
next) {
290 agxbprint(&diag,
"# type \"%.*s\" did not match \"%.*s\"\n",
297 "# dependencies \"%.*s\" did not match \"%.*s\"\n",
306 if (dep.
data && apidep != api)
309 "# plugin loading of dependency \"%.*s\" failed\n",
324 for (i = 0; types[i].
type; i++) {
337 agxbprint(&diag,
"# unsuccessful plugin load\n");
375 for (pnext = plugin; pnext; pnext = pnext->
next) {
378 bool already_seen =
false;
381 already_seen |= strcasecmp(pnext->
typestr, p->typestr) == 0 &&
382 strcasecmp(pnext->
package->
name, p->package->name) == 0;
399 for (pnext = plugin; pnext; pnext = pnext->
next) {
439 agerrorf(
"unrecognized api name \"%s\"\n", kind);
446 for (pnext = plugin; pnext; pnext = pnext->
next) {
455 *sz = (int)strs_size(&list);
456 return strs_detach(&list);
465 fprintf(stderr,
"The plugin configuration file:\n\t%s\n",
gvc->
config_path);
467 fprintf(stderr,
"\t\twas successfully loaded.\n");
469 fprintf(stderr,
"\t\twas not found or not usable. No on-demand plugins.\n");
471 fprintf(stderr,
"Demand loading of plugins is disabled.\n");
487 Agnode_t *n, *m, *loadimage_n, *renderer_n, *device_n, *textlayout_n, *layout_n;
492 char *p, *q, *lq, *t;
493 int neededge_loadimage, neededge_device;
516 for (package =
gvc->
packages; package;
package = package->next) {
517 loadimage_n = renderer_n = device_n = textlayout_n = layout_n = NULL;
518 neededge_loadimage = neededge_device = 0;
528 for (pnext =
gvc->
apis[api]; pnext; pnext = pnext->
next) {
529 if (pnext->
package == package) {
531 if ((p = strchr(q,
':')))
546 lq =
"jpeg\\njpe\\njpg";
552 else if (!strcmp(q,
"x11") || !strcmp(q,
"xlib")) {
556 else if (!strcmp(q,
"dot") || !strcmp(q,
"gv")) {
569 if (api == API_device) {
580 m =
agnode(sg,
"render_cg", 1);
600 agxset(n, a,
"invtriangle");
621 if (api == API_loadimage && !loadimage_n) {
622 neededge_loadimage = 1;
644 if (api == API_render && !renderer_n) {
645 neededge_loadimage = 1;
654 if (api == API_device && !device_n) {
666 if (neededge_loadimage) {
667 e =
agedge(sg, loadimage_n, renderer_n,
NULL, 1);
671 if (neededge_device) {
672 e =
agedge(sg, renderer_n, device_n,
NULL, 1);
677 e =
agedge(sg, loadimage_n, textlayout_n,
NULL, 1);
682 e =
agedge(sg, loadimage_n, layout_n,
NULL, 1);
688 ssg =
agsubg(g,
"output_formats", 1);
691 for (package =
gvc->
packages; package;
package = package->next) {
693 for (pnext =
gvc->
apis[api]; pnext; pnext = pnext->
next) {
694 if (pnext->
package == package) {
696 if ((p = strchr(q,
':')))
706 lq =
"jpeg\\njpe\\njpg";
712 else if (!strcmp(q,
"x11") || !strcmp(q,
"xlib")) {
716 else if (!strcmp(q,
"dot") || !strcmp(q,
"gv")) {
727 char *
const output =
agxbuse(&buf);
730 m =
agnode(ssg, output, 1);
751 case API_loadimage: {
756 char *
const input =
agxbuse(&buf);
static void agxbfree(agxbuf *xb)
free any malloced resources
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
static WUR char * agxbuse(agxbuf *xb)
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
static void * gv_alloc(size_t size)
static double len(glCompPoint p)
Agsym_t * agattr(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up attributes of a graph
int agxset(void *obj, Agsym_t *sym, const char *value)
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
#define agfindedgeattr(g, a)
#define agfindedge(g, t, h)
void agwarningf(const char *fmt,...)
void agerrorf(const char *fmt,...)
#define agfindgraphattr(g, a)
Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
creates a new graph with the given name and kind
Agdesc_t Agdirected
directed
Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
#define agfindnodeattr(g, a)
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
char ** gvPluginList(GVC_t *gvc, const char *kind, int *sz)
Graphviz context library.
char * gvconfig_libdir(GVC_t *gvc)
void gvplugin_write_status(GVC_t *gvc)
static char * api_names[]
gvplugin_library_t * gvplugin_library_load(GVC_t *gvc, const char *pathname)
static void gvplugin_activate(GVC_t *gvc, api_t api, const char *typestr, const char *name, const char *plugin_path, gvplugin_installed_t *typeptr)
api_t gvplugin_api(const char *str)
gvplugin_available_t * gvplugin_load(GVC_t *gvc, api_t api, const char *str, FILE *debug)
Agraph_t * gvplugin_graph(GVC_t *gvc)
char * gvplugin_api_name(api_t api)
bool gvplugin_install(GVC_t *gvc, api_t api, const char *typestr, int quality, gvplugin_package_t *package, gvplugin_installed_t *typeptr)
char * gvplugin_list(GVC_t *gvc, api_t api, const char *str)
static gvplugin_api_t apis[]
textitem scanner parser str
#define DEFINE_LIST(name, type)
static bool startswith(const char *s, const char *prefix)
does the string s begin with the string prefix?
platform abstraction for case-insensitive string functions
gvplugin_package_t * packages
gvplugin_available_t * apis[APIS]
gvplugin_available_t * api[APIS]
size_t size
number of characters in the buffer
gvplugin_installed_t * types
gvplugin_package_t * package
gvplugin_available_t * next
gvplugin_installed_t * typeptr
a non-owning string reference
const char * data
start of the pointed to string
size_t size
extent of the string in bytes
Non-owning string references.
static bool strview_str_eq(strview_t a, const char *b)
compare a string reference to a string for equality
static int strview_cmp(strview_t a, strview_t b)
compare two string references
static char * strview_str(strview_t source)
make a heap-allocated string from this string view
static bool strview_eq(strview_t a, strview_t b)
compare two string references for equality
static bool strview_case_eq(strview_t a, strview_t b)
compare two string references for case insensitive equality
static strview_t strview(const char *referent, char terminator)
create a string reference
graphs, nodes and edges info: Agraphinfo_t, Agnodeinfo_t and Agedgeinfo_t