w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

fc-cache.c
Go to the documentation of this file.
1 /*
2  * fontconfig/fc-cache/fc-cache.c
3  *
4  * Copyright © 2002 Keith Packard
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the author(s) not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission. The authors make no
13  * representations about the suitability of this software for any purpose. It
14  * is provided "as is" without express or implied warranty.
15  *
16  * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24 
25 #ifdef _WIN32
26 #define X_OK 0
27 #define F_OK 0
28 #include <kpathsea/c-proto.h>
29 #include <kpathsea/variable.h>
30 #endif
31 
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #else
35 #ifdef linux
36 #define HAVE_GETOPT_LONG 1
37 #endif
38 #define HAVE_GETOPT 1
39 #endif
40 
41 #include <fontconfig/fontconfig.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #ifndef _WIN32
45 #include <unistd.h>
46 #endif
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 #include <dirent.h>
52 #include <string.h>
53 #include <locale.h>
54 
55 #if defined (_WIN32)
56 #ifndef STRICT
57 #define STRICT
58 #endif
59 #include <windows.h>
60 #define sleep(x) Sleep((x) * 1000)
61 #undef STRICT
62 #endif
63 
64 #ifdef ENABLE_NLS
65 #include <libintl.h>
66 #define _(x) (dgettext(GETTEXT_PACKAGE, x))
67 #else
68 #define dgettext(d, s) (s)
69 #define _(x) (x)
70 #endif
71 
72 #ifndef O_BINARY
73 #define O_BINARY 0
74 #endif
75 
76 #ifndef S_ISDIR
77 #define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
78 #endif
79 
80 #ifndef HAVE_GETOPT
81 #define HAVE_GETOPT 0
82 #endif
83 #ifndef HAVE_GETOPT_LONG
84 #define HAVE_GETOPT_LONG 0
85 #endif
86 
87 #if HAVE_GETOPT_LONG
88 #undef _GNU_SOURCE
89 #define _GNU_SOURCE
90 #include <getopt.h>
91 const struct option longopts[] = {
92  {"error-on-no-fonts", 0, 0, 'E'},
93  {"force", 0, 0, 'f'},
94  {"really-force", 0, 0, 'r'},
95  {"sysroot", required_argument, 0, 'y'},
96  {"system-only", 0, 0, 's'},
97  {"version", 0, 0, 'V'},
98  {"verbose", 0, 0, 'v'},
99  {"help", 0, 0, 'h'},
100  {NULL,0,0,0},
101 };
102 #else
103 #if HAVE_GETOPT
104 extern char *optarg;
105 #ifndef _WIN32
106 extern int optind, opterr, optopt;
107 #endif
108 #endif
109 #endif
110 
111 static void
112 usage (char *program, int error)
113 {
114  FILE *file = error ? stderr : stdout;
115 #if HAVE_GETOPT_LONG
116 #if defined(_WIN32)
117  fprintf (file, _("usage: %s [-EfrsvVh] [--error-on-no-fonts] [--force|--really-force] [--system-only] [--verbose] [--version] [--help] [dirs]\n"),
118  program);
119 #else
120  fprintf (file, _("usage: %s [-EfrsvVh] [-y SYSROOT] [--error-on-no-fonts] [--force|--really-force] [--sysroot=SYSROOT] [--system-only] [--verbose] [--version] [--help] [dirs]\n"),
121  program);
122 #endif /* _WIN32 */
123 #else
124 #if defined(_WIN32)
125  fprintf (file, _("usage: %s [-EfrsvVh] [dirs]\n"),
126  program);
127 #else
128  fprintf (file, _("usage: %s [-EfrsvVh] [-y SYSROOT] [dirs]\n"),
129  program);
130 #endif /* _WIN32 */
131 #endif
132  fprintf (file, _("Build font information caches in [dirs]\n"
133  "(all directories in font configuration by default).\n"));
134  fprintf (file, "\n");
135 #if HAVE_GETOPT_LONG
136  fprintf (file, _(" -E, --error-on-no-fonts raise an error if no fonts in a directory\n"));
137  fprintf (file, _(" -f, --force scan directories with apparently valid caches\n"));
138  fprintf (file, _(" -r, --really-force erase all existing caches, then rescan\n"));
139  fprintf (file, _(" -s, --system-only scan system-wide directories only\n"));
140 #if !defined(_WIN32)
141  fprintf (file, _(" -y, --sysroot=SYSROOT prepend SYSROOT to all paths for scanning\n"));
142 #endif /* !_WIN32 */
143  fprintf (file, _(" -v, --verbose display status information while busy\n"));
144  fprintf (file, _(" -V, --version display font config version and exit\n"));
145  fprintf (file, _(" -h, --help display this help and exit\n"));
146 #else
147  fprintf (file, _(" -E (error-on-no-fonts)\n"));
148  fprintf (file, _(" raise an error if no fonts in a directory\n"));
149  fprintf (file, _(" -f (force) scan directories with apparently valid caches\n"));
150  fprintf (file, _(" -r, (really force) erase all existing caches, then rescan\n"));
151  fprintf (file, _(" -s (system) scan system-wide directories only\n"));
152 #if !defined(_WIN32)
153  fprintf (file, _(" -y SYSROOT (sysroot) prepend SYSROOT to all paths for scanning\n"));
154 #endif /* !_WIN32 */
155  fprintf (file, _(" -v (verbose) display status information while busy\n"));
156  fprintf (file, _(" -V (version) display font config version and exit\n"));
157  fprintf (file, _(" -h (help) display this help and exit\n"));
158 #endif
159  exit (error);
160 }
161 
163 
164 static int
165 scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose, FcBool error_on_no_fonts, int *changed)
166 {
167  int ret = 0;
168  const FcChar8 *dir;
169  FcStrSet *subdirs;
170  FcStrList *sublist;
171  FcCache *cache;
172  struct stat statb;
173  FcBool was_valid, was_processed = FcFalse;
174  int i;
175  const FcChar8 *sysroot = FcConfigGetSysRoot (config);
176 
177  /*
178  * Now scan all of the directories into separate databases
179  * and write out the results
180  */
181  while ((dir = FcStrListNext (list)))
182  {
183 #ifdef _WIN32 /* we don't show looped-dir messages */
185  {
186  continue;
187  }
188 #endif /* _WIN32 */
189  if (verbose)
190  {
191  if (sysroot)
192  printf ("[%s]", sysroot);
193  printf ("%s: ", dir);
194  fflush (stdout);
195  }
196 
197 #ifndef _WIN32 /* we don't show looped-dir messages */
199  {
200  if (verbose)
201  printf (_("skipping, looped directory detected\n"));
202  continue;
203  }
204 #endif /* !_WIN32 */
205 
206  FcChar8 *rooted_dir = NULL;
207  if (sysroot)
208  {
209  rooted_dir = FcStrPlus(sysroot, dir);
210  }
211  else {
212  rooted_dir = FcStrCopy(dir);
213  }
214 
215  if (stat ((char *) rooted_dir, &statb) == -1)
216  {
217  switch (errno) {
218  case ENOENT:
219  case ENOTDIR:
220  if (verbose)
221  printf (_("skipping, no such directory\n"));
222  break;
223  default:
224  fprintf (stderr, "\"%s\": ", dir);
225  perror ("");
226  ret++;
227  break;
228  }
229  FcStrFree (rooted_dir);
230  rooted_dir = NULL;
231  continue;
232  }
233 
234  FcStrFree(rooted_dir);
235  rooted_dir = NULL;
236 
237  if (!S_ISDIR (statb.st_mode))
238  {
239  fprintf (stderr, _("\"%s\": not a directory, skipping\n"), dir);
240  continue;
241  }
242  was_processed = FcTrue;
243 
244 /*
245  In the case of _WIN32, we remove all caches if really_force
246  is FcTrue at the very first. Thus the following is not
247  necessary.
248 */
249 #if !defined(_WIN32)
250  if (really_force)
251  {
253  }
254 #endif
255 
256  cache = NULL;
257  was_valid = FcFalse;
258  if (!force) {
260  if (cache)
261  was_valid = FcTrue;
262  }
263 
264  if (!cache)
265  {
266  (*changed)++;
268  if (!cache)
269  {
270  fprintf (stderr, _("\"%s\": scanning error\n"), dir);
271  ret++;
272  continue;
273  }
274  }
275 
276  if (was_valid)
277  {
278  if (verbose)
279  printf (_("skipping, existing cache is valid: %d fonts, %d dirs\n"),
281  }
282  else
283  {
284  if (verbose)
285  printf (_("caching, new cache contents: %d fonts, %d dirs\n"),
287 
288 /* #ifndef _WIN32 */
289  if (!FcDirCacheValid (dir))
290  {
291  fprintf (stderr, _("%s: failed to write cache\n"), dir);
293  ret++;
294  }
295 /* #endif */ /* !_WIN32 */
296  }
297 
298  subdirs = FcStrSetCreate ();
299  if (!subdirs)
300  {
301  fprintf (stderr, _("%s: Can't create subdir set\n"), dir);
302  ret++;
304  continue;
305  }
306  for (i = 0; i < FcCacheNumSubdir (cache); i++)
307  FcStrSetAdd (subdirs, FcCacheSubdir (cache, i));
308 
310 
311  sublist = FcStrListCreate (subdirs);
312  FcStrSetDestroy (subdirs);
313  if (!sublist)
314  {
315  fprintf (stderr, _("%s: Can't create subdir list\n"), dir);
316  ret++;
317  continue;
318  }
320  ret += scanDirs (sublist, config, force, really_force, verbose, error_on_no_fonts, changed);
321  FcStrListDone (sublist);
322  }
323 
324  if (error_on_no_fonts && !was_processed)
325  ret++;
326  return ret;
327 }
328 
329 static FcBool
331 {
332  FcStrList *cache_dirs = FcConfigGetCacheDirs (config);
333  FcChar8 *cache_dir;
334  FcBool ret = FcTrue;
335 
336  if (!cache_dirs)
337  return FcFalse;
338  while ((cache_dir = FcStrListNext (cache_dirs)))
339  {
340  if (!FcDirCacheClean (cache_dir, verbose))
341  {
342  ret = FcFalse;
343  break;
344  }
345  }
346  FcStrListDone (cache_dirs);
347  return ret;
348 }
349 
350 int
351 main (int argc, char **argv)
352 {
353  FcStrSet *dirs;
354  FcStrList *list;
356  FcBool force = FcFalse;
357  FcBool really_force = FcFalse;
358  FcBool systemOnly = FcFalse;
359  FcBool error_on_no_fonts = FcFalse;
360  FcConfig *config;
361  FcChar8 *sysroot = NULL;
362  int i;
363  int changed;
364  int ret;
365 #if HAVE_GETOPT_LONG || HAVE_GETOPT
366  int c;
367 
368  setlocale (LC_ALL, "");
369 
370 #ifdef _WIN32
371  kpse_set_program_name(argv[0], NULL);
372 #endif
373 
374 #if HAVE_GETOPT_LONG
375  while ((c = getopt_long (argc, argv, "Efrsy:Vvh", longopts, NULL)) != -1)
376 #else
377  while ((c = getopt (argc, argv, "Efrsy:Vvh")) != -1)
378 #endif
379  {
380  switch (c) {
381  case 'E':
382  error_on_no_fonts = FcTrue;
383  break;
384  case 'r':
385 #if !defined(_WIN32)
386  really_force = FcTrue;
387 #endif /* _WIN32 */
388  /* fall through */
389  case 'f':
390 #if defined(_WIN32)
391 /*
392  In the case of Windows, -r and -f are the same, because
393  all cache files are removed in a special way.
394 */
395  really_force = FcTrue;
396 #endif /* _WIN32 */
397  force = FcTrue;
398  break;
399  case 's':
400  systemOnly = FcTrue;
401  break;
402  case 'y':
403 #if !defined(_WIN32)
404  sysroot = FcStrCopy ((const FcChar8 *)optarg);
405 #endif /* !_WIN32 */
406  break;
407  case 'V':
408  fprintf (stderr, "fontconfig version %d.%d.%d\n",
410  exit (0);
411  case 'v':
412  verbose = FcTrue;
413  break;
414  case 'h':
415  usage (argv[0], 0);
416  default:
417  usage (argv[0], 1);
418  }
419  }
420  i = optind;
421 #else
422  i = 1;
423 #endif
424 
425 #ifdef _WIN32
426 /* Always print (2014 ak) */
427  printf ("Note that it needs some time to create caches,\n"
428  "especially if there are many large font files.\n"
429  "Wait with patience.\n\n");
430 #endif
431 
432 #if defined(_WIN32)
433 /*
434  In the case of -r and -f options (they are equivalent on Windows)
435  remove all cache files here in our special way.
436  In the default case, unlink() fails in most cases, so "foo.NEW"
437  cannot be renamed as "foo".
438 */
439  if (really_force) {
440  char *fname;
441  char *cdir;
442  DIR *dp;
443  struct dirent *de;
444 
445  cdir = kpse_var_value ("XE_FC_CACHEDIR");
446  if (cdir == NULL) {
447  cdir = kpse_var_value ("FC_CACHEDIR");
448  }
449 
450  if (cdir) {
451  if ((dp = opendir(cdir))) {
452  while((de = readdir(dp))) {
453  if (strcmp(de->d_name, ".") &&
454  strcmp(de->d_name, "..") &&
455  stricmp(de->d_name, "readme.txt")) {
456  fname = malloc (strlen(cdir) + strlen(de->d_name) + 2);
457  strcpy (fname, cdir);
458  strcat (fname, "/");
459  strcat (fname, de->d_name);
460  (void) remove (fname);
461  free (fname);
462  }
463  }
464  closedir (dp);
465  }
466  free (cdir);
467  }
468  }
469 #endif /* _WIN32 */
470 
471  if (systemOnly)
473  if (sysroot)
474  {
475  FcConfigSetSysRoot (NULL, sysroot);
476  FcStrFree (sysroot);
478  }
479  else
480  {
482  }
483  if (!config)
484  {
485  fprintf (stderr, _("%s: Can't initialize font config library\n"), argv[0]);
486  return 1;
487  }
489 
490  if (argv[i])
491  {
492  dirs = FcStrSetCreate ();
493  if (!dirs)
494  {
495  fprintf (stderr, _("%s: Can't create list of directories\n"),
496  argv[0]);
497  return 1;
498  }
499  while (argv[i])
500  {
501  if (!FcStrSetAddFilename (dirs, (FcChar8 *) argv[i]))
502  {
503  fprintf (stderr, _("%s: Can't add directory\n"), argv[0]);
504  return 1;
505  }
506  i++;
507  }
508  list = FcStrListCreate (dirs);
509  FcStrSetDestroy (dirs);
510  }
511  else
513 
514  if ((processed_dirs = FcStrSetCreate()) == NULL) {
515  fprintf(stderr, _("Out of Memory\n"));
516  return 1;
517  }
518 
519  if (verbose)
520  {
521  const FcChar8 *dir;
522 
523  printf ("Font directories:\n");
524  while ((dir = FcStrListNext (list)))
525  {
526  printf ("\t%s\n", dir);
527  }
529  }
530  changed = 0;
531  ret = scanDirs (list, config, force, really_force, verbose, error_on_no_fonts, &changed);
533 
534  /*
535  * Try to create CACHEDIR.TAG anyway.
536  * This expects the fontconfig cache directory already exists.
537  * If it doesn't, it won't be simply created.
538  */
540 
542 
544 
546  FcFini ();
547  /*
548  * Now we need to sleep a second (or two, to be extra sure), to make
549  * sure that timestamps for changes after this run of fc-cache are later
550  * then any timestamps we wrote. We don't use gettimeofday() because
551  * sleep(3) can't be interrupted by a signal here -- this isn't in the
552  * library, and there aren't any signals flying around here.
553  */
554  /* the resolution of mtime on FAT is 2 seconds */
555  if (changed)
556  sleep (2);
557  if (verbose)
558  printf ("%s: %s\n", argv[0], ret ? _("failed") : _("succeeded"));
559  return ret;
560 }
void __cdecl perror(char const *_ErrMsg)
#define free(a)
Definition: decNumber.cpp:310
#define ENOTDIR
Definition: director.c:104
const char * program
Definition: dv2dt.c:152
#define fflush
Definition: xxstdio.h:24
int strcmp()
Definition: coll.cpp:143
int printf()
char * strcpy()
#define error(a)
Definition: dviinfo.c:48
static FcBool cleanCacheDirectories(FcConfig *config, FcBool verbose)
Definition: fc-cache.c:330
int main(int argc, char **argv)
Definition: fc-cache.c:351
int optopt
Definition: fc-cache.c:106
#define S_ISDIR(m)
Definition: fc-cache.c:77
static void usage(char *program, int error)
Definition: fc-cache.c:112
static FcStrSet * processed_dirs
Definition: fc-cache.c:162
static int scanDirs(FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose, FcBool error_on_no_fonts, int *changed)
Definition: fc-cache.c:165
int optind
Definition: getopt.c:39
char * optarg
Definition: getopt.c:42
int opterr
Definition: fc-cache.c:106
#define _(x)
Definition: fc-cache.c:69
#define FcStrPlus
Definition: fcalias.h:394
#define FcCacheNumSubdir
Definition: fcalias.h:12
#define FcStrSetMember
Definition: fcalias.h:426
#define FcStrListDone
Definition: fcalias.h:444
#define FcDirCacheValid
Definition: fcalias.h:18
#define FcDirCacheLoad
Definition: fcalias.h:144
#define FcCacheNumFont
Definition: fcalias.h:14
#define FcStrSetCreate
Definition: fcalias.h:424
#define FcConfigGetCurrent
Definition: fcalias.h:44
#define FcDirCacheUnload
Definition: fcalias.h:152
#define FcConfigGetCacheDirs
Definition: fcalias.h:60
#define FcConfigDestroy
Definition: fcalias.h:40
#define FcDirCacheRead
Definition: fcalias.h:148
#define FcStrListCreate
Definition: fcalias.h:438
#define FcStrSetDestroy
Definition: fcalias.h:436
#define FcStrSetAdd
Definition: fcalias.h:430
#define FcInitLoadConfig
Definition: fcalias.h:164
#define FcStrListFirst
Definition: fcalias.h:440
#define FcFini
Definition: fcalias.h:170
#define FcConfigGetFontDirs
Definition: fcalias.h:50
#define FcConfigSetSysRoot
Definition: fcalias.h:80
#define FcConfigEnableHome
Definition: fcalias.h:30
#define FcConfigGetSysRoot
Definition: fcalias.h:78
#define FcConfigSetCurrent
Definition: fcalias.h:42
#define FcDirCacheClean
Definition: fcalias.h:20
#define FcStrFree
Definition: fcalias.h:396
#define FcDirCacheUnlink
Definition: fcalias.h:16
#define FcStrSetAddFilename
Definition: fcalias.h:432
#define FcStrListNext
Definition: fcalias.h:442
#define FcStrCopy
Definition: fcalias.h:390
#define FcCacheCreateTagFile
Definition: fcalias.h:22
#define FcCacheSubdir(c, i)
Definition: fcint.h:436
unsigned char FcChar8
Definition: fontconfig.h:43
#define FcFalse
Definition: fontconfig.h:75
#define FC_MAJOR
Definition: fontconfig.h:54
#define FC_MINOR
Definition: fontconfig.h:55
#define FcTrue
Definition: fontconfig.h:76
#define FC_REVISION
Definition: fontconfig.h:56
int FcBool
Definition: fontconfig.h:46
static void
Definition: fpif.c:118
#define c(n)
Definition: gpos-common.c:150
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
int getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.c:53
#define required_argument
Definition: getopt.h:111
int getopt_long()
struct config_s config
int errno
struct dirent * readdir(DIR *dirp)
Definition: dirent.c:138
int closedir(DIR *dirp)
Definition: dirent.c:123
DIR * opendir(char *fname)
Definition: dirent.c:60
#define stricmp
Definition: win32lib.h:93
static int ret
Definition: convert.c:72
#define fprintf
Definition: mendex.h:64
#define setlocale(A, B)
Definition: cwebboot.c:31
#define malloc
Definition: alloca.c:91
unsigned int sleep()
int remove()
cell * list
Definition: list_routines.h:30
static UHashtable * cache
boolean changed
Definition: parse_ofm.c:90
char * fname
Definition: plain2.c:121
static int force
Definition: pnmtopng.c:115
#define dir
static struct option longopts[]
Definition: main.c:385
RETTYPE mp_ptr mp_size_t mp_srcptr dp
Definition: sec_div.c:70
Definition: dirent.h:44
Definition: dirent.h:34
char d_name[260]
Definition: dirent.h:37
Definition: filedef.h:30
Definition: getopt.h:95
#define FILE
Definition: t1stdio.h:34
*job_name strlen((char *) job_name) - 4)
#define verbose
Definition: jpeg.c:35
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269