Mike FABIAN <mfabian@xxxxxxx> さんは書きました: > Patch by Takashi Iwai <tiwai@xxxxxxx>: This patch is obsolete, Takashi made a better one yesterday. Attached.
--- src/fcint.h-dist 2006-01-30 12:15:19.000000000 +0100 +++ src/fcint.h 2006-02-01 19:20:35.000000000 +0100 @@ -328,6 +328,9 @@ typedef struct _FcCaseFold { typedef struct _FcGlobalCacheDir FcGlobalCacheDir; +enum FcGCDirState { + FcGCDirDisabled, FcGCDirFileRead, FcGCDirConsumed, FcGCDirUpdated +}; struct _FcGlobalCacheDir { struct _FcGlobalCacheDir *next; char *name; @@ -335,6 +338,7 @@ struct _FcGlobalCacheDir { off_t offset; FcStrSet *subdirs; void *ent; + enum FcGCDirState state; }; typedef struct _FcGlobalCache { --- src/fccache.c-dist 2006-02-01 12:28:09.000000000 +0100 +++ src/fccache.c 2006-02-01 19:48:28.000000000 +0100 @@ -254,6 +254,12 @@ FcGlobalCacheLoad (FcGlobalCache *cac off_t off; FcStrSetAdd (staleDirs, FcStrCopy ((FcChar8 *)name_buf)); + + /* skip subdirs */ + while (FcCacheReadString (cache->fd, subdirName, + sizeof (subdirName)) && + strlen (subdirName)) + ; if (read (cache->fd, &md, sizeof (FcCache)) != sizeof(FcCache)) { perror ("read metadata"); goto bail1; @@ -275,6 +281,7 @@ FcGlobalCacheLoad (FcGlobalCache *cac d->name = (char *)FcStrCopy ((FcChar8 *)name_buf); d->ent = 0; + d->state = FcGCDirFileRead; d->subdirs = FcStrSetCreate(); do @@ -322,7 +329,6 @@ FcBool FcGlobalCacheReadDir (FcFontSet *set, FcStrSet *dirs, FcGlobalCache * cache, const char *dir, FcConfig *config) { FcGlobalCacheDir *d; - FcBool ret = FcFalse; int i; if (cache->fd == -1) @@ -333,42 +339,62 @@ FcGlobalCacheReadDir (FcFontSet *set, Fc for (d = cache->dirs; d; d = d->next) { - if (strncmp (d->name, dir, strlen(dir)) == 0) + if (strcmp (d->name, dir) == 0) { - lseek (cache->fd, d->offset, SEEK_SET); - if (!FcDirCacheConsume (cache->fd, d->name, set, config)) + if (d->state == FcGCDirDisabled) return FcFalse; - if (strcmp (d->name, dir) == 0) - { + if (d->state == FcGCDirFileRead) { + lseek (cache->fd, d->offset, SEEK_SET); + if (! FcDirCacheConsume (cache->fd, d->name, set, config)) + return FcFalse; + for (i = 0; i < d->subdirs->num; i++) FcStrSetAdd (dirs, (FcChar8 *)d->subdirs->strs[i]); - ret = FcTrue; - } + d->state = FcGCDirConsumed; + } + return FcTrue; } } - return ret; + return FcFalse; } +static FcGlobalCacheDir * +FcGlobalCacheDirFind (FcGlobalCache *cache, const char *name) +{ + FcGlobalCacheDir * d; + + if (! cache || ! name) + return NULL; + + for (d = cache->dirs; d; d = d->next) + if (strcmp((const char *)d->name, (const char *)name) == 0) + return d; + + return NULL; + } + FcBool FcGlobalCacheUpdate (FcGlobalCache *cache, FcStrSet *dirs, - const char *name, + const char *orig_name, FcFontSet *set, FcConfig *config) { FcGlobalCacheDir *d; int i; + const char *name; - name = (char *)FcConfigNormalizeFontDir (config, (FcChar8 *)name); - for (d = cache->dirs; d; d = d->next) - { - if (strcmp(d->name, name) == 0) - break; + name = (char *)FcConfigNormalizeFontDir (config, (FcChar8 *)orig_name); + if (! name) { + fprintf(stderr, "Invalid font name %s\n", orig_name); + return FcFalse; } + d = FcGlobalCacheDirFind (cache, name); + if (!d) { d = malloc (sizeof (FcGlobalCacheDir)); @@ -376,6 +402,11 @@ FcGlobalCacheUpdate (FcGlobalCache *cac return FcFalse; d->next = cache->dirs; cache->dirs = d; + } else { + /* free old resources */ + FcStrFree ((FcChar8 *)d->name); + free (d->ent); + FcStrSetDestroy (d->subdirs); } cache->updated = FcTrue; @@ -384,6 +415,7 @@ FcGlobalCacheUpdate (FcGlobalCache *cac d->ent = FcDirCacheProduce (set, &d->metadata); d->offset = 0; d->subdirs = FcStrSetCreate(); + d->state = FcGCDirUpdated; for (i = 0; i < dirs->num; i++) FcStrSetAdd (d->subdirs, dirs->strs[i]); return FcTrue; @@ -441,9 +473,6 @@ FcGlobalCacheSave (FcGlobalCache *cac if (!FcCacheCopyOld(fd, fd_orig, current_arch_start)) goto bail3; - close (fd_orig); - fd_orig = -1; - current_arch_start = lseek(fd, 0, SEEK_CUR); if (ftruncate (fd, current_arch_start) == -1) goto bail3; @@ -455,6 +484,8 @@ FcGlobalCacheSave (FcGlobalCache *cac truncate_to = current_arch_start + strlen(current_arch_machine_name) + 11; for (dir = cache->dirs; dir; dir = dir->next) { + if (dir->state == FcGCDirDisabled) + continue; truncate_to += strlen(dir->name) + 1; truncate_to += sizeof (FcCache); truncate_to = FcCacheNextOffset (truncate_to); @@ -473,11 +504,39 @@ FcGlobalCacheSave (FcGlobalCache *cac for (dir = cache->dirs; dir; dir = dir->next) { - if (dir->name) - { - const char * d = (const char *)FcConfigNormalizeFontDir (config, (const FcChar8 *)dir->name); + const char * d; + + if (! dir->name || dir->state == FcGCDirDisabled) + continue; + d = (const char *)FcConfigNormalizeFontDir (config, (const FcChar8 *)dir->name); + if (d) { off_t off; + if (dir->metadata.count && ! dir->ent) { + if (dir->state == FcGCDirUpdated || fd_orig < 0) { + fprintf(stderr, "Invalid metadata entry for %s, skipping...\n", d); + continue; + } + /* copy the old content */ + dir->ent = malloc(dir->metadata.count); + if (! dir->ent) { + perror("malloc error"); + continue; + } + off = FcCacheNextOffset (dir->offset + sizeof(FcCache)); + if (lseek(fd_orig, off, SEEK_SET) != off) { + perror("lseek"); + free(dir->ent); + continue; + } + if (read(fd_orig, dir->ent, dir->metadata.count) + != dir->metadata.count) { + perror("read"); + free(dir->ent); + continue; + } + } + FcCacheWriteString (fd, d); for (i = 0; i < dir->subdirs->size; i++) @@ -497,20 +556,25 @@ FcGlobalCacheSave (FcGlobalCache *cac free (dir->ent); continue; } - if (write (fd, dir->ent, dir->metadata.count) != dir->metadata.count) - { - perror ("write dirent"); - free (dir->ent); - continue; + if (dir->metadata.count) { + if (write (fd, dir->ent, dir->metadata.count) != dir->metadata.count) + { + perror ("write dirent"); + free (dir->ent); + continue; + } } - free (dir->ent); - } + free (dir->ent); + } } FcCacheWriteString (fd, ""); if (close (fd) == -1) goto bail25; + close (fd_orig); + fd_orig = -1; + if (!FcAtomicReplaceOrig (atomic)) goto bail25; @@ -792,10 +856,11 @@ FcCacheReadDirs (FcConfig * config, FcGl { int ret = 0; FcChar8 *dir; - FcChar8 *file, *base; + const FcChar8 *name; FcStrSet *subdirs; FcStrList *sublist; struct stat statb; + FcGlobalCacheDir * d; /* * Read in the results from 'list'. @@ -805,21 +870,21 @@ FcCacheReadDirs (FcConfig * config, FcGl if (!FcConfigAcceptFilename (config, dir)) continue; - /* freed below */ - file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1); - if (!file) - return FcFalse; - - strcpy ((char *) file, (char *) dir); - strcat ((char *) file, "/"); - base = file + strlen ((char *) file); + /* Skip this directory if already updated + * to avoid the looped directories via symlinks + */ + name = FcConfigNormalizeFontDir (config, dir); + if (name) { + if ((d = FcGlobalCacheDirFind (cache, (const char *)name)) != NULL && + d->state == FcGCDirUpdated) + continue; + } subdirs = FcStrSetCreate (); if (!subdirs) { fprintf (stderr, "Can't create directory set\n"); ret++; - free (file); continue; } @@ -836,7 +901,6 @@ FcCacheReadDirs (FcConfig * config, FcGl ret++; } FcStrSetDestroy (subdirs); - free (file); continue; } if (stat ((char *) dir, &statb) == -1) @@ -845,17 +909,24 @@ FcCacheReadDirs (FcConfig * config, FcGl perror (""); FcStrSetDestroy (subdirs); ret++; - free (file); continue; } if (!S_ISDIR (statb.st_mode)) { fprintf (stderr, "\"%s\": not a directory, skipping\n", dir); FcStrSetDestroy (subdirs); - free (file); continue; } - if (!FcDirCacheValid (dir) || !FcDirCacheRead (set, subdirs, dir, config)) + if (FcDirCacheValid (dir) && FcDirCacheRead (set, subdirs, dir, config)) + { + /* if an old entry is found in the global cache, disable it */ + if ((d = FcGlobalCacheDirFind (cache, (const char *)name)) != NULL) { + d->state = FcGCDirDisabled; + /* save the updated config later without this entry */ + cache->updated = FcTrue; + } + } + else { if (FcDebug () & FC_DBG_FONTSET) printf ("cache scan dir %s\n", dir); @@ -869,11 +940,9 @@ FcCacheReadDirs (FcConfig * config, FcGl { fprintf (stderr, "Can't create subdir list in \"%s\"\n", dir); ret++; - free (file); continue; } ret += FcCacheReadDirs (config, cache, sublist, set); - free (file); } FcStrListDone (list); return ret; --- src/fcdir.c-dist 2006-01-30 12:15:19.000000000 +0100 +++ src/fcdir.c 2006-02-01 17:05:50.000000000 +0100 @@ -47,14 +47,17 @@ FcFileScanConfig (FcFontSet *set, int id; FcPattern *font; FcBool ret = FcTrue; - FcBool isDir; int count = 0; if (config && !FcConfigAcceptFilename (config, file)) return FcTrue; + if (FcFileIsDir (file)) + return FcStrSetAdd (dirs, file); + if (force) cache = 0; + id = 0; do { @@ -70,12 +73,6 @@ FcFileScanConfig (FcFontSet *set, font = FcFreeTypeQuery (file, id, blanks, &count); if (FcDebug () & FC_DBG_SCAN) printf ("done\n"); - isDir = FcFalse; - if (!font && FcFileIsDir (file)) - { - isDir = FcTrue; - ret = FcStrSetAdd (dirs, file); - } /* * Add the font */
-- Mike FABIAN <mfabian@xxxxxxx> http://www.suse.de/~mfabian 睡眠不足はいい仕事の敵だ。
_______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/fontconfig