Keith Packard <keithp@keithp.com>
+Patrick Lam <plam@mit.edu>
+
+2006-01-05 Patrick Lam <plam@mit.edu>
+ * AUTHORS:
+
+ Add self to AUTHORS list.
+
+ * fc-cat/fc-cat.c (FcCacheGlobalFileReadAndPrint,
+ FcCacheFileRead, FcCachePrintSet, main):
+ * src/fccache.c (FcGlobalCacheLoad, FcGlobalCacheUpdate,
+ FcGlobalCacheSave, FcCacheNextOffset,
+ FcDirCacheHasCurrentArch, FcDirCacheRead,
+ FcDirCacheConsume, FcDirCacheWrite):
+ * src/fcint.h:
+ * src/fcpat.c (comment):
+
+ Minor change to global cache file format to fix fc-cat bug
+ reported by Frederic Crozat, and buglet with not globally caching
+ directories with zero fonts cached.
+
2006-01-02 Lubos Lunak <l.lunak@suse.cz>
reviewed by: plam
#endif
FcBool
-FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *cache_file);
+FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *base_name);
static FcBool
FcCacheWriteChars (FILE *f, const FcChar8 *chars)
}
static FcBool
-FcCacheGlobalFileReadAndPrint (FcFontSet * set, FcStrSet *dirs, char * dir, char *cache_file)
+FcCacheGlobalFileReadAndPrint (FcFontSet * set, FcStrSet *dirs, char *cache_file)
{
char name_buf[8192];
int fd;
if (fd == -1)
goto bail;
- current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name,
- FcTrue);
+ current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
if (current_arch_start < 0)
goto bail1;
while (1)
{
+ char * dir, * ls;
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))
+ if (!FcDirCacheConsume (fd, name_buf, set))
goto bail1;
- FcCachePrintSet (set, dirs, name_buf);
+ dir = strdup(name_buf);
+ strcat (dir, "/");
+
+ FcCachePrintSet (set, dirs, dir);
+ free (dir);
FcFontSetDestroy (set);
set = FcFontSetCreate();
}
/* read serialized state from the cache file */
-static FcBool
-FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char * dir, char *cache_file)
+static char *
+FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, 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];
+ static char name_buf[8192], *dir;
+ FcChar8 * ls;
if (!cache_file)
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",
+ 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,
- FcFalse);
+ 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 (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))
- goto bail1;
-
+ goto bail2;
+ free (dir);
+
close(fd);
- return FcTrue;
+ return name_buf;
+
+ bail2:
+ free (dir);
bail1:
close (fd);
bail:
- return FcFalse;
+ return 0;
}
/*
}
FcBool
-FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *cache_file)
+FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *base_name)
{
FcPattern *font;
FcChar8 *name, *dir;
while ((dir = FcStrListNext (list)))
{
- base = FcFileBaseName (cache_file, dir);
+ base = FcFileBaseName (base_name, dir);
if (!FcCacheWriteStringOld (stdout, base))
goto bail3;
if (PUTC (' ', stdout) == EOF)
font = set->fonts[n];
if (FcPatternGetString (font, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
goto bail3;
- base = FcFileBaseName (cache_file, file);
+ base = FcFileBaseName (base_name, file);
if (FcPatternGetInteger (font, FC_INDEX, 0, &id) != FcResultMatch)
goto bail3;
if (FcDebug () & FC_DBG_CACHEV)
int c;
FcFontSet *fs = FcFontSetCreate();
FcStrSet *dirs = FcStrSetCreate();
+ char *name_buf;
#if HAVE_GETOPT_LONG
while ((c = getopt_long (argc, argv, "fsVv?", longopts, NULL)) != -1)
if (i >= argc)
usage (argv[0]);
- if (FcCacheFileRead (fs, dirs, dirname (strdup(argv[i])), argv[i]))
- FcCachePrintSet (fs, dirs, argv[i]);
+ if (name_buf = FcCacheFileRead (fs, dirs, argv[i]))
+ FcCachePrintSet (fs, dirs, name_buf);
else
{
FcStrSetDestroy (dirs);
dirs = FcStrSetCreate ();
- if (FcCacheGlobalFileReadAndPrint (fs, dirs, dirname (strdup (argv[i])),
- argv[i]))
+ if (FcCacheGlobalFileReadAndPrint (fs, dirs, argv[i]))
;
}
FcDirCacheHashName (char * cache_file, int collisions);
static off_t
-FcCacheSkipToArch (int fd, const char * arch, FcBool global);
+FcCacheSkipToArch (int fd, const char * arch);
static FcBool
FcCacheCopyOld (int fd, int fd_orig, off_t start);
cache->updated = FcFalse;
+ FcCacheReadString (cache->fd, name_buf, sizeof (name_buf));
+ if (strcmp (name_buf, FC_GLOBAL_MAGIC_COOKIE) != 0)
+ return;
+
current_arch_machine_name = FcCacheMachineSignature ();
current_arch_start = FcCacheSkipToArch(cache->fd,
- current_arch_machine_name, FcTrue);
+ current_arch_machine_name);
if (current_arch_start < 0)
goto bail_and_destroy;
{
FcGlobalCacheDir * d;
- if (!set->nfont)
- return FcTrue;
-
for (d = cache->dirs; d; d = d->next)
{
if (strcmp(d->name, name) == 0)
current_arch_start = 0;
else
current_arch_start = FcCacheSkipToArch (fd_orig,
- current_arch_machine_name,
- FcTrue);
+ current_arch_machine_name);
if (current_arch_start < 0)
current_arch_start = FcCacheNextOffset (lseek(fd_orig, 0, SEEK_END));
}
truncate_to -= current_arch_start;
+ FcCacheWriteString (fd, FC_GLOBAL_MAGIC_COOKIE);
sprintf (header, "%8x ", (int)truncate_to);
strcat (header, current_arch_machine_name);
if (!FcCacheWriteString (fd, header))
for (dir = cache->dirs; dir; dir = dir->next)
{
- if (dir->ent)
+ if (dir->name)
{
FcCacheWriteString (fd, dir->name);
write (fd, &dir->metadata, sizeof(FcCache));
/* return the address of the segment for the provided arch,
* or -1 if arch not found */
static off_t
-FcCacheSkipToArch (int fd, const char * arch, FcBool global)
+FcCacheSkipToArch (int fd, const char * arch)
{
char candidate_arch_machine_name_count[MACHINE_SIGNATURE_SIZE + 9];
char * candidate_arch;
off_t current_arch_start = 0;
lseek (fd, 0, SEEK_SET);
- if (!global)
- FcCacheSkipString (fd);
+ FcCacheSkipString (fd);
current_arch_start = lseek (fd, 0, SEEK_CUR);
/* skip arches that are not the current arch */
goto bail;
current_arch_machine_name = FcCacheMachineSignature();
- current_arch_start = FcCacheSkipToArch(fd,
- current_arch_machine_name, FcFalse);
+ current_arch_start = FcCacheSkipToArch(fd, current_arch_machine_name);
close (fd);
if (current_arch_start < 0)
current_arch_machine_name = FcCacheMachineSignature();
current_arch_start = FcCacheSkipToArch(fd,
- current_arch_machine_name,
- FcFalse);
+ current_arch_machine_name);
if (current_arch_start < 0)
goto bail1;
pos = FcCacheNextOffset (lseek(fd, 0, SEEK_CUR));
current_dir_block = mmap (0, metadata.count,
PROT_READ, MAP_SHARED, fd, pos);
+ lseek (fd, pos+metadata.count, SEEK_SET);
if (current_dir_block == MAP_FAILED)
return FcFalse;
if (fd_orig != -1)
current_arch_start =
- FcCacheSkipToArch(fd_orig, current_arch_machine_name, FcFalse);
+ FcCacheSkipToArch(fd_orig, current_arch_machine_name);
if (current_arch_start < 0)
current_arch_start = FcCacheNextOffset (lseek(fd_orig, 0, SEEK_END));
#define FC_FONT_FILE_INVALID ((FcChar8 *) ".")
#define FC_FONT_FILE_DIR ((FcChar8 *) ".dir")
+#define FC_GLOBAL_MAGIC_COOKIE "GLOBAL"
#ifdef _WIN32
#define FC_SEARCH_PATH_SEPARATOR ';'
/* we don't store these in the FcPattern itself because
* we don't want to serialize the directory names */
-/* I suppose this should be cleaned, too... */
+/* I suppose this should be cleaned upon termination, too... */
typedef struct _FcPatternDirMapping {
const FcPattern *p;
const char *fname;