78 char *
const t = strdup(typestr);
96 pnext = &(*pnext)->
next;
107 if (quality >= (*pnext)->quality)
109 pnext = &(*pnext)->
next;
113 plugin->
next = *pnext;
131 const char *name,
const char *plugin_path,
140 if (strcasecmp(typestr, pnext->
typestr) == 0
143 && strcasecmp(plugin_path, pnext->
package->
path) == 0) {
158 char *
suffix =
"_LTX_library";
166 if (pathname[1] ==
':') {
168 if (pathname[0] ==
'/') {
176 agerrorf(
"failed to init libltdl\n");
183 if (access(p, R_OK) == 0) {
184 agwarningf(
"Could not load \"%s\" - %s\n", p,
"It was found, so perhaps one of its dependents was not. Try ldd.");
187 agwarningf(
"Could not load \"%s\" - %s\n", p, lt_dlerror());
193 fprintf(stderr,
"Loading %s\n", p);
197#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
198 if (
len < strlen(
"/gvplugin_x")) {
200 if (
len < strlen(
"/libgvplugin_x")) {
202 agerrorf(
"invalid plugin path \"%s\"\n", p);
207#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
212#if defined(__CYGWIN__) || defined(__MINGW32__)
213 s = strchr(sym,
'-');
215 s = strchr(sym,
'.');
219 ptr = lt_dlsym(hndl, sym);
221 agerrorf(
"failed to resolve %s in %s\n", sym, p);
233 agerrorf(
"dynamic loading not available\n");
260 if (api == API_device || api == API_loadimage)
272 if (reqtyp.
data[reqtyp.
size] ==
':') {
274 if (reqdep.
data[reqdep.
size] ==
':') {
282 for (pnext =
gvc->
apis[api]; pnext; pnext = pnext->
next) {
291 agxbprint(&diag,
"# type \"%.*s\" did not match \"%.*s\"\n",
298 "# dependencies \"%.*s\" did not match \"%.*s\"\n",
307 if (dep.
data && apidep != api)
310 "# plugin loading of dependency \"%.*s\" failed\n",
325 for (i = 0; types[i].
type; i++) {
338 agxbprint(&diag,
"# unsuccessful plugin load\n");
376 for (pnext = plugin; pnext; pnext = pnext->
next) {
379 bool already_seen =
false;
382 already_seen |= strcasecmp(pnext->
typestr, p->typestr) == 0 &&
383 strcasecmp(pnext->
package->
name, p->package->name) == 0;
400 for (pnext = plugin; pnext; pnext = pnext->
next) {
429 LIST(
char *) list = {0};
438 agerrorf(
"unrecognized api name \"%s\"\n", kind);
445 for (pnext = plugin; pnext; pnext = pnext->
next) {
467 fprintf(stderr,
"The plugin configuration file:\n\t%s\n",
gvc->
config_path);
469 fprintf(stderr,
"\t\twas successfully loaded.\n");
471 fprintf(stderr,
"\t\twas not found or not usable. No on-demand plugins.\n");
473 fprintf(stderr,
"Demand loading of plugins is disabled.\n");
512 Agnode_t *loadimage_n = NULL;
517 bool neededge_loadimage =
false;
518 bool neededge_device =
false;
519 agxbprint(&buf,
"cluster_%s", package->name);
529 if (pnext->package == package) {
530 char *
const t =
gv_strdup(pnext->typestr);
532 if ((p = strchr(q,
':')))
539 case API_loadimage: {
547 lq =
"jpeg\\njpe\\njpg";
553 else if (!strcmp(q,
"x11") || !strcmp(q,
"xlib")) {
557 else if (!strcmp(q,
"dot") || !strcmp(q,
"gv")) {
562 agxbprint(&buf,
"%s_%s_%s", package->name,
570 if (api == API_device) {
581 m =
agnode(sg,
"render_cg", 1);
598 case API_textlayout: {
605 agxset(n, a,
"invtriangle");
629 if (api == API_loadimage && !loadimage_n) {
630 neededge_loadimage =
true;
641 agxbprint(&buf,
"%s_%s_invis_src", package->name,
653 if (api == API_render && !renderer_n) {
654 neededge_loadimage =
true;
655 neededge_device =
true;
664 if (api == API_device && !device_n) {
665 neededge_device =
true;
677 if (neededge_loadimage) {
682 if (neededge_device) {
705 if (pnext->package == package) {
706 char *
const t =
gv_strdup(pnext->typestr);
708 if ((p = strchr(q,
':')))
718 lq =
"jpeg\\njpe\\njpg";
724 else if (!strcmp(q,
"x11") || !strcmp(q,
"xlib")) {
728 else if (!strcmp(q,
"dot") || !strcmp(q,
"gv")) {
735 agxbprint(&buf,
"%s_%s_%s", package->name,
739 char *
const output =
agxbuse(&buf);
742 m =
agnode(ssg, output, 1);
763 case API_loadimage: {
764 agxbprint(&buf,
"%s_%s_%s", package->name,
768 char *
const input =
agxbuse(&buf);
Dynamically expanding string buffers.
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_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text 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
type-generic dynamically expanding list
#define LIST_DETACH(list, datap, sizep)
#define LIST_APPEND(list, item)
File system path helpers.
#define PATH_SEPARATOR
character for separating directory components in a file system path
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