diff --git a/src/variable.c b/src/variable.c index 6ac8075..84cd416 100644 --- a/src/variable.c +++ b/src/variable.c @@ -280,8 +280,11 @@ static const struct path_table fontpath_tbl[] = { "$`kpsexpand '$TEXMFDIST'`/fonts/type1!" }, #endif /* Linux paths */ - { "/usr/X11R6/lib/X11/fonts/Type1" }, - { "/usr/X11R6/lib/X11/fonts/truetype" }, + { "/usr/share/fonts/default/ghostscript/" }, + { "/usr/share/fonts/default/Type1/" }, + { "/usr/share/fonts/bitstream-vera/" }, + { "/usr/share/fonts/dejavu-lgc" }, + { "/usr/share/fonts/liberation" }, /* HP-UX */ { "/usr/lib/X11/fonts!"}, /* Ghostscript */ diff --git a/src/variable.c.refto b/src/variable.c.refto new file mode 100644 index 0000000..6ac8075 --- /dev/null +++ b/src/variable.c.refto @@ -0,0 +1,625 @@ +#ifndef lint +static char *RCSid() { return RCSid("$Id: variable.c,v 1.44 2013/07/02 22:19:09 sfeam Exp $"); } +#endif + +/* GNUPLOT - variable.c */ + +/*[ + * Copyright 1999, 2004 Lars Hecking + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted, but not the right to + * distribute the complete modified source code. Modifications are to + * be distributed as patches to the released version. Permission to + * distribute binaries produced by compiling modified sources is granted, + * provided you + * 1. distribute the corresponding source modifications from the + * released version in the form of a patch file along with the binaries, + * 2. add special version identification to distinguish your version + * in addition to the base release version number, + * 3. provide your name and address as the primary contact for the + * support of your modified version, and + * 4. retain our contact information in regard to use of the base + * software. + * Permission to distribute the released version of the source code along + * with corresponding source modifications in the form of a patch file is + * granted with same provisions 2 through 4 for binary distributions. + * + * This software is provided "as is" without express or implied warranty + * to the extent permitted by applicable law. +]*/ + +/* The Death of Global Variables - part one. */ + +#include + +#include "variable.h" + +#include "alloc.h" +#include "command.h" +#include "plot.h" +#include "util.h" +#include "term_api.h" + +#define PATHSEP_TO_NUL(arg) \ +do { \ + char *s = arg; \ + while ((s = strchr(s, PATHSEP)) != NULL) \ + *s++ = NUL; \ +} while (0) + +#define PRINT_PATHLIST(start, limit) \ +do { \ + char *s = start; \ + \ + while (s < limit) { \ + fprintf(stderr, "\"%s\" ", s); \ + s += strlen(s) + 1; \ + } \ + fputc('\n',stderr); \ +} while (0) + +/* + * char *loadpath_handler (int, char *) + * + */ +char * +loadpath_handler(int action, char *path) +{ + /* loadpath variable + * the path elements are '\0' separated (!) + * this way, reading out loadpath is very + * easy to implement */ + static char *loadpath; + /* index pointer, end of loadpath, + * env section of loadpath, current limit, in that order */ + static char *p, *last, *envptr, *limit; +#ifdef X11 + char *appdir; +#endif + + switch (action) { + case ACTION_CLEAR: + /* Clear loadpath, fall through to init */ + FPRINTF((stderr, "Clear loadpath\n")); + free(loadpath); + loadpath = p = last = NULL; + /* HBB 20000726: 'limit' has to be initialized to NULL, too! */ + limit = NULL; + case ACTION_INIT: + /* Init loadpath from environment */ + FPRINTF((stderr, "Init loadpath from environment\n")); + assert(loadpath == NULL); + if (!loadpath) + { + char *envlib = getenv("GNUPLOT_LIB"); + if (envlib) { + int len = strlen(envlib); + loadpath = gp_strdup(envlib); + /* point to end of loadpath */ + last = loadpath + len; + /* convert all PATHSEPs to \0 */ + PATHSEP_TO_NUL(loadpath); + } /* else: NULL = empty */ + } /* else: already initialised; int_warn (?) */ + /* point to env portion of loadpath */ + envptr = loadpath; + break; + case ACTION_SET: + /* set the loadpath */ + FPRINTF((stderr, "Set loadpath\n")); + if (path && *path != NUL) { + /* length of env portion */ + size_t elen = last - envptr; + size_t plen = strlen(path); + if (loadpath && envptr) { + /* we are prepending a path name; because + * realloc() preserves only the contents up + * to the minimum of old and new size, we move + * the part to be preserved to the beginning + * of the string; use memmove() because strings + * may overlap */ + memmove(loadpath, envptr, elen + 1); + } + loadpath = gp_realloc(loadpath, elen + 1 + plen + 1, "expand loadpath"); + /* now move env part back to the end to make space for + * the new path */ + memmove(loadpath + plen + 1, loadpath, elen + 1); + strcpy(loadpath, path); + /* separate new path(s) and env path(s) */ + loadpath[plen] = PATHSEP; + /* adjust pointer to env part and last */ + envptr = &loadpath[plen+1]; + last = envptr + elen; + PATHSEP_TO_NUL(loadpath); + } /* else: NULL = empty */ + break; + case ACTION_SHOW: + /* print the current, full loadpath */ + FPRINTF((stderr, "Show loadpath\n")); + if (loadpath) { + fputs("\tloadpath is ", stderr); + PRINT_PATHLIST(loadpath, envptr); + if (envptr) { + /* env part */ + fputs("\tloadpath from GNUPLOT_LIB is ", stderr); + PRINT_PATHLIST(envptr, last); + } + } else + fputs("\tloadpath is empty\n", stderr); +#ifdef GNUPLOT_SHARE_DIR + fprintf(stderr,"\tgnuplotrc is read from %s\n",GNUPLOT_SHARE_DIR); +#endif +#ifdef X11 + if ((appdir = getenv("XAPPLRESDIR"))) { + fprintf(stderr,"\tenvironmental path for X11 application defaults: \"%s\"\n", + appdir); + } +#ifdef XAPPLRESDIR + else { + fprintf(stderr,"\tno XAPPLRESDIR found in the environment,\n"); + fprintf(stderr,"\t falling back to \"%s\"\n", XAPPLRESDIR); + } +#endif +#endif + break; + case ACTION_SAVE: + /* we don't save the load path taken from the + * environment, so don't go beyond envptr when + * extracting the path elements + */ + limit = envptr; + case ACTION_GET: + /* subsequent calls to get_loadpath() return all + * elements of the loadpath until exhausted + */ + FPRINTF((stderr, "Get loadpath\n")); + if (!loadpath) + return NULL; + if (!p) { + /* init section */ + p = loadpath; + if (!limit) + limit = last; + } else { + /* skip over '\0' */ + p += strlen(p) + 1; + } + if (p >= limit) + limit = p = NULL; + return p; + break; + case ACTION_NULL: + /* just return */ + default: + break; + } + + /* should always be ignored - points to the + * first path in the list */ + return loadpath; + +} + + + +struct path_table { + const char *dir; +}; + +/* + * Environmental variables are written as $(name). + * Commands are written as $`command`. + */ + +#if defined(OS2) && !defined(FONTPATHSET) +# define FONTPATHSET +static const struct path_table fontpath_tbl[] = +{ + { "$(BOOTDIR)/PSFONTS" }, + /* X11 */ + { "$(X11ROOT)/X11R6/lib/X11/fonts/Type1" }, + { NULL } +}; +#endif + +#if defined(_Windows) && !defined(FONTPATHSET) +# define FONTPATHSET +static const struct path_table fontpath_tbl[] = +{ + { "$(windir)\\fonts" }, + /* Ghostscript */ + { "c:\\gs\\fonts" }, + /* X11 */ + { "$(CYGWIN_ROOT)\\usr\\X11R6\\lib\\X11\\fonts\\Type1" }, +#ifdef HAVE_KPSEXPAND + /* fpTeX */ + { "$`kpsewhich -expand-path=$HOMETEXMF`\\fonts\\type1!" }, + { "$`kpsewhich -expand-path=$TEXMFLOCAL`\\fonts\\type1!" }, + { "$`kpsewhich -expand-path=$TEXMFMAIN`\\fonts\\type1!" }, + { "$`kpsewhich -expand-path=$TEXMFDIST`\\fonts\\type1!" }, +#endif + { NULL } +}; +#endif + +#if defined(__APPLE__) && !defined(FONTPATHSET) +# define FONTPATHSET +static const struct path_table fontpath_tbl[] = +{ + { "/System/Library/Fonts!" }, + { "/Library/Fonts!" }, + { "$(HOME)/Library/Fonts!" }, + { NULL } +}; +#endif + +#if defined(VMS) && !defined(FONTPATHSET) +# define FONTPATHSET +static const struct path_table fontpath_tbl[] = +{ + { "SYS$COMMON:[SYSFONT]!" }, + { NULL } +}; +#endif + +/* Fallback: Should work for unix */ +#ifndef FONTPATHSET +static const struct path_table fontpath_tbl[] = +{ +#ifdef HAVE_KPSEXPAND + /* teTeX or TeXLive */ + { "$`kpsexpand '$HOMETEXMF'`/fonts/type1!" }, + { "$`kpsexpand '$TEXMFLOCAL'`/fonts/type1!" }, + { "$`kpsexpand '$TEXMFMAIN'`/fonts/type1!" }, + { "$`kpsexpand '$TEXMFDIST'`/fonts/type1!" }, +#endif + /* Linux paths */ + { "/usr/X11R6/lib/X11/fonts/Type1" }, + { "/usr/X11R6/lib/X11/fonts/truetype" }, + /* HP-UX */ + { "/usr/lib/X11/fonts!"}, + /* Ghostscript */ + { "/usr/share/ghostscript/fonts" }, + { "/usr/local/share/ghostscript/fonts" }, + { NULL } +}; +#endif + +#undef FONTPATHSET + +static TBOOLEAN fontpath_init_done = FALSE; + +/* + * char *fontpath_handler (int, char *) + * + */ +char * +fontpath_handler(int action, char *path) +{ + /* fontpath variable + * the path elements are '\0' separated (!) + * this way, reading out fontpath is very + * easy to implement */ + static char *fontpath; + /* index pointer, end of fontpath, + * env section of fontpath, current limit, in that order */ + static char *p, *last, *envptr, *limit; + + if (!fontpath_init_done) { + fontpath_init_done = TRUE; + init_fontpath(); + } + + switch (action) { + case ACTION_CLEAR: + /* Clear fontpath, fall through to init */ + FPRINTF((stderr, "Clear fontpath\n")); + free(fontpath); + fontpath = p = last = NULL; + /* HBB 20000726: 'limit' has to be initialized to NULL, too! */ + limit = NULL; + case ACTION_INIT: + /* Init fontpath from environment */ + FPRINTF((stderr, "Init fontpath from environment\n")); + assert(fontpath == NULL); + if (!fontpath) + { + char *envlib = getenv("GNUPLOT_FONTPATH"); + if (envlib) { + /* get paths from environment */ + int len = strlen(envlib); + fontpath = gp_strdup(envlib); + /* point to end of fontpath */ + last = fontpath + len; + /* convert all PATHSEPs to \0 */ + PATHSEP_TO_NUL(fontpath); + } +#if defined(HAVE_DIRENT_H) || defined(_Windows) + else { + /* set hardcoded paths */ + const struct path_table *curr_fontpath = fontpath_tbl; + + while (curr_fontpath->dir) { + char *currdir = NULL; + char *envbeg = NULL; +# if defined(PIPES) + char *cmdbeg = NULL; +# endif + TBOOLEAN subdirs = FALSE; + + currdir = gp_strdup( curr_fontpath->dir ); + + while ( (envbeg=strstr(currdir, "$(")) +# if defined(PIPES) + || (cmdbeg=strstr( currdir, "$`" )) +# endif + ) { + /* Read environment variables */ + if (envbeg) { + char *tmpdir = NULL; + char *envend = NULL, *envval = NULL; + unsigned int envlen; + envend = strchr(envbeg+2,')'); + envend[0] = '\0'; + envval = getenv(envbeg+2); + envend[0] = ')'; + envlen = envval ? strlen(envval) : 0; + tmpdir = gp_alloc(strlen(currdir)+envlen + +envbeg-envend+1, + "expand fontpath"); + strncpy(tmpdir,currdir,envbeg-currdir); + if (envval) + strcpy(tmpdir+(envbeg-currdir),envval); + strcpy(tmpdir+(envbeg-currdir+envlen), envend+1); + + free(currdir); + currdir = tmpdir; + } +# if defined(PIPES) + /* Read environment variables */ + else if (cmdbeg) { + char *tmpdir = NULL; + char *envend = NULL; + char envval[256]; + unsigned int envlen; + FILE *fcmd; + envend = strchr(cmdbeg+2,'`'); + envend[0] = '\0'; + restrict_popen(); + fcmd = popen(cmdbeg+2,"r"); + if (fcmd) { + fgets(envval,255,fcmd); + if (envval[strlen(envval)-1]=='\n') + envval[strlen(envval)-1]='\0'; + pclose(fcmd); + } + envend[0] = '`'; + envlen = strlen(envval); + tmpdir = gp_alloc(strlen(currdir)+envlen + +cmdbeg-envend+1, + "expand fontpath"); + strncpy(tmpdir,currdir,cmdbeg-currdir); + if (*envval) + strcpy(tmpdir+(cmdbeg-currdir),envval); + strcpy(tmpdir+(cmdbeg-currdir+envlen), envend+1); + + free(currdir); + currdir = tmpdir; + } +# endif + } + + if ( currdir[strlen(currdir)-1] == '!' ) { + /* search subdirectories */ + /* delete ! from directory name */ + currdir[strlen(currdir)-1] = '\0'; + subdirs = TRUE; + } + + if ( existdir( currdir ) ) { + size_t plen; + if ( subdirs ) + /* add ! to directory name again */ + currdir[strlen(currdir)] = '!'; + plen = strlen(currdir); + if (fontpath) { + size_t elen = strlen(fontpath); + fontpath = gp_realloc(fontpath, + elen + 1 + plen + 1, + "expand fontpath"); + last = fontpath+elen; + *last = PATHSEP; + ++last; + *last = '\0'; + } else { + fontpath = gp_alloc(plen + 1, + "expand fontpath"); + last = fontpath; + } + + strcpy(last, currdir ); + last += plen; + } + curr_fontpath++; + if (currdir) { + free(currdir); + currdir = NULL; + } + } + /* convert all PATHSEPs to \0 */ + if (fontpath) + PATHSEP_TO_NUL(fontpath); + } +#endif /* HAVE_DIRENT_H */ + + } /* else: already initialised; int_warn (?) */ + /* point to env portion of fontpath */ + envptr = fontpath; + break; + case ACTION_SET: + /* set the fontpath */ + FPRINTF((stderr, "Set fontpath\n")); + if (path && *path != NUL) { + /* length of env portion */ + size_t elen = last - envptr; + size_t plen = strlen(path); + if (fontpath && envptr) { + /* we are prepending a path name; because + * realloc() preserves only the contents up + * to the minimum of old and new size, we move + * the part to be preserved to the beginning + * of the string; use memmove() because strings + * may overlap */ + memmove(fontpath, envptr, elen + 1); + } + fontpath = gp_realloc(fontpath, elen + 1 + plen + 1, "expand fontpath"); + /* now move env part back to the end to make space for + * the new path */ + memmove(fontpath + plen + 1, fontpath, elen + 1); + strcpy(fontpath, path); + /* separate new path(s) and env path(s) */ + fontpath[plen] = PATHSEP; + /* adjust pointer to env part and last */ + envptr = &fontpath[plen+1]; + last = envptr + elen; + PATHSEP_TO_NUL(fontpath); + } /* else: NULL = empty */ + break; + case ACTION_SHOW: + /* print the current, full fontpath */ + FPRINTF((stderr, "Show fontpath\n")); + if (fontpath) { + fputs("\tfontpath is ", stderr); + PRINT_PATHLIST(fontpath, envptr); + if (envptr) { + /* env part */ + fputs("\tsystem fontpath is ", stderr); + PRINT_PATHLIST(envptr, last); + } + } else + fputs("\tfontpath is empty\n", stderr); + break; + case ACTION_SAVE: + /* we don't save the font path taken from the + * environment, so don't go beyond envptr when + * extracting the path elements + */ + limit = envptr; + case ACTION_GET: + /* subsequent calls to get_fontpath() return all + * elements of the fontpath until exhausted + */ + FPRINTF((stderr, "Get fontpath\n")); + if (!fontpath) + return NULL; + if (!p) { + /* init section */ + p = fontpath; + if (!limit) + limit = last; + } else { + /* skip over '\0' */ + p += strlen(p) + 1; + } + if (p >= limit) + limit = p = NULL; + return p; + case ACTION_NULL: + /* just return */ + default: + break; + } + + /* should always be ignored - points to the + * first path in the list */ + return fontpath; + +} + +/* not set or shown directly, but controlled by 'set locale' + * defined in national.h + */ + +char full_month_names[12][32] = +{ FMON01, FMON02, FMON03, FMON04, FMON05, FMON06, FMON07, FMON08, FMON09, FMON10, FMON11, FMON12 }; +char abbrev_month_names[12][8] = +{ AMON01, AMON02, AMON03, AMON04, AMON05, AMON06, AMON07, AMON08, AMON09, AMON10, AMON11, AMON12 }; + +char full_day_names[7][32] = +{ FDAY0, FDAY1, FDAY2, FDAY3, FDAY4, FDAY5, FDAY6 }; +char abbrev_day_names[7][8] = +{ ADAY0, ADAY1, ADAY2, ADAY3, ADAY4, ADAY5, ADAY6 }; + +char * +locale_handler(int action, char *newlocale) +{ + struct tm tm; + int i; + + switch(action) { + case ACTION_CLEAR: + case ACTION_INIT: + free(current_locale); +#ifdef HAVE_LOCALE_H + setlocale(LC_TIME, ""); + setlocale(LC_CTYPE, ""); + current_locale = gp_strdup(setlocale(LC_TIME,NULL)); +#else + current_locale = gp_strdup(INITIAL_LOCALE); +#endif + break; + + case ACTION_SET: +#ifdef HAVE_LOCALE_H + if (setlocale(LC_TIME, newlocale)) { + free(current_locale); + current_locale = gp_strdup(setlocale(LC_TIME,NULL)); + } else { + int_error(c_token, "Locale not available"); + } + + /* we can do a *lot* better than this ; eg use system functions + * where available; create values on first use, etc + */ + memset(&tm, 0, sizeof(struct tm)); + for (i = 0; i < 7; ++i) { + tm.tm_wday = i; /* hope this enough */ + strftime(full_day_names[i], sizeof(full_day_names[i]), "%A", &tm); + strftime(abbrev_day_names[i], sizeof(abbrev_day_names[i]), "%a", &tm); + } + for (i = 0; i < 12; ++i) { + tm.tm_mon = i; /* hope this enough */ + strftime(full_month_names[i], sizeof(full_month_names[i]), "%B", &tm); + strftime(abbrev_month_names[i], sizeof(abbrev_month_names[i]), "%b", &tm); + } +#else + current_locale = gp_realloc(current_locale, strlen(newlocale) + 1, "locale"); + strcpy(current_locale, newlocale); +#endif /* HAVE_LOCALE_H */ + break; + + case ACTION_SHOW: +#ifdef HAVE_LOCALE_H + fprintf(stderr, "\tgnuplot LC_CTYPE %s\n", setlocale(LC_CTYPE,NULL)); + fprintf(stderr, "\tgnuplot encoding %s\n", encoding_names[encoding]); + fprintf(stderr, "\tgnuplot LC_TIME %s\n", setlocale(LC_TIME,NULL)); + fprintf(stderr, "\tgnuplot LC_NUMERIC %s\n", numeric_locale ? numeric_locale : "C"); +#else + fprintf(stderr, "\tlocale is \"%s\"\n", current_locale); +#endif + break; + + case ACTION_GET: + default: + break; + } + + return current_locale; +} +