22 #include <sys/types.h>
25 #define GLOB_NOSPACE 1
26 #define GLOB_ABORTED 2
27 #define GLOB_NOMATCH 3
29 #define DMKEY "Software\\Microsoft" //key to look for library dir
37 static void globfree (glob_t* pglob);
38 static int glob (
GVC_t *
gvc,
char*,
int,
int (*errfunc)(
const char *,
int), glob_t*);
49 #include <mach-o/dyld.h>
97 package->name = strdup(name);
113 static void separator(
int *nest,
char **tokens)
139 if (c ==
' ' || c ==
'\n' || c ==
'\t') {
152 static char *token(
int *nest,
char **tokens)
159 || c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'{' || c ==
'}')
164 separator(nest, tokens);
169 static int gvconfig_plugin_install_from_config(
GVC_t * gvc,
char *s)
171 char *
path, *name, *api;
178 separator(&nest, &s);
180 path = token(&nest, &s);
182 name = token(&nest, &s);
185 package = gvplugin_package_record(gvc, path, name);
187 api = token(&nest, &s);
191 type = token(&nest, &s);
193 quality = atoi(token(&nest, &s));
197 type, quality, package,
NULL);
199 agerr(
AGERR,
"config error: %s %s %s\n", path, api, type);
217 package = gvplugin_package_record(gvc, path, library->packagename);
218 for (apis = library->
apis; (types = apis->
types); apis++) {
219 for (i = 0; types[i].
type; i++) {
221 types[i].
quality, package, &types[i]);
226 static void gvconfig_plugin_install_builtins(
GVC_t * gvc)
234 if (name[0] ==
'g' && strstr(name,
"_LTX_library"))
246 fprintf(f,
"%s %s {\n", path, library->
packagename);
247 for (apis = library->
apis; (types = apis->
types); apis++) {
249 for (i = 0; types[i].
type; i++) {
252 fprintf(f,
"#FAILS");
253 fprintf(f,
"\t\t%s %d\n", types[i].type, types[i].quality);
261 #define DOTLIBS "/.libs"
262 #define STRLEN(s) (sizeof(s)-1)
266 static char line[
BSZ];
268 static boolean dirShown = 0;
272 libdir=getenv(
"GVBINDIR");
278 MEMORY_BASIC_INFORMATION mbi;
280 agerr(
AGERR,
"failed to get handle for executable.\n");
283 r = GetModuleFileName ((HMODULE)mbi.AllocationBase, line,
BSZ);
284 if (!r || (r ==
BSZ)) {
285 agerr(
AGERR,
"failed to get path for executable.\n");
288 s = strrchr(line,
'\\');
298 uint32_t i, c = _dyld_image_count();
301 for (i = 0; i < c; ++i) {
302 path = _dyld_get_image_name(i);
303 tmp = strstr(path,
"/libgvc.");
309 while ((*s !=
'/') && (s > path)) s--;
310 if (strncmp (s, DOTLIBS,
STRLEN(DOTLIBS)) == 0)
315 len = ind +
sizeof(
"/graphviz");
320 bcopy (path, libdir, ind);
322 strcpy(libdir+ind,
"/graphviz");
327 FILE* f = fopen (
"/proc/self/maps",
"r");
331 if (!fgets (line,
sizeof (line), f))
333 if (!strstr (line,
" r-xp "))
335 path = strchr (line,
'/');
338 tmp = strstr (path,
"/libgvc.");
342 if (strcmp(strrchr(path,
'/'),
"/.libs") == 0)
345 strcat(line,
"/graphviz");
357 fprintf (stderr,
"libdir = \"%s\"\n", (libdir ? libdir :
"<null>"));
365 static void config_rescan(
GVC_t *gvc,
char *config_path)
369 char *config_glob, *config_re, *
path, *libdir;
370 int i, rc, re_status;
374 char *plugin_glob =
"libgvplugin_*";
376 #if defined(DARWIN_DYLIB)
377 char *plugin_re_beg =
"[^0-9]\\.";
378 char *plugin_re_end =
"\\.dylib$";
379 #elif defined(__MINGW32__)
380 char *plugin_glob =
"libgvplugin_*";
381 char *plugin_re_beg =
"[^0-9]-";
382 char *plugin_re_end =
"\\.dll$";
383 #elif defined(__CYGWIN__)
384 plugin_glob =
"cyggvplugin_*";
385 char *plugin_re_beg =
"[^0-9]-";
386 char *plugin_re_end =
"\\.dll$";
387 #elif defined(_WIN32)
388 char *plugin_glob =
"gvplugin_*";
389 char *plugin_re_beg =
"[^0-9]";
390 char *plugin_re_end =
"\\.dll$";
391 #elif ((defined(__hpux__) || defined(__hpux)) && !(defined(__ia64)))
392 char *plugin_re_beg =
"\\.sl\\.";
393 char *plugin_re_end =
"$";
396 char *plugin_re_beg =
"\\.so\\.";
397 char *plugin_re_end=
"$";
401 f = fopen(config_path,
"w");
403 agerr(
AGERR,
"failed to open %s for write.\n", config_path);
407 fprintf(f,
"# This file was generated by \"dot -c\" at time of install.\n\n");
408 fprintf(f,
"# You may temporarily disable a plugin by removing or commenting out\n");
409 fprintf(f,
"# a line in this file, or you can modify its \"quality\" value to affect\n");
410 fprintf(f,
"# default plugin selection.\n\n");
411 fprintf(f,
"# Manual edits to this file **will be lost** on upgrade.\n\n");
416 config_re =
gmalloc(strlen(plugin_re_beg) + 20 + strlen(plugin_re_end) + 1);
418 #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
419 sprintf(config_re,
"%s%s", plugin_re_beg, plugin_re_end);
420 #elif defined(GVPLUGIN_VERSION)
421 sprintf(config_re,
"%s%d%s", plugin_re_beg, GVPLUGIN_VERSION, plugin_re_end);
423 sprintf(config_re,
"%s[0-9]+%s", plugin_re_beg, plugin_re_end);
426 if (regcomp(&re, config_re, REG_EXTENDED|REG_NOSUB) != 0) {
427 agerr(
AGERR,
"cannot compile regular expression %s", config_re);
430 config_glob =
gmalloc(strlen(libdir) + 1 + strlen(plugin_glob) + 1);
431 strcpy(config_glob, libdir);
432 strcat(config_glob,
DIRSEP);
433 strcat(config_glob, plugin_glob);
438 rc = glob(gvc, config_glob, GLOB_NOSORT,
NULL, &globbuf);
440 rc = glob(config_glob, GLOB_NOSORT,
NULL, &globbuf);
443 for (i = 0; i < globbuf.gl_pathc; i++) {
444 re_status = regexec(&re, globbuf.gl_pathv[i], (
size_t) 0,
NULL, 0);
445 if (re_status == 0) {
453 for (i = 0; i < globbuf.gl_pathc; i++) {
454 re_status = regexec(&re, globbuf.gl_pathv[i], (
size_t) 0,
NULL, 0);
455 if (re_status == 0) {
458 path = strrchr(globbuf.gl_pathv[i],
DIRSEP[0]);
462 gvconfig_write_library_config(gvc, path, library, f);
486 struct stat config_st, libdir_st;
488 char *config_text =
NULL;
490 char *config_file_name = GVPLUGIN_CONFIG_FILE;
492 #define MAX_SZ_CONFIG 100000
496 gvconfig_plugin_install_builtins(gvc);
503 rc = stat(libdir, &libdir_st);
532 else if (config_st.st_size > MAX_SZ_CONFIG) {
542 config_text =
gmalloc(config_st.st_size + 1);
543 sz = fread(config_text, 1, config_st.st_size, f);
550 config_text[sz] =
'\0';
551 rc = gvconfig_plugin_install_from_config(gvc, config_text);
576 glob (
GVC_t* gvc,
char* pattern,
int flags,
int (*errfunc)(
const char *,
int), glob_t *pglob)
586 pglob->gl_pathv =
NULL;
588 h = FindFirstFile (pattern, &wfd);
589 if (h == INVALID_HANDLE_VALUE)
return GLOB_NOMATCH;
592 if (cnt >= arrsize-1) {
594 if (str) str = (
char**)realloc (str, arrsize*
sizeof(
char*));
595 else str = (
char**)malloc (arrsize*
sizeof(
char*));
596 if (!str)
return GLOB_NOSPACE;
598 str[cnt] = (
char*)malloc (strlen(libdir)+1+strlen(wfd.cFileName)+1);
599 if (!str[cnt])
return GLOB_NOSPACE;
600 strcpy(str[cnt],libdir);
602 strcat(str[cnt],wfd.cFileName);
604 }
while (FindNextFile (h, &wfd));
607 pglob->gl_pathc = cnt;
608 pglob->gl_pathv = (
char**)realloc(str, (cnt+1)*
sizeof(
char*));
614 globfree (glob_t* pglob)
617 for (i = 0; i < pglob->gl_pathc; i++)
618 free (pglob->gl_pathv[i]);
620 free (pglob->gl_pathv);
char * gvconfig_libdir(GVC_t *gvc)
void gvconfig(GVC_t *gvc, boolean rescan)
Dt_t * textfont_dict_open(GVC_t *gvc)
void * gmalloc(size_t nbytes)
int agerr(agerrlevel_t level, const char *fmt,...)
gvplugin_available_t * gvplugin_load(GVC_t *gvc, api_t api, const char *type)
const lt_symlist_t * builtins
char * gvplugin_api_name(api_t api)
gvplugin_package_t * packages
void gvconfig_plugin_install_from_library(GVC_t *gvc, char *path, gvplugin_library_t *library)
boolean gvplugin_install(GVC_t *gvc, api_t api, const char *typestr, int quality, gvplugin_package_t *package, gvplugin_installed_t *typeptr)
int gvtextlayout_select(GVC_t *gvc)
gvplugin_installed_t * types
gvplugin_library_t * gvplugin_library_load(GVC_t *gvc, char *path)
api_t gvplugin_api(char *str)