* 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 "../fc-arch/fcarch.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.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'},
+ {"recurse", 0, 0, 'r'},
{"help", 0, 0, '?'},
{NULL,0,0,0},
};
#define PUTC(c,f) putc(c,f)
#endif
-FcBool
-FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *cache_file);
-
static FcBool
-FcCacheWriteChars (FILE *f, const FcChar8 *chars)
+write_chars (FILE *f, const FcChar8 *chars)
{
FcChar8 c;
while ((c = *chars++))
}
static FcBool
-FcCacheWriteUlong (FILE *f, unsigned long t)
+write_ulong (FILE *f, unsigned long t)
{
int pow;
unsigned long temp, digit;
}
static FcBool
-FcCacheWriteInt (FILE *f, int i)
+write_int (FILE *f, int i)
{
- return FcCacheWriteUlong (f, (unsigned long) i);
+ return write_ulong (f, (unsigned long) i);
}
static FcBool
-FcCacheWriteStringOld (FILE *f, const FcChar8 *string)
+write_string (FILE *f, const FcChar8 *string)
{
if (PUTC ('"', f) == EOF)
return FcFalse;
- if (!FcCacheWriteChars (f, string))
+ if (!write_chars (f, string))
return FcFalse;
if (PUTC ('"', f) == EOF)
return FcFalse;
usage (char *program)
{
#if HAVE_GETOPT_LONG
- fprintf (stderr, "usage: %s [-V?] [--version] [--help] <fonts.cache-2>\n",
- program);
+ fprintf (stderr, "usage: %s [-V?] [--version] [--help] {*-%s.cache-2|directory}...\n",
+ program, FC_ARCHITECTURE);
#else
- fprintf (stderr, "usage: %s [-fsvV?] <fonts.cache-2>\n",
- program);
+ fprintf (stderr, "usage: %s [-fsvV?] {*-%s.cache-2|directory}...\n",
+ program, FC_ARCHITECTURE);
#endif
- fprintf (stderr, "Reads font information caches in <fonts.cache-2>\n");
+ fprintf (stderr, "Reads font information cache from:\n");
+ fprintf (stderr, " 1) specified fontconfig cache file\n");
+ fprintf (stderr, " 2) related to a particular font directory\n");
fprintf (stderr, "\n");
#if HAVE_GETOPT_LONG
fprintf (stderr, " -V, --version display font config version and exit\n");
exit (1);
}
-static FcBool
-FcCacheGlobalFileReadAndPrint (FcFontSet * set, FcStrSet *dirs, char * dir, char *cache_file)
-{
- char name_buf[8192];
- int fd;
- char * current_arch_machine_name;
- char candidate_arch_machine_name[9+MACHINE_SIGNATURE_SIZE];
- 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,
- FcTrue);
- 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)
- {
- 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);
-
- if (!FcDirCacheConsume (fd, dir, set))
- goto bail1;
-
- FcCachePrintSet (set, dirs, name_buf);
-
- FcFontSetDestroy (set);
- set = FcFontSetCreate();
- }
-
- bail1:
- close (fd);
- bail:
- return FcFalse;
-}
-
-/* read serialized state from the cache file */
-static FcBool
-FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char * dir, char *cache_file)
-{
- int fd;
- char * current_arch_machine_name;
- char candidate_arch_machine_name[9+MACHINE_SIGNATURE_SIZE];
- off_t current_arch_start = 0;
- char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
- char name_buf[8192];
-
- 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;
- printf ("fc-cat: printing directory cache contents for dir %s\n",
- name_buf);
-
- current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name,
- FcFalse);
- 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 (strlen(FcCacheReadString (fd, subdirName, sizeof (subdirName))) > 0)
- FcStrSetAdd (dirs, (FcChar8 *)subdirName);
-
- if (!FcDirCacheConsume (fd, dir, set))
- goto bail1;
-
- close(fd);
- return FcTrue;
-
- bail1:
- close (fd);
- bail:
- return FcFalse;
-}
-
/*
* return the path from the directory containing 'cache' to 'file'
*/
static const FcChar8 *
-FcFileBaseName (const char *cache, const FcChar8 *file)
+file_base_name (const FcChar8 *cache, const FcChar8 *file)
{
- const FcChar8 *cache_slash;
+ int cache_len = strlen ((char *) 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 ((char *) cache, (char *) file, cache_len) && file[cache_len] == '/')
+ return file + cache_len + 1;
return file;
}
-FcBool
-FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *cache_file)
+#define FC_FONT_FILE_DIR ((FcChar8 *) ".dir")
+
+static FcBool
+cache_print_set (FcFontSet *set, FcStrSet *dirs, const FcChar8 *base_name, FcBool verbose)
{
- FcPattern *font;
FcChar8 *name, *dir;
const FcChar8 *file, *base;
int ret;
int n;
int id;
+ int ndir = 0;
FcStrList *list;
list = FcStrListCreate (dirs);
while ((dir = FcStrListNext (list)))
{
- base = FcFileBaseName (cache_file, dir);
- if (!FcCacheWriteStringOld (stdout, base))
+ base = file_base_name (base_name, dir);
+ if (!write_string (stdout, base))
goto bail3;
if (PUTC (' ', stdout) == EOF)
goto bail3;
- if (!FcCacheWriteInt (stdout, 0))
+ if (!write_int (stdout, 0))
goto bail3;
if (PUTC (' ', stdout) == EOF)
goto bail3;
- if (!FcCacheWriteStringOld (stdout, FC_FONT_FILE_DIR))
+ if (!write_string (stdout, FC_FONT_FILE_DIR))
goto bail3;
if (PUTC ('\n', stdout) == EOF)
goto bail3;
+ ndir++;
}
for (n = 0; n < set->nfont; n++)
{
- font = set->fonts[n];
+ FcPattern *font = set->fonts[n];
+
if (FcPatternGetString (font, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
goto bail3;
- base = FcFileBaseName (cache_file, file);
+ base = file_base_name (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))
+ if (!write_string (stdout, base))
goto bail3;
if (PUTC (' ', stdout) == EOF)
goto bail3;
- if (!FcCacheWriteInt (stdout, id))
+ if (!write_int (stdout, id))
goto bail3;
if (PUTC (' ', stdout) == EOF)
goto bail3;
name = FcNameUnparse (font);
if (!name)
goto bail3;
- ret = FcCacheWriteStringOld (stdout, name);
+ ret = write_string (stdout, name);
FcStrFree (name);
if (!ret)
goto bail3;
if (PUTC ('\n', stdout) == EOF)
goto bail3;
}
+ if (verbose && !set->nfont && !ndir)
+ printf ("<empty>\n");
FcStrListDone (list);
main (int argc, char **argv)
{
int i;
+ int ret = 0;
+ FcFontSet *fs;
+ FcStrSet *dirs;
+ FcStrSet *args = NULL;
+ FcStrList *arglist;
+ FcCache *cache;
+ FcConfig *config;
+ FcChar8 *arg;
+ int verbose = 0;
+ int recurse = 0;
+ FcBool first = FcTrue;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
int c;
- FcFontSet *fs = FcFontSetCreate();
- FcStrSet *dirs = FcStrSetCreate();
#if HAVE_GETOPT_LONG
- while ((c = getopt_long (argc, argv, "fsVv?", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "Vvr?", longopts, NULL)) != -1)
#else
- while ((c = getopt (argc, argv, "fsVv?")) != -1)
+ while ((c = getopt (argc, argv, "Vvr?")) != -1)
#endif
{
switch (c) {
fprintf (stderr, "fontconfig version %d.%d.%d\n",
FC_MAJOR, FC_MINOR, FC_REVISION);
exit (0);
+ case 'v':
+ verbose++;
+ break;
+ case 'r':
+ recurse++;
+ break;
default:
usage (argv[0]);
}
i = 1;
#endif
- if (i >= argc)
- usage (argv[0]);
-
- if (FcCacheFileRead (fs, dirs, dirname (strdup(argv[i])), argv[i]))
- FcCachePrintSet (fs, dirs, argv[i]);
+ config = FcInitLoadConfig ();
+ if (!config)
+ {
+ fprintf (stderr, "%s: Can't init font config library\n", argv[0]);
+ return 1;
+ }
+ FcConfigSetCurrent (config);
+
+ args = FcStrSetCreate ();
+ if (!args)
+ {
+ fprintf (stderr, "%s: malloc failure\n", argv[0]);
+ return 1;
+ }
+ if (i < argc)
+ {
+ for (; i < argc; i++)
+ {
+ if (!FcStrSetAddFilename (args, (const FcChar8 *) argv[i]))
+ {
+ fprintf (stderr, "%s: malloc failure\n", argv[0]);
+ return 1;
+ }
+ }
+ arglist = FcStrListCreate (args);
+ if (!arglist)
+ {
+ fprintf (stderr, "%s: malloc failure\n", argv[0]);
+ return 1;
+ }
+ }
else
{
- FcStrSetDestroy (dirs);
- dirs = FcStrSetCreate ();
- if (FcCacheGlobalFileReadAndPrint (fs, dirs, dirname (strdup (argv[i])),
- argv[i]))
- ;
+ recurse++;
+ arglist = FcConfigGetFontDirs (config);
+ while ((arg = FcStrListNext (arglist)))
+ if (!FcStrSetAdd (args, arg))
+ {
+ fprintf (stderr, "%s: malloc failure\n", argv[0]);
+ return 1;
+ }
+ FcStrListDone (arglist);
+ }
+ arglist = FcStrListCreate (args);
+ if (!arglist)
+ {
+ fprintf (stderr, "%s: malloc failure\n", argv[0]);
+ return 1;
}
- FcStrSetDestroy (dirs);
- FcFontSetDestroy (fs);
+ while ((arg = FcStrListNext (arglist)))
+ {
+ int j;
+ FcChar8 *cache_file = NULL;
+ struct stat file_stat;
+
+ if (FcFileIsDir (arg))
+ cache = FcDirCacheLoad (arg, config, &cache_file);
+ else
+ cache = FcDirCacheLoadFile (arg, &file_stat);
+ if (!cache)
+ {
+ perror ((char *) arg);
+ ret++;
+ continue;
+ }
+
+ dirs = FcStrSetCreate ();
+ fs = FcCacheCopySet (cache);
+ for (j = 0; j < FcCacheNumSubdir (cache); j++)
+ {
+ FcStrSetAdd (dirs, FcCacheSubdir (cache, j));
+ if (recurse)
+ FcStrSetAdd (args, FcCacheSubdir (cache, j));
+ }
+
+ if (verbose)
+ {
+ if (!first)
+ printf ("\n");
+ printf ("Directory: %s\nCache: %s\n--------\n",
+ FcCacheDir(cache), cache_file ? cache_file : arg);
+ first = FcFalse;
+ }
+ cache_print_set (fs, dirs, FcCacheDir (cache), verbose);
+
+ FcStrSetDestroy (dirs);
+
+ FcFontSetDestroy (fs);
+ FcDirCacheUnload (cache);
+ if (cache_file)
+ FcStrFree (cache_file);
+ }
return 0;
}