FcCharSetSerialize was using wrong offset for leaves. Make fc-cat work.
FcCharSetSerialize was computing the offset to the unserialized leaf, which left it pointing at random data when the cache was reloaded. fc-cat has been updated to work with the new cache structure. Various debug messages extended to help diagnose serialization errors.
This commit is contained in:
parent
e3096d90fd
commit
c02886485b
126
fc-cat/fc-cat.c
126
fc-cat/fc-cat.c
|
@ -53,6 +53,7 @@
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
const struct option longopts[] = {
|
const struct option longopts[] = {
|
||||||
{"version", 0, 0, 'V'},
|
{"version", 0, 0, 'V'},
|
||||||
|
{"verbose", 0, 0, 'v'},
|
||||||
{"help", 0, 0, '?'},
|
{"help", 0, 0, '?'},
|
||||||
{NULL,0,0,0},
|
{NULL,0,0,0},
|
||||||
};
|
};
|
||||||
|
@ -167,39 +168,22 @@ usage (char *program)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read serialized state from the cache file */
|
static int
|
||||||
static char *
|
FcCacheFileOpen (char *cache_file, off_t *size)
|
||||||
FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char *cache_file)
|
|
||||||
{
|
{
|
||||||
FILE *file;
|
|
||||||
int fd;
|
int fd;
|
||||||
char subdirName[FC_MAX_FILE_LEN + 1 + 12 + 1];
|
struct stat file_stat;
|
||||||
static char name_buf[8192];
|
|
||||||
FcChar8 * ls;
|
|
||||||
char * buf;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!cache_file)
|
fd = open(cache_file, O_RDONLY | O_BINARY);
|
||||||
goto bail;
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
file = fopen(cache_file, "rb");
|
if (fstat (fd, &file_stat) < 0) {
|
||||||
if (file == NULL)
|
close (fd);
|
||||||
goto bail;
|
return -1;
|
||||||
|
}
|
||||||
if (!FcDirCacheConsume (file, set, dirs, NULL, name_buf))
|
*size = file_stat.st_size;
|
||||||
goto bail1;
|
return fd;
|
||||||
|
|
||||||
fclose (file);
|
|
||||||
|
|
||||||
printf ("fc-cat: printing directory cache for cache which would be named %s\n",
|
|
||||||
name_buf);
|
|
||||||
|
|
||||||
return name_buf;
|
|
||||||
|
|
||||||
bail1:
|
|
||||||
fclose (file);
|
|
||||||
bail:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -210,11 +194,10 @@ static const FcChar8 *
|
||||||
FcFileBaseName (const char *cache, const FcChar8 *file)
|
FcFileBaseName (const char *cache, const FcChar8 *file)
|
||||||
{
|
{
|
||||||
const FcChar8 *cache_slash;
|
const FcChar8 *cache_slash;
|
||||||
|
int cache_len = strlen (cache);
|
||||||
|
|
||||||
cache_slash = FcStrLastSlash ((const FcChar8 *)cache);
|
if (!strncmp (cache, file, cache_len) && file[cache_len] == '/')
|
||||||
if (cache_slash && !strncmp ((const char *) cache, (const char *) file,
|
return file + cache_len + 1;
|
||||||
(cache_slash + 1) - (const FcChar8 *)cache))
|
|
||||||
return file + ((cache_slash + 1) - (const FcChar8 *)cache);
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,14 +235,15 @@ FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *base_name)
|
||||||
|
|
||||||
for (n = 0; n < set->nfont; n++)
|
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)
|
if (FcPatternGetString (font, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
|
||||||
goto bail3;
|
goto bail3;
|
||||||
base = FcFileBaseName (base_name, file);
|
base = FcFileBaseName (base_name, file);
|
||||||
if (FcPatternGetInteger (font, FC_INDEX, 0, &id) != FcResultMatch)
|
if (FcPatternGetInteger (font, FC_INDEX, 0, &id) != FcResultMatch)
|
||||||
goto bail3;
|
goto bail3;
|
||||||
if (FcDebug () & FC_DBG_CACHEV)
|
|
||||||
printf (" write file \"%s\"\n", base);
|
|
||||||
if (!FcCacheWriteStringOld (stdout, base))
|
if (!FcCacheWriteStringOld (stdout, base))
|
||||||
goto bail3;
|
goto bail3;
|
||||||
if (PUTC (' ', stdout) == EOF)
|
if (PUTC (' ', stdout) == EOF)
|
||||||
|
@ -293,17 +277,19 @@ int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int ret = 0;
|
||||||
|
FcFontSet *fs;
|
||||||
|
FcStrSet *dirs;
|
||||||
|
FcCache *cache;
|
||||||
|
FcConfig *config;
|
||||||
|
int verbose = 0;
|
||||||
#if HAVE_GETOPT_LONG || HAVE_GETOPT
|
#if HAVE_GETOPT_LONG || HAVE_GETOPT
|
||||||
int c;
|
int c;
|
||||||
FcFontSet *fs = FcFontSetCreate();
|
|
||||||
FcStrSet *dirs = FcStrSetCreate();
|
|
||||||
char *name_buf;
|
|
||||||
FcConfig *config;
|
|
||||||
|
|
||||||
#if HAVE_GETOPT_LONG
|
#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
|
#else
|
||||||
while ((c = getopt (argc, argv, "fsVv?")) != -1)
|
while ((c = getopt (argc, argv, "Vv?")) != -1)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -311,6 +297,9 @@ main (int argc, char **argv)
|
||||||
fprintf (stderr, "fontconfig version %d.%d.%d\n",
|
fprintf (stderr, "fontconfig version %d.%d.%d\n",
|
||||||
FC_MAJOR, FC_MINOR, FC_REVISION);
|
FC_MAJOR, FC_MINOR, FC_REVISION);
|
||||||
exit (0);
|
exit (0);
|
||||||
|
case 'v':
|
||||||
|
verbose++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage (argv[0]);
|
usage (argv[0]);
|
||||||
}
|
}
|
||||||
|
@ -331,29 +320,48 @@ main (int argc, char **argv)
|
||||||
if (i >= argc)
|
if (i >= argc)
|
||||||
usage (argv[0]);
|
usage (argv[0]);
|
||||||
|
|
||||||
|
for (; i < argc; i++)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int j;
|
||||||
|
off_t size;
|
||||||
|
intptr_t *cache_dirs;
|
||||||
|
|
||||||
if (FcFileIsDir ((const FcChar8 *)argv[i]))
|
if (FcFileIsDir ((const FcChar8 *)argv[i]))
|
||||||
{
|
fd = FcDirCacheOpen (config, (const FcChar8 *) argv[i], &size);
|
||||||
char * dummy_name = (char *)FcStrPlus ((FcChar8 *)argv[i],
|
|
||||||
(FcChar8 *)"/dummy");
|
|
||||||
if (!FcDirScanConfig (fs, dirs, 0,
|
|
||||||
(const FcChar8 *)argv[i], FcFalse, config))
|
|
||||||
fprintf (stderr, "couldn't load font dir %s\n", argv[i]);
|
|
||||||
else
|
else
|
||||||
|
fd = FcCacheFileOpen (argv[i], &size);
|
||||||
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
/* sorry, we can't tell you where the cache file is. */
|
perror (argv[i]);
|
||||||
FcCachePrintSet (fs, dirs, dummy_name);
|
ret++;
|
||||||
FcStrFree ((FcChar8 *)dummy_name);
|
continue;
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((name_buf = FcCacheFileRead (fs, dirs, argv[i])) != 0)
|
|
||||||
FcCachePrintSet (fs, dirs, name_buf);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf ("nothing to do\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache = FcDirCacheMap (fd, size);
|
||||||
|
close (fd);
|
||||||
|
if (!cache)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: cannot map cache\n", 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);
|
FcStrSetDestroy (dirs);
|
||||||
FcFontSetDestroy (fs);
|
|
||||||
|
FcDirCacheUnmap (cache);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,8 +255,7 @@ FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, off_t *size)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
void
|
||||||
static void
|
|
||||||
FcDirCacheUnmap (FcCache *cache)
|
FcDirCacheUnmap (FcCache *cache)
|
||||||
{
|
{
|
||||||
if (cache->magic == FC_CACHE_MAGIC_COPY)
|
if (cache->magic == FC_CACHE_MAGIC_COPY)
|
||||||
|
@ -270,10 +269,9 @@ FcDirCacheUnmap (FcCache *cache)
|
||||||
UnmapViewOfFile (cache);
|
UnmapViewOfFile (cache);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* read serialized state from the cache file */
|
/* read serialized state from the cache file */
|
||||||
static FcCache *
|
FcCache *
|
||||||
FcDirCacheMap (int fd, off_t size)
|
FcDirCacheMap (int fd, off_t size)
|
||||||
{
|
{
|
||||||
FcCache *cache;
|
FcCache *cache;
|
||||||
|
|
|
@ -1320,7 +1320,8 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs)
|
||||||
if (!leaf_serialized)
|
if (!leaf_serialized)
|
||||||
return NULL;
|
return NULL;
|
||||||
*leaf_serialized = *leaf;
|
*leaf_serialized = *leaf;
|
||||||
leaves_serialized[i] = FcPtrToOffset (leaves_serialized, leaf);
|
leaves_serialized[i] = FcPtrToOffset (leaves_serialized,
|
||||||
|
leaf_serialized);
|
||||||
numbers_serialized[i] = numbers[i];
|
numbers_serialized[i] = numbers[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
src/fcdbg.c
18
src/fcdbg.c
|
@ -100,12 +100,26 @@ void
|
||||||
FcCharSetPrint (const FcCharSet *c)
|
FcCharSetPrint (const FcCharSet *c)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
intptr_t *leaves = FcCharSetLeaves (c);
|
||||||
|
FcChar16 *numbers = FcCharSetNumbers (c);
|
||||||
|
|
||||||
|
printf ("CharSet 0x%x\n", (intptr_t) c);
|
||||||
|
printf ("Leaves: +%d = 0x%x\n", c->leaves_offset, (intptr_t) leaves);
|
||||||
|
printf ("Numbers: +%d = 0x%x\n", c->numbers_offset, (intptr_t) numbers);
|
||||||
|
|
||||||
for (i = 0; i < c->num; i++)
|
for (i = 0; i < c->num; i++)
|
||||||
{
|
{
|
||||||
FcCharLeaf *leaf = FcCharSetLeaf(c, i);
|
printf ("Page %d: %04x +%d = 0x%x\n",
|
||||||
|
i, numbers[i], leaves[i],
|
||||||
|
(intptr_t) FcOffsetToPtr (leaves, leaves[i], FcCharLeaf));
|
||||||
|
}
|
||||||
|
|
||||||
printf ("%04x:", FcCharSetNumbers(c)[i]);
|
for (i = 0; i < c->num; i++)
|
||||||
|
{
|
||||||
|
intptr_t leaf_offset = leaves[i];
|
||||||
|
FcCharLeaf *leaf = FcOffsetToPtr (leaves, leaf_offset, FcCharLeaf);
|
||||||
|
|
||||||
|
printf ("%04x:", numbers[i]);
|
||||||
for (j = 0; j < 256/32; j++)
|
for (j = 0; j < 256/32; j++)
|
||||||
printf (" %08x", leaf->map[j]);
|
printf (" %08x", leaf->map[j]);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
|
15
src/fcint.h
15
src/fcint.h
|
@ -199,11 +199,12 @@ struct _FcPattern {
|
||||||
#define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt)
|
#define FcPatternElts(p) FcOffsetMember(p,elts_offset,FcPatternElt)
|
||||||
|
|
||||||
#define FcFontSetFonts(fs) FcPointerMember(fs,fonts,FcPattern *)
|
#define FcFontSetFonts(fs) FcPointerMember(fs,fonts,FcPattern *)
|
||||||
/*
|
|
||||||
#define FcFontSetFont(fs,i) (FcIsEncodedOffset((fs)->fonts) ? \
|
#define FcFontSetFont(fs,i) (FcIsEncodedOffset((fs)->fonts) ? \
|
||||||
FcOffsetToPtr(FcFontSetFonts(fs), \
|
FcEncodedOffsetToPtr(FcFontSetFonts(fs), \
|
||||||
FcFontSetFonts(fs)[i]) : \
|
FcFontSetFonts(fs)[i], \
|
||||||
fs->fonts[i])*/
|
FcPattern) : \
|
||||||
|
fs->fonts[i])
|
||||||
|
|
||||||
typedef enum _FcOp {
|
typedef enum _FcOp {
|
||||||
FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet,
|
FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet,
|
||||||
|
@ -490,6 +491,12 @@ FcBool
|
||||||
FcDirCacheConsume (FILE *file, FcFontSet *set, FcStrSet *dirs,
|
FcDirCacheConsume (FILE *file, FcFontSet *set, FcStrSet *dirs,
|
||||||
const FcChar8 *dir, char *dirname);
|
const FcChar8 *dir, char *dirname);
|
||||||
|
|
||||||
|
FcCache *
|
||||||
|
FcDirCacheMap (int fd, off_t size);
|
||||||
|
|
||||||
|
void
|
||||||
|
FcDirCacheUnmap (FcCache *cache);
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config);
|
FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir, FcConfig *config);
|
||||||
|
|
||||||
|
|
|
@ -1096,6 +1096,13 @@ FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
|
||||||
values_serialized,
|
values_serialized,
|
||||||
FcValueList);
|
FcValueList);
|
||||||
}
|
}
|
||||||
|
if (FcDebug() & FC_DBG_CACHEV) {
|
||||||
|
printf ("Raw pattern:\n");
|
||||||
|
FcPatternPrint (pat);
|
||||||
|
printf ("Serialized pattern:\n");
|
||||||
|
FcPatternPrint (pat_serialized);
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
return pat_serialized;
|
return pat_serialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue