* PERFORMANCE OF THIS SOFTWARE.
*/
-#include <fontconfig/fontconfig.h>
-#include <../src/fccache.c>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#define HAVE_GETOPT 1
#endif
+#include <fontconfig/fontconfig.h>
+#include <../src/fccache.c>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
#ifndef HAVE_GETOPT
#define HAVE_GETOPT 0
#endif
#include <getopt.h>
const struct option longopts[] = {
{"version", 0, 0, 'V'},
+ {"verbose", 0, 0, 'v'},
{"help", 0, 0, '?'},
{NULL,0,0,0},
};
exit (1);
}
-static FcBool
-FcCacheGlobalFileReadAndPrint (FcFontSet * set, FcStrSet *dirs, char *cache_file)
+static int
+FcCacheFileOpen (char *cache_file, off_t *size)
{
- char name_buf[8192];
int fd;
- char * current_arch_machine_name;
- char candidate_arch_machine_name[9+MACHINE_SIGNATURE_SIZE];
- char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
- off_t current_arch_start = 0;
-
- if (!cache_file)
- goto bail;
-
- current_arch_machine_name = FcCacheMachineSignature();
- fd = open(cache_file, O_RDONLY);
- if (fd == -1)
- goto bail;
-
- current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
- if (current_arch_start < 0)
- goto bail1;
-
- lseek (fd, current_arch_start, SEEK_SET);
- if (FcCacheReadString (fd, candidate_arch_machine_name,
- sizeof (candidate_arch_machine_name)) == 0)
- goto bail1;
-
- while (1)
- {
- char * dir;
- FcCacheReadString (fd, name_buf, sizeof (name_buf));
- if (!strlen(name_buf))
- break;
- printf ("fc-cat: printing global cache contents for dir %s\n",
- name_buf);
-
- do
- {
- if (!FcCacheReadString (fd, subdirName,
- sizeof (subdirName)) ||
- !strlen (subdirName))
- break;
- /* then don't do anything with subdirName. */
- } while (1);
-
- if (!FcDirCacheConsume (fd, name_buf, set, 0))
- goto bail1;
-
- dir = malloc (strlen (name_buf) + 2);
- if (!dir)
- goto bail1;
-
- strcpy (dir, name_buf);
- strcat (dir, "/");
+ struct stat file_stat;
- FcCachePrintSet (set, dirs, dir);
- free (dir);
+ fd = open(cache_file, O_RDONLY | O_BINARY);
+ if (fd < 0)
+ return -1;
- FcFontSetDestroy (set);
- set = FcFontSetCreate();
+ if (fstat (fd, &file_stat) < 0) {
+ close (fd);
+ return -1;
}
-
- bail1:
- close (fd);
- bail:
- return FcFalse;
-}
-
-/* read serialized state from the cache file */
-static char *
-FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char *cache_file)
-{
- int fd;
- char * current_arch_machine_name;
- off_t current_arch_start = 0;
- char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
- static char name_buf[8192], *dir;
- FcChar8 * ls;
-
- if (!cache_file)
- goto bail;
-
- current_arch_machine_name = FcCacheMachineSignature();
- fd = open(cache_file, O_RDONLY);
- if (fd == -1)
- goto bail;
-
- FcCacheReadString (fd, name_buf, sizeof (name_buf));
- if (!strlen (name_buf))
- goto bail;
- if (strcmp (name_buf, FC_GLOBAL_MAGIC_COOKIE) == 0)
- goto bail;
- printf ("fc-cat: printing directory cache for cache which would be named %s\n",
- name_buf);
-
- current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
- if (current_arch_start < 0)
- goto bail1;
-
- while (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
- FcStrSetAdd (dirs, (FcChar8 *)subdirName);
-
- dir = strdup(name_buf);
- ls = FcStrLastSlash ((FcChar8 *)dir);
- if (ls)
- *ls = 0;
-
- if (!FcDirCacheConsume (fd, dir, set, 0))
- goto bail2;
- free (dir);
-
- close(fd);
- return name_buf;
-
- bail2:
- free (dir);
-
- bail1:
- close (fd);
- bail:
- return 0;
+ *size = file_stat.st_size;
+ return fd;
}
/*
FcFileBaseName (const char *cache, const FcChar8 *file)
{
const FcChar8 *cache_slash;
+ int cache_len = strlen (cache);
- cache_slash = FcStrLastSlash ((const FcChar8 *)cache);
- if (cache_slash && !strncmp ((const char *) cache, (const char *) file,
- (cache_slash + 1) - (const FcChar8 *)cache))
- return file + ((cache_slash + 1) - (const FcChar8 *)cache);
+ if (!strncmp (cache, file, cache_len) && file[cache_len] == '/')
+ return file + cache_len + 1;
return file;
}
for (n = 0; n < set->nfont; n++)
{
- font = set->fonts[n];
+ FcPattern **fonts = FcFontSetFonts (set);
+ FcPattern *encoded_font = fonts[n];
+ FcPattern *font = FcEncodedOffsetToPtr (set, encoded_font, FcPattern);
+
if (FcPatternGetString (font, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
goto bail3;
base = FcFileBaseName (base_name, file);
if (FcPatternGetInteger (font, FC_INDEX, 0, &id) != FcResultMatch)
goto bail3;
- if (FcDebug () & FC_DBG_CACHEV)
- printf (" write file \"%s\"\n", base);
if (!FcCacheWriteStringOld (stdout, base))
goto bail3;
if (PUTC (' ', stdout) == EOF)
return FcFalse;
}
+FcCache *
+FcCacheFileMap (const FcChar8 *file)
+{
+ FcCache *cache;
+ int fd;
+ struct stat file_stat;
+
+ fd = open (file, O_RDONLY | O_BINARY);
+ if (fd < 0)
+ return NULL;
+ if (fstat (fd, &file_stat) < 0) {
+ close (fd);
+ return NULL;
+ }
+ if (FcCacheLoad (fd, file_stat.st_size, &cache)) {
+ close (fd);
+ return cache;
+ }
+ close (fd);
+ return NULL;
+}
+
int
main (int argc, char **argv)
{
int i;
+ int ret = 0;
+ FcFontSet *fs;
+ FcStrSet *dirs;
+ FcCache *cache;
+ FcConfig *config;
+ int verbose = 0;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
int c;
- FcFontSet *fs = FcFontSetCreate();
- FcStrSet *dirs = FcStrSetCreate();
- char *name_buf;
- FcConfig *config;
#if HAVE_GETOPT_LONG
- while ((c = getopt_long (argc, argv, "fsVv?", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "Vv?", longopts, NULL)) != -1)
#else
- while ((c = getopt (argc, argv, "fsVv?")) != -1)
+ while ((c = getopt (argc, argv, "Vv?")) != -1)
#endif
{
switch (c) {
fprintf (stderr, "fontconfig version %d.%d.%d\n",
FC_MAJOR, FC_MINOR, FC_REVISION);
exit (0);
+ case 'v':
+ verbose++;
+ break;
default:
usage (argv[0]);
}
if (i >= argc)
usage (argv[0]);
- if (FcFileIsDir ((const FcChar8 *)argv[i]))
- {
- char * dummy_name = (char *)FcStrPlus ((FcChar8 *)argv[i],
- (FcChar8 *)"/dummy");
- if (!FcDirScanConfig (fs, dirs, 0, 0,
- (const FcChar8 *)argv[i], FcFalse, config))
- fprintf (stderr, "couldn't load font dir %s\n", argv[i]);
- else
- {
- /* sorry, we can't tell you where the cache file is. */
- FcCachePrintSet (fs, dirs, dummy_name);
- FcStrFree ((FcChar8 *)dummy_name);
- }
- }
- else if ((name_buf = FcCacheFileRead (fs, dirs, argv[i])) != 0)
- FcCachePrintSet (fs, dirs, name_buf);
- else
+ for (; i < argc; i++)
{
- FcStrSetDestroy (dirs);
- dirs = FcStrSetCreate ();
- if (FcCacheGlobalFileReadAndPrint (fs, dirs, argv[i]))
- ;
+ int j;
+ off_t size;
+ intptr_t *cache_dirs;
+
+ if (FcFileIsDir ((const FcChar8 *)argv[i]))
+ cache = FcDirCacheMap ((const FcChar8 *) argv[i], config);
+ else
+ cache = FcCacheFileMap (argv[i]);
+ if (!cache)
+ {
+ perror (argv[i]);
+ ret++;
+ continue;
+ }
+
+ dirs = FcStrSetCreate ();
+ fs = FcCacheSet (cache);
+ cache_dirs = FcCacheDirs (cache);
+ for (j = 0; j < cache->dirs_count; j++)
+ FcStrSetAdd (dirs, FcOffsetToPtr (cache_dirs,
+ cache_dirs[j],
+ FcChar8));
+
+ if (verbose)
+ printf ("Name: %s\nDirectory: %s\n", argv[i], FcCacheDir(cache));
+ FcCachePrintSet (fs, dirs, FcCacheDir (cache));
+
+ FcStrSetDestroy (dirs);
+
+ FcDirCacheUnmap (cache);
}
- FcStrSetDestroy (dirs);
- FcFontSetDestroy (fs);
-
return 0;
}