2 static char *RCSid() { return RCSid("$Id: variable.c,v 1.27.2.1 2008/12/12 07:14:11 sfeam Exp $"); }
5 /* GNUPLOT - variable.c */
8 * Copyright 1999, 2004 Lars Hecking
10 * Permission to use, copy, and distribute this software and its
11 * documentation for any purpose with or without fee is hereby granted,
12 * provided that the above copyright notice appear in all copies and
13 * that both that copyright notice and this permission notice appear
14 * in supporting documentation.
16 * Permission to modify the software is granted, but not the right to
17 * distribute the complete modified source code. Modifications are to
18 * be distributed as patches to the released version. Permission to
19 * distribute binaries produced by compiling modified sources is granted,
21 * 1. distribute the corresponding source modifications from the
22 * released version in the form of a patch file along with the binaries,
23 * 2. add special version identification to distinguish your version
24 * in addition to the base release version number,
25 * 3. provide your name and address as the primary contact for the
26 * support of your modified version, and
27 * 4. retain our contact information in regard to use of the base
29 * Permission to distribute the released version of the source code along
30 * with corresponding source modifications in the form of a patch file is
31 * granted with same provisions 2 through 4 for binary distributions.
33 * This software is provided "as is" without express or implied warranty
34 * to the extent permitted by applicable law.
37 /* The Death of Global Variables - part one. */
48 #define PATHSEP_TO_NUL(arg) \
51 while ((s = strchr(s, PATHSEP)) != NULL) \
55 #define PRINT_PATHLIST(start, limit) \
60 fprintf(stderr, "\"%s\" ", s); \
67 * char *loadpath_handler (int, char *)
71 loadpath_handler(int action, char *path)
74 * the path elements are '\0' separated (!)
75 * this way, reading out loadpath is very
76 * easy to implement */
77 static char *loadpath;
78 /* index pointer, end of loadpath,
79 * env section of loadpath, current limit, in that order */
80 static char *p, *last, *envptr, *limit;
84 /* Clear loadpath, fall through to init */
85 FPRINTF((stderr, "Clear loadpath\n"));
87 loadpath = p = last = NULL;
88 /* HBB 20000726: 'limit' has to be initialized to NULL, too! */
91 /* Init loadpath from environment */
92 FPRINTF((stderr, "Init loadpath from environment\n"));
93 assert(loadpath == NULL);
96 char *envlib = getenv("GNUPLOT_LIB");
98 int len = strlen(envlib);
99 loadpath = gp_strdup(envlib);
100 /* point to end of loadpath */
101 last = loadpath + len;
102 /* convert all PATHSEPs to \0 */
103 PATHSEP_TO_NUL(loadpath);
104 } /* else: NULL = empty */
105 } /* else: already initialised; int_warn (?) */
106 /* point to env portion of loadpath */
110 /* set the loadpath */
111 FPRINTF((stderr, "Set loadpath\n"));
112 if (path && *path != NUL) {
113 /* length of env portion */
114 size_t elen = last - envptr;
115 size_t plen = strlen(path);
116 if (loadpath && envptr) {
117 /* we are prepending a path name; because
118 * realloc() preserves only the contents up
119 * to the minimum of old and new size, we move
120 * the part to be preserved to the beginning
121 * of the string; use memmove() because strings
123 memmove(loadpath, envptr, elen + 1);
125 loadpath = gp_realloc(loadpath, elen + 1 + plen + 1, "expand loadpath");
126 /* now move env part back to the end to make space for
128 memmove(loadpath + plen + 1, loadpath, elen + 1);
129 strcpy(loadpath, path);
130 /* separate new path(s) and env path(s) */
131 loadpath[plen] = PATHSEP;
132 /* adjust pointer to env part and last */
133 envptr = &loadpath[plen+1];
134 last = envptr + elen;
135 PATHSEP_TO_NUL(loadpath);
136 } /* else: NULL = empty */
139 /* print the current, full loadpath */
140 FPRINTF((stderr, "Show loadpath\n"));
142 fputs("\tloadpath is ", stderr);
143 PRINT_PATHLIST(loadpath, envptr);
146 fputs("\tsystem loadpath is ", stderr);
147 PRINT_PATHLIST(envptr, last);
150 fputs("\tloadpath is empty\n", stderr);
153 /* we don't save the load path taken from the
154 * environment, so don't go beyond envptr when
155 * extracting the path elements
159 /* subsequent calls to get_loadpath() return all
160 * elements of the loadpath until exhausted
162 FPRINTF((stderr, "Get loadpath\n"));
184 /* should always be ignored - points to the
185 * first path in the list */
196 /* Yet, no special font paths for these operating systems:
197 * MSDOS, ATARI, AMIGA, MTOS, NeXT, ultrix, VMS, _IBMR2, alliant
199 * Environmental variables are written as $(name).
200 * Commands are written as $`command`.
203 #if defined(OS2) && !defined(FONTPATHSET)
205 static const struct path_table fontpath_tbl[] =
207 { "$(BOOTDIR)/PSFONTS" },
209 { "$(X11ROOT)/X11R6/lib/X11/fonts/Type1" },
214 #if defined(_Windows) && !defined(FONTPATHSET)
216 static const struct path_table fontpath_tbl[] =
218 { "$(windir)\\fonts" },
222 { "$(CYGWIN_ROOT)\\usr\\X11R6\\lib\\X11\\fonts\\Type1" },
223 #ifdef HAVE_KPSEXPAND
225 { "$`kpsewhich -expand-path=$HOMETEXMF`\\fonts\\type1!" },
226 { "$`kpsewhich -expand-path=$TEXMFLOCAL`\\fonts\\type1!" },
227 { "$`kpsewhich -expand-path=$TEXMFMAIN`\\fonts\\type1!" },
228 { "$`kpsewhich -expand-path=$TEXMFDIST`\\fonts\\type1!" },
234 #if defined(_Macintosh) && !defined(FONTPATHSET)
236 static const struct path_table fontpath_tbl[] =
238 { "/System/Library/Fonts!" },
239 { "/Library/Fonts!" },
240 { "$(HOME)/Library/Fonts!" },
245 #if defined(VMS) && !defined(FONTPATHSET)
247 static const struct path_table fontpath_tbl[] =
249 { "SYS$COMMON:[SYSFONT]!" },
254 /* Fallback: Should work for unix */
256 static const struct path_table fontpath_tbl[] =
258 #ifdef HAVE_KPSEXPAND
259 /* teTeX or TeXLive */
260 { "$`kpsexpand '$HOMETEXMF'`/fonts/type1!" },
261 { "$`kpsexpand '$TEXMFLOCAL'`/fonts/type1!" },
262 { "$`kpsexpand '$TEXMFMAIN'`/fonts/type1!" },
263 { "$`kpsexpand '$TEXMFDIST'`/fonts/type1!" },
266 { "/usr/X11R6/lib/X11/fonts/Type1" },
267 { "/usr/X11R6/lib/X11/fonts/truetype" },
269 { "/usr/lib/X11/fonts!"},
271 { "/usr/share/ghostscript/fonts" },
272 { "/usr/local/share/ghostscript/fonts" },
279 static TBOOLEAN fontpath_init_done = FALSE;
282 * char *fontpath_handler (int, char *)
286 fontpath_handler(int action, char *path)
289 * the path elements are '\0' separated (!)
290 * this way, reading out fontpath is very
291 * easy to implement */
292 static char *fontpath;
293 /* index pointer, end of fontpath,
294 * env section of fontpath, current limit, in that order */
295 static char *p, *last, *envptr, *limit;
297 if (!fontpath_init_done) {
298 fontpath_init_done = TRUE;
304 /* Clear fontpath, fall through to init */
305 FPRINTF((stderr, "Clear fontpath\n"));
307 fontpath = p = last = NULL;
308 /* HBB 20000726: 'limit' has to be initialized to NULL, too! */
311 /* Init fontpath from environment */
312 FPRINTF((stderr, "Init fontpath from environment\n"));
313 assert(fontpath == NULL);
316 char *envlib = getenv("GNUPLOT_FONTPATH");
318 /* get paths from environment */
319 int len = strlen(envlib);
320 fontpath = gp_strdup(envlib);
321 /* point to end of fontpath */
322 last = fontpath + len;
323 /* convert all PATHSEPs to \0 */
324 PATHSEP_TO_NUL(fontpath);
326 #if defined(HAVE_DIRENT_H) || defined(_Windows)
328 /* set hardcoded paths */
329 const struct path_table *curr_fontpath = fontpath_tbl;
331 while (curr_fontpath->dir) {
332 char *currdir = NULL;
337 TBOOLEAN subdirs = FALSE;
339 currdir = gp_strdup( curr_fontpath->dir );
341 while ( (envbeg=strstr(currdir, "$("))
343 || (cmdbeg=strstr( currdir, "$`" ))
346 /* Read environment variables */
349 char *envend = NULL, *envval = NULL;
351 envend = strchr(envbeg+2,')');
353 envval = getenv(envbeg+2);
355 envlen = envval ? strlen(envval) : 0;
356 tmpdir = gp_alloc(strlen(currdir)+envlen
359 strncpy(tmpdir,currdir,envbeg-currdir);
361 strcpy(tmpdir+(envbeg-currdir),envval);
362 strcpy(tmpdir+(envbeg-currdir+envlen), envend+1);
368 /* Read environment variables */
375 envend = strchr(cmdbeg+2,'`');
377 fcmd = popen(cmdbeg+2,"r");
379 fgets(envval,255,fcmd);
380 if (envval[strlen(envval)-1]=='\n')
381 envval[strlen(envval)-1]='\0';
385 envlen = strlen(envval);
386 tmpdir = gp_alloc(strlen(currdir)+envlen
389 strncpy(tmpdir,currdir,cmdbeg-currdir);
390 strcpy(tmpdir+(cmdbeg-currdir),envval);
391 strcpy(tmpdir+(cmdbeg-currdir+envlen), envend+1);
399 if ( currdir[strlen(currdir)-1] == '!' ) {
400 /* search subdirectories */
401 /* delete ! from directory name */
402 currdir[strlen(currdir)-1] = '\0';
406 if ( existdir( currdir ) ) {
409 /* add ! to directory name again */
410 currdir[strlen(currdir)] = '!';
411 plen = strlen(currdir);
413 size_t elen = strlen(fontpath);
414 fontpath = gp_realloc(fontpath,
417 last = fontpath+elen;
422 fontpath = gp_alloc(plen + 1,
427 strcpy(last, currdir );
436 /* convert all PATHSEPs to \0 */
438 PATHSEP_TO_NUL(fontpath);
440 #endif /* HAVE_DIRENT_H */
442 } /* else: already initialised; int_warn (?) */
443 /* point to env portion of fontpath */
447 /* set the fontpath */
448 FPRINTF((stderr, "Set fontpath\n"));
449 if (path && *path != NUL) {
450 /* length of env portion */
451 size_t elen = last - envptr;
452 size_t plen = strlen(path);
453 if (fontpath && envptr) {
454 /* we are prepending a path name; because
455 * realloc() preserves only the contents up
456 * to the minimum of old and new size, we move
457 * the part to be preserved to the beginning
458 * of the string; use memmove() because strings
460 memmove(fontpath, envptr, elen + 1);
462 fontpath = gp_realloc(fontpath, elen + 1 + plen + 1, "expand fontpath");
463 /* now move env part back to the end to make space for
465 memmove(fontpath + plen + 1, fontpath, elen + 1);
466 strcpy(fontpath, path);
467 /* separate new path(s) and env path(s) */
468 fontpath[plen] = PATHSEP;
469 /* adjust pointer to env part and last */
470 envptr = &fontpath[plen+1];
471 last = envptr + elen;
472 PATHSEP_TO_NUL(fontpath);
473 } /* else: NULL = empty */
476 /* print the current, full fontpath */
477 FPRINTF((stderr, "Show fontpath\n"));
479 fputs("\tfontpath is ", stderr);
480 PRINT_PATHLIST(fontpath, envptr);
483 fputs("\tsystem fontpath is ", stderr);
484 PRINT_PATHLIST(envptr, last);
487 fputs("\tfontpath is empty\n", stderr);
490 /* we don't save the font path taken from the
491 * environment, so don't go beyond envptr when
492 * extracting the path elements
496 /* subsequent calls to get_fontpath() return all
497 * elements of the fontpath until exhausted
499 FPRINTF((stderr, "Get fontpath\n"));
520 /* should always be ignored - points to the
521 * first path in the list */
526 /* not set or shown directly, but controlled by 'set locale'
527 * defined in national.h
530 char full_month_names[12][32] =
531 { FMON01, FMON02, FMON03, FMON04, FMON05, FMON06, FMON07, FMON08, FMON09, FMON10, FMON11, FMON12 };
532 char abbrev_month_names[12][8] =
533 { AMON01, AMON02, AMON03, AMON04, AMON05, AMON06, AMON07, AMON08, AMON09, AMON10, AMON11, AMON12 };
535 char full_day_names[7][32] =
536 { FDAY0, FDAY1, FDAY2, FDAY3, FDAY4, FDAY5, FDAY6 };
537 char abbrev_day_names[7][8] =
538 { ADAY0, ADAY1, ADAY2, ADAY3, ADAY4, ADAY5, ADAY6 };
541 locale_handler(int action, char *newlocale)
543 static char *current_locale = NULL;
550 if (current_locale) free(current_locale);
551 current_locale = gp_strdup(INITIAL_LOCALE);
554 /* FIXME: configure test for setlocale() */
556 if (setlocale(LC_TIME, newlocale)) {
557 current_locale = gp_realloc(current_locale, strlen(newlocale) + 1, "locale");
558 strcpy(current_locale, newlocale);
561 int_error(c_token, "Locale not available");
563 /* we can do a *lot* better than this ; eg use system functions
564 * where available; create values on first use, etc
566 memset(&tm, 0, sizeof(struct tm));
567 for (i = 0; i < 7; ++i) {
568 tm.tm_wday = i; /* hope this enough */
569 strftime(full_day_names[i], sizeof(full_day_names[i]), "%A", &tm);
570 strftime(abbrev_day_names[i], sizeof(abbrev_day_names[i]), "%a", &tm);
572 for (i = 0; i < 12; ++i) {
573 tm.tm_mon = i; /* hope this enough */
574 strftime(full_month_names[i], sizeof(full_month_names[i]), "%B", &tm);
575 strftime(abbrev_month_names[i], sizeof(abbrev_month_names[i]), "%b", &tm);
578 current_locale = gp_realloc(current_locale, strlen(newlocale) + 1, "locale");
579 strcpy(current_locale, newlocale);
580 #endif /* HAVE_LOCALE_H */
584 fprintf(stderr, "\tLC_CTYPE is %s\n", setlocale(LC_CTYPE,NULL));
585 fprintf(stderr, "\tLC_TIME is %s\n", setlocale(LC_TIME,NULL));
587 fprintf(stderr, "\tlocale is \"%s\"\n", current_locale);
598 return current_locale;