diff --git a/AUTHORS b/AUTHORS index 9cee037..5ef8885 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,3 @@ Keith Packard +Patrick Lam + diff --git a/ChangeLog b/ChangeLog index ee3fb89..645cb83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-01-05 Patrick Lam + * 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 reviewed by: plam diff --git a/fc-cat/fc-cat.c b/fc-cat/fc-cat.c index f088e45..14e5c16 100644 --- a/fc-cat/fc-cat.c +++ b/fc-cat/fc-cat.c @@ -79,7 +79,7 @@ extern int optind, opterr, optopt; #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) @@ -168,7 +168,7 @@ usage (char *program) } 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; @@ -184,8 +184,7 @@ FcCacheGlobalFileReadAndPrint (FcFontSet * set, FcStrSet *dirs, char * dir, char 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; @@ -196,16 +195,21 @@ FcCacheGlobalFileReadAndPrint (FcFontSet * set, FcStrSet *dirs, char * dir, char 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(); @@ -218,15 +222,16 @@ FcCacheGlobalFileReadAndPrint (FcFontSet * set, FcStrSet *dirs, char * dir, char } /* 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; @@ -239,32 +244,37 @@ FcCacheFileRead (FcFontSet * set, FcStrSet *dirs, char * dir, char *cache_file) 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; } /* @@ -284,7 +294,7 @@ FcFileBaseName (const char *cache, const FcChar8 *file) } FcBool -FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *cache_file) +FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *base_name) { FcPattern *font; FcChar8 *name, *dir; @@ -300,7 +310,7 @@ FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *cache_file) while ((dir = FcStrListNext (list))) { - base = FcFileBaseName (cache_file, dir); + base = FcFileBaseName (base_name, dir); if (!FcCacheWriteStringOld (stdout, base)) goto bail3; if (PUTC (' ', stdout) == EOF) @@ -320,7 +330,7 @@ FcCachePrintSet (FcFontSet *set, FcStrSet *dirs, char *cache_file) 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) @@ -362,6 +372,7 @@ main (int argc, char **argv) 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) @@ -386,14 +397,13 @@ main (int argc, char **argv) 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])) ; } diff --git a/src/fccache.c b/src/fccache.c index 98f6d00..50dc4d1 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -43,7 +43,7 @@ static char * 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); @@ -219,9 +219,13 @@ FcGlobalCacheLoad (FcGlobalCache *cache, 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; @@ -325,9 +329,6 @@ FcGlobalCacheUpdate (FcGlobalCache *cache, { FcGlobalCacheDir * d; - if (!set->nfont) - return FcTrue; - for (d = cache->dirs; d; d = d->next) { if (strcmp(d->name, name) == 0) @@ -388,8 +389,7 @@ FcGlobalCacheSave (FcGlobalCache *cache, 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)); @@ -418,6 +418,7 @@ FcGlobalCacheSave (FcGlobalCache *cache, } 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)) @@ -425,7 +426,7 @@ FcGlobalCacheSave (FcGlobalCache *cache, for (dir = cache->dirs; dir; dir = dir->next) { - if (dir->ent) + if (dir->name) { FcCacheWriteString (fd, dir->name); write (fd, &dir->metadata, sizeof(FcCache)); @@ -483,15 +484,14 @@ FcCacheNextOffset(off_t w) /* 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 */ @@ -652,8 +652,7 @@ FcDirCacheHasCurrentArch (const FcChar8 *dir) 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) @@ -929,8 +928,7 @@ FcDirCacheRead (FcFontSet * set, FcStrSet * dirs, const FcChar8 *dir) 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; @@ -973,6 +971,7 @@ FcDirCacheConsume (int fd, const char * dir, FcFontSet *set) 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; @@ -1122,7 +1121,7 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir) 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)); diff --git a/src/fcint.h b/src/fcint.h index c3430ae..435af82 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -48,6 +48,7 @@ #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 ';' diff --git a/src/fcpat.c b/src/fcpat.c index 9a33e1c..f150614 100644 --- a/src/fcpat.c +++ b/src/fcpat.c @@ -2000,7 +2000,7 @@ FcStrUnserialize (FcCache * metadata, void *block_ptr) /* 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;