diff -ur fontconfig-2.3.2/ChangeLog fontconfig-2.3.2.cachefix/ChangeLog --- fontconfig-2.3.2/ChangeLog 2005-04-27 21:00:13.000000000 +0200 +++ fontconfig-2.3.2.cachefix/ChangeLog 2006-03-23 18:25:02.000000000 +0100 @@ -1,3 +1,10 @@ +2006-03-23 Han-Wen Nienhuys + + * src/fccache.c (NormalizeFileName): new function. Clear + superflous slashes. + (FcDirCacheValid): rewrite. Use NormalizeFileName. + This fixes FontConfig caching on mingw target. + 2005-04-27 Keith Packard * README: Only in fontconfig-2.3.2.cachefix/: ChangeLog~ diff -ur fontconfig-2.3.2/src/fccache.c fontconfig-2.3.2.cachefix/src/fccache.c --- fontconfig-2.3.2/src/fccache.c 2005-01-04 22:53:36.000000000 +0100 +++ fontconfig-2.3.2.cachefix/src/fccache.c 2006-03-23 18:28:34.000000000 +0100 @@ -24,6 +24,9 @@ #include "fcint.h" +static FcChar8 *NormalizeFileName (FcChar8 const *name); + + /* * POSIX has broken stdio so that getc must do thread-safe locking, * this is a serious performance problem for applications doing large @@ -956,36 +959,88 @@ return FcFalse; } -FcBool -FcDirCacheValid (const FcChar8 *dir) +/* + Remove double and trailing slashes. + */ +static FcChar8 * +NormalizeFileName (FcChar8 const *name) { - FcChar8 *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE); - struct stat file_stat, dir_stat; + FcChar8 *new_name = FcStrCopy (name); - if (stat ((char *) dir, &dir_stat) < 0) + FcChar8 *n = new_name; + FcChar8 *c = name; + FcChar8 last = 0; + size_t len = 0; + + if (new_name == NULL) + return new_name; + + for (; *c; c++) { - FcStrFree (cache_file); - return FcFalse; + if (*c == '/' && last == '/') + continue; + + *n++ = *c; + last = *c; } - if (stat ((char *) cache_file, &file_stat) < 0) + + *n = 0; + + len = n - new_name; + + while (len > 0 + && new_name[len-1] == '/') { - FcStrFree (cache_file); - return FcFalse; + new_name[len-1] = 0; + len--; } + + return new_name; +} + + +FcBool +FcDirCacheValid (const FcChar8 *dir) +{ + FcChar8 *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE); + FcChar8 *sane_cache_file = NormalizeFileName (cache_file); + FcChar8 *sane_dir = NormalizeFileName (dir); + int result = FcFalse; + int debug = (FcDebug () & FC_DBG_CACHE); + + struct stat file_stat, dir_stat; + if (stat ((char *) sane_dir, &dir_stat) < 0) + { + if (debug) + printf ("Cannot stat dir %s\n", sane_dir); + } + else if (stat ((char *) sane_cache_file, &file_stat) < 0) + { + if (debug) + printf ("Cannot stat cache file %s\n", sane_cache_file); + } + else if (dir_stat.st_mtime - file_stat.st_mtime > 0) + { + if (debug) + printf ("Cache file %s is older than dir", sane_cache_file); + } + else + { + result = FcTrue; + } + FcStrFree (cache_file); - /* - * If the directory has been modified more recently than - * the cache file, the cache is not valid - */ - if (dir_stat.st_mtime - file_stat.st_mtime > 0) - return FcFalse; - return FcTrue; + FcStrFree (sane_cache_file); + FcStrFree (sane_dir); + + return result; } FcBool FcDirCacheReadDir (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *config) { - FcChar8 *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE); + FcChar8 *insane_cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE); + FcChar8 *cache_file = NormalizeFileName (insane_cache_file); FILE *f; FcChar8 *base; int id; @@ -994,26 +1049,29 @@ FcChar8 name_buf[8192], *name; FcBool ret = FcFalse; + FcStrFree (insane_cache_file); + if (!cache_file) goto bail0; - + if (FcDebug () & FC_DBG_CACHE) printf ("FcDirCacheReadDir cache_file \"%s\"\n", cache_file); - f = fopen ((char *) cache_file, "r"); - if (!f) + if (!FcDirCacheValid (dir)) { if (FcDebug () & FC_DBG_CACHE) - printf (" no cache file\n"); + printf (" cache file invalid.\n"); goto bail1; } - if (!FcDirCacheValid (dir)) + f = fopen ((char *) cache_file, "r"); + if (!f) { if (FcDebug () & FC_DBG_CACHE) - printf (" cache file older than directory\n"); - goto bail2; + printf (" no cache file\n"); + goto bail1; } + base = (FcChar8 *) strrchr ((char *) cache_file, '/'); if (!base) Only in fontconfig-2.3.2.cachefix/src: fccache.c~