Read the config files and fonts on the sysroot when --sysroot is given to fc-cache

Fix for e96d776088

https://bugs.freedesktop.org/show_bug.cgi?id=59456
This commit is contained in:
Akira TAGOH 2014-06-17 20:08:24 +09:00
parent 8f62ccaa96
commit d17f556153
7 changed files with 158 additions and 44 deletions

View File

@ -128,6 +128,7 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force,
struct stat statb; struct stat statb;
FcBool was_valid; FcBool was_valid;
int i; int i;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
/* /*
* Now scan all of the directories into separate databases * Now scan all of the directories into separate databases
@ -138,8 +139,9 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force,
if (verbose) if (verbose)
{ {
if (!recursive) if (!recursive)
printf ("Re-scanning %s: ", dir); printf ("Re-scanning ");
else if (sysroot)
printf ("[%s]", sysroot);
printf ("%s: ", dir); printf ("%s: ", dir);
fflush (stdout); fflush (stdout);
} }

View File

@ -177,19 +177,28 @@ FcDirCacheOpenFile (const FcChar8 *cache_file, struct stat *file_stat)
*/ */
static FcBool static FcBool
FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
FcBool (*callback) (int fd, struct stat *fd_stat, FcBool (*callback) (FcConfig *config, int fd, struct stat *fd_stat,
struct stat *dir_stat, void *closure), struct stat *dir_stat, void *closure),
void *closure, FcChar8 **cache_file_ret) void *closure, FcChar8 **cache_file_ret)
{ {
int fd = -1; int fd = -1;
FcChar8 cache_base[CACHEBASE_LEN]; FcChar8 cache_base[CACHEBASE_LEN];
FcStrList *list; FcStrList *list;
FcChar8 *cache_dir; FcChar8 *cache_dir, *d;
struct stat file_stat, dir_stat; struct stat file_stat, dir_stat;
FcBool ret = FcFalse; FcBool ret = FcFalse;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
if (FcStatChecksum (dir, &dir_stat) < 0) if (sysroot)
d = FcStrBuildFilename (sysroot, dir, NULL);
else
d = FcStrdup (dir);
if (FcStatChecksum (d, &dir_stat) < 0)
{
FcStrFree (d);
return FcFalse; return FcFalse;
}
FcStrFree (d);
FcDirCacheBasename (dir, cache_base); FcDirCacheBasename (dir, cache_base);
@ -199,7 +208,6 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
while ((cache_dir = FcStrListNext (list))) while ((cache_dir = FcStrListNext (list)))
{ {
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcChar8 *cache_hashed; FcChar8 *cache_hashed;
if (sysroot) if (sysroot)
@ -210,7 +218,7 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
break; break;
fd = FcDirCacheOpenFile (cache_hashed, &file_stat); fd = FcDirCacheOpenFile (cache_hashed, &file_stat);
if (fd >= 0) { if (fd >= 0) {
ret = (*callback) (fd, &file_stat, &dir_stat, closure); ret = (*callback) (config, fd, &file_stat, &dir_stat, closure);
close (fd); close (fd);
if (ret) if (ret)
{ {
@ -529,14 +537,25 @@ FcCacheFini (void)
} }
static FcBool static FcBool
FcCacheTimeValid (FcCache *cache, struct stat *dir_stat) FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat)
{ {
struct stat dir_static; struct stat dir_static;
if (!dir_stat) if (!dir_stat)
{ {
if (FcStatChecksum (FcCacheDir (cache), &dir_static) < 0) const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcChar8 *d;
if (sysroot)
d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL);
else
d = FcStrdup (FcCacheDir (cache));
if (FcStatChecksum (d, &dir_static) < 0)
{
FcStrFree (d);
return FcFalse; return FcFalse;
}
FcStrFree (d);
dir_stat = &dir_static; dir_stat = &dir_static;
} }
if (FcDebug () & FC_DBG_CACHE) if (FcDebug () & FC_DBG_CACHE)
@ -546,21 +565,28 @@ FcCacheTimeValid (FcCache *cache, struct stat *dir_stat)
} }
static FcBool static FcBool
FcCacheDirsValid (FcCache *cache) FcCacheDirsValid (FcConfig *config, FcCache *cache)
{ {
FcStrSet *dirs = FcStrSetCreate (); FcStrSet *dirs = FcStrSetCreate ();
FcBool ret = FcFalse; FcBool ret = FcFalse;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcChar8 *d;
if (!dirs) if (!dirs)
goto bail; goto bail;
if (!FcDirScanOnly (dirs, FcCacheDir (cache))) if (sysroot)
d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL);
else
d = FcStrdup (FcCacheDir (cache));
if (!FcDirScanOnly (dirs, d, config))
goto bail1; goto bail1;
ret = cache->dirs_count == dirs->num; ret = cache->dirs_count == dirs->num;
if (FcDebug () & FC_DBG_CACHE) if (FcDebug () & FC_DBG_CACHE)
printf ("%s: cache: %d, fs: %d\n", FcCacheDir (cache), cache->dirs_count, dirs->num); printf ("%s: cache: %d, fs: %d\n", d, cache->dirs_count, dirs->num);
bail1: bail1:
FcStrSetDestroy (dirs); FcStrSetDestroy (dirs);
FcStrFree (d);
bail: bail:
return ret; return ret;
} }
@ -569,7 +595,7 @@ bail:
* Map a cache file into memory * Map a cache file into memory
*/ */
static FcCache * static FcCache *
FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat) FcDirCacheMapFd (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat)
{ {
FcCache *cache; FcCache *cache;
FcBool allocated = FcFalse; FcBool allocated = FcFalse;
@ -579,8 +605,8 @@ FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat)
cache = FcCacheFindByStat (fd_stat); cache = FcCacheFindByStat (fd_stat);
if (cache) if (cache)
{ {
if (FcCacheTimeValid (cache, dir_stat) && if (FcCacheTimeValid (config, cache, dir_stat) &&
FcCacheDirsValid (cache)) FcCacheDirsValid (config, cache))
return cache; return cache;
FcDirCacheUnload (cache); FcDirCacheUnload (cache);
cache = NULL; cache = NULL;
@ -631,8 +657,8 @@ FcDirCacheMapFd (int fd, struct stat *fd_stat, struct stat *dir_stat)
if (cache->magic != FC_CACHE_MAGIC_MMAP || if (cache->magic != FC_CACHE_MAGIC_MMAP ||
cache->version < FC_CACHE_CONTENT_VERSION || cache->version < FC_CACHE_CONTENT_VERSION ||
cache->size != (intptr_t) fd_stat->st_size || cache->size != (intptr_t) fd_stat->st_size ||
!FcCacheTimeValid (cache, dir_stat) || !FcCacheTimeValid (config, cache, dir_stat) ||
!FcCacheDirsValid (cache) || !FcCacheDirsValid (config, cache) ||
!FcCacheInsert (cache, fd_stat)) !FcCacheInsert (cache, fd_stat))
{ {
if (allocated) if (allocated)
@ -671,9 +697,9 @@ FcDirCacheUnload (FcCache *cache)
} }
static FcBool static FcBool
FcDirCacheMapHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure) FcDirCacheMapHelper (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure)
{ {
FcCache *cache = FcDirCacheMapFd (fd, fd_stat, dir_stat); FcCache *cache = FcDirCacheMapFd (config, fd, fd_stat, dir_stat);
if (!cache) if (!cache)
return FcFalse; return FcFalse;
@ -690,6 +716,7 @@ FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file)
FcDirCacheMapHelper, FcDirCacheMapHelper,
&cache, cache_file)) &cache, cache_file))
return NULL; return NULL;
return cache; return cache;
} }
@ -705,7 +732,7 @@ FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat)
fd = FcDirCacheOpenFile (cache_file, file_stat); fd = FcDirCacheOpenFile (cache_file, file_stat);
if (fd < 0) if (fd < 0)
return NULL; return NULL;
cache = FcDirCacheMapFd (fd, file_stat, NULL); cache = FcDirCacheMapFd (FcConfigGetCurrent (), fd, file_stat, NULL);
close (fd); close (fd);
return cache; return cache;
} }
@ -715,7 +742,7 @@ FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat)
* the magic number and the size field * the magic number and the size field
*/ */
static FcBool static FcBool
FcDirCacheValidateHelper (int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure FC_UNUSED) FcDirCacheValidateHelper (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure FC_UNUSED)
{ {
FcBool ret = FcTrue; FcBool ret = FcTrue;
FcCache c; FcCache c;
@ -1080,15 +1107,22 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
} }
else else
{ {
FcChar8 *s;
target_dir = FcCacheDir (cache); target_dir = FcCacheDir (cache);
if (stat ((char *) target_dir, &target_stat) < 0) if (sysroot)
s = FcStrBuildFilename (sysroot, target_dir, NULL);
else
s = FcStrdup (target_dir);
if (stat ((char *) s, &target_stat) < 0)
{ {
if (verbose || FcDebug () & FC_DBG_CACHE) if (verbose || FcDebug () & FC_DBG_CACHE)
printf ("%s: %s: missing directory: %s \n", printf ("%s: %s: missing directory: %s \n",
dir, ent->d_name, target_dir); dir, ent->d_name, s);
remove = FcTrue; remove = FcTrue;
} }
FcDirCacheUnload (cache); FcDirCacheUnload (cache);
FcStrFree (s);
} }
if (remove) if (remove)
{ {

View File

@ -69,6 +69,7 @@ FcFileScanFontConfig (FcFontSet *set,
FcBool ret = FcTrue; FcBool ret = FcTrue;
int id; int id;
int count = 0; int count = 0;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
id = 0; id = 0;
do do
@ -85,6 +86,28 @@ FcFileScanFontConfig (FcFontSet *set,
font = FcFreeTypeQuery (file, id, blanks, &count); font = FcFreeTypeQuery (file, id, blanks, &count);
if (FcDebug () & FC_DBG_SCAN) if (FcDebug () & FC_DBG_SCAN)
printf ("done\n"); printf ("done\n");
/*
* Get rid of sysroot here so that targeting scan rule may contains FC_FILE pattern
* and they should usually expect without sysroot.
*/
if (sysroot)
{
size_t len = strlen ((const char *)sysroot);
FcChar8 *f = NULL;
if (FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &f) == FcResultMatch &&
strncmp ((const char *)f, (const char *)sysroot, len) == 0)
{
FcChar8 *s = FcStrdup (f);
FcPatternObjectDel (font, FC_FILE_OBJECT);
if (s[len] != '/')
len--;
else if (s[len+1] == '/')
len++;
FcPatternObjectAddString (font, FC_FILE_OBJECT, &s[len]);
FcStrFree (s);
}
}
/* /*
* Edit pattern with user-defined rules * Edit pattern with user-defined rules
@ -128,7 +151,23 @@ FcFileScanConfig (FcFontSet *set,
FcConfig *config) FcConfig *config)
{ {
if (FcFileIsDir (file)) if (FcFileIsDir (file))
return FcStrSetAdd (dirs, file); {
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
const FcChar8 *d;
size_t len = strlen ((const char *)sysroot);
if (sysroot && strncmp ((const char *)file, (const char *)sysroot, len) == 0)
{
if (file[len] != '/')
len--;
else if (file[len+1] == '/')
len++;
d = &file[len];
}
else
d = file;
return FcStrSetAdd (dirs, d);
}
else else
{ {
if (set) if (set)
@ -238,7 +277,7 @@ FcDirScanConfig (FcFontSet *set,
if (scanOnly) if (scanOnly)
{ {
if (FcFileIsDir (files->strs[i])) if (FcFileIsDir (files->strs[i]))
FcStrSetAdd (dirs, files->strs[i]); FcFileScanConfig (NULL, dirs, NULL, files->strs[i], config);
} }
else else
{ {
@ -273,9 +312,10 @@ FcDirScan (FcFontSet *set,
FcBool FcBool
FcDirScanOnly (FcStrSet *dirs, FcDirScanOnly (FcStrSet *dirs,
const FcChar8 *dir) const FcChar8 *dir,
FcConfig *config)
{ {
return FcDirScanConfig (NULL, dirs, NULL, dir, FcTrue, NULL, FcTrue); return FcDirScanConfig (NULL, dirs, NULL, dir, FcTrue, config, FcTrue);
} }
/* /*
@ -288,11 +328,18 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
FcFontSet *set; FcFontSet *set;
FcCache *cache = NULL; FcCache *cache = NULL;
struct stat dir_stat; struct stat dir_stat;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcChar8 *d;
if (sysroot)
d = FcStrBuildFilename (sysroot, dir, NULL);
else
d = FcStrdup (dir);
if (FcDebug () & FC_DBG_FONTSET) if (FcDebug () & FC_DBG_FONTSET)
printf ("cache scan dir %s\n", dir); printf ("cache scan dir %s\n", d);
if (FcStatChecksum (dir, &dir_stat) < 0) if (FcStatChecksum (d, &dir_stat) < 0)
goto bail; goto bail;
set = FcFontSetCreate(); set = FcFontSetCreate();
@ -306,7 +353,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
/* /*
* Scan the dir * Scan the dir
*/ */
if (!FcDirScanConfig (set, dirs, NULL, dir, FcTrue, config, FcFalse)) if (!FcDirScanConfig (set, dirs, NULL, d, FcTrue, config, FcFalse))
goto bail2; goto bail2;
/* /*
@ -326,20 +373,30 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
bail1: bail1:
FcFontSetDestroy (set); FcFontSetDestroy (set);
bail: bail:
FcStrFree (d);
return cache; return cache;
} }
FcCache * FcCache *
FcDirCacheRescan (const FcChar8 *dir, FcConfig *config) FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
{ {
FcCache *cache = FcDirCacheLoad (dir, config, NULL); FcCache *cache;
FcCache *new = NULL; FcCache *new = NULL;
struct stat dir_stat; struct stat dir_stat;
FcStrSet *dirs; FcStrSet *dirs;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcChar8 *d = NULL;
cache = FcDirCacheLoad (dir, config, NULL);
if (!cache) if (!cache)
return NULL; goto bail;
if (FcStatChecksum (dir, &dir_stat) < 0)
if (sysroot)
d = FcStrBuildFilename (sysroot, dir, NULL);
else
d = FcStrdup (dir);
if (FcStatChecksum (d, &dir_stat) < 0)
goto bail; goto bail;
dirs = FcStrSetCreate (); dirs = FcStrSetCreate ();
if (!dirs) if (!dirs)
@ -348,7 +405,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
/* /*
* Scan the dir * Scan the dir
*/ */
if (!FcDirScanConfig (NULL, dirs, NULL, dir, FcTrue, config, FcFalse)) if (!FcDirScanConfig (NULL, dirs, NULL, d, FcTrue, config, FcFalse))
goto bail1; goto bail1;
/* /*
* Rebuild the cache object * Rebuild the cache object
@ -365,6 +422,9 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
bail1: bail1:
FcStrSetDestroy (dirs); FcStrSetDestroy (dirs);
bail: bail:
if (d)
FcStrFree (d);
return new; return new;
} }

View File

@ -36,13 +36,14 @@
#endif #endif
static FcConfig * static FcConfig *
FcInitFallbackConfig (void) FcInitFallbackConfig (const FcChar8 *sysroot)
{ {
FcConfig *config; FcConfig *config;
config = FcConfigCreate (); config = FcConfigCreate ();
if (!config) if (!config)
goto bail0; goto bail0;
FcConfigSetSysRoot (config, sysroot);
if (!FcConfigAddDir (config, (FcChar8 *) FC_DEFAULT_FONTS)) if (!FcConfigAddDir (config, (FcChar8 *) FC_DEFAULT_FONTS))
goto bail1; goto bail1;
if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR)) if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR))
@ -78,8 +79,12 @@ FcInitLoadOwnConfig (FcConfig *config)
if (!FcConfigParseAndLoad (config, 0, FcTrue)) if (!FcConfigParseAndLoad (config, 0, FcTrue))
{ {
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcConfig *fallback = FcInitFallbackConfig (sysroot);
FcConfigDestroy (config); FcConfigDestroy (config);
return FcInitFallbackConfig ();
return fallback;
} }
if (config->cacheDirs && config->cacheDirs->num == 0) if (config->cacheDirs && config->cacheDirs->num == 0)
@ -108,13 +113,19 @@ FcInitLoadOwnConfig (FcConfig *config)
if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) || if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
!FcConfigAddCacheDir (config, (FcChar8 *) prefix)) !FcConfigAddCacheDir (config, (FcChar8 *) prefix))
{ {
FcConfig *fallback;
const FcChar8 *sysroot;
bail: bail:
sysroot = FcConfigGetSysRoot (config);
fprintf (stderr, fprintf (stderr,
"Fontconfig error: out of memory"); "Fontconfig error: out of memory");
if (prefix) if (prefix)
FcStrFree (prefix); FcStrFree (prefix);
fallback = FcInitFallbackConfig (sysroot);
FcConfigDestroy (config); FcConfigDestroy (config);
return FcInitFallbackConfig ();
return fallback;
} }
FcStrFree (prefix); FcStrFree (prefix);
} }

View File

@ -854,7 +854,8 @@ FcDirScanConfig (FcFontSet *set,
FcPrivate FcBool FcPrivate FcBool
FcDirScanOnly (FcStrSet *dirs, FcDirScanOnly (FcStrSet *dirs,
const FcChar8 *dir); const FcChar8 *dir,
FcConfig *config);
/* fcfont.c */ /* fcfont.c */
FcPrivate int FcPrivate int

View File

@ -3129,11 +3129,12 @@ FcConfigParseAndLoad (FcConfig *config,
{ {
XML_Parser p; XML_Parser p;
FcChar8 *filename; FcChar8 *filename, *f;
int fd; int fd;
int len; int len;
FcConfigParse parse; FcConfigParse parse;
FcBool error = FcTrue; FcBool error = FcTrue;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
#ifdef ENABLE_LIBXML2 #ifdef ENABLE_LIBXML2
xmlSAXHandler sax; xmlSAXHandler sax;
@ -3158,9 +3159,14 @@ FcConfigParseAndLoad (FcConfig *config,
} }
#endif #endif
filename = FcConfigFilename (name); f = FcConfigFilename (name);
if (!filename) if (!f)
goto bail0; goto bail0;
if (sysroot)
filename = FcStrBuildFilename (sysroot, f, NULL);
else
filename = FcStrdup (f);
FcStrFree (f);
if (FcStrSetMember (config->configFiles, filename)) if (FcStrSetMember (config->configFiles, filename))
{ {