aboutsummaryrefslogtreecommitdiff
path: root/fontconfig/src
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig/src')
-rw-r--r--fontconfig/src/fccache.c99
-rw-r--r--fontconfig/src/fccfg.c57
-rw-r--r--fontconfig/src/fcinit.c30
-rw-r--r--fontconfig/src/fcint.h15
-rw-r--r--fontconfig/src/fclang.c4
-rw-r--r--fontconfig/src/fcstr.c62
6 files changed, 223 insertions, 44 deletions
diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c
index 36111bd89..fab2c1f2c 100644
--- a/fontconfig/src/fccache.c
+++ b/fontconfig/src/fccache.c
@@ -124,6 +124,7 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
FcChar8 cache_base[CACHEBASE_LEN];
FcStrList *list;
FcChar8 *cache_dir;
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcDirCacheBasename (dir, cache_base);
@@ -133,7 +134,10 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config)
while ((cache_dir = FcStrListNext (list)))
{
- cache_hashed = FcStrPlus (cache_dir, cache_base);
+ if (sysroot)
+ cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL);
+ else
+ cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL);
if (!cache_hashed)
break;
(void) unlink ((char *) cache_hashed);
@@ -197,7 +201,13 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
while ((cache_dir = FcStrListNext (list)))
{
- FcChar8 *cache_hashed = FcStrPlus (cache_dir, cache_base);
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
+ FcChar8 *cache_hashed;
+
+ if (sysroot)
+ cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL);
+ else
+ cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL);
if (!cache_hashed)
break;
fd = FcDirCacheOpenFile (cache_hashed, &file_stat);
@@ -859,11 +869,12 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
FcAtomic *atomic;
FcStrList *list;
FcChar8 *cache_dir = NULL;
- FcChar8 *test_dir;
+ FcChar8 *test_dir, *d = NULL;
FcCacheSkip *skip;
struct stat cache_stat;
unsigned int magic;
int written;
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
/*
* Write it to the first directory in the list which is writable
@@ -872,10 +883,18 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
list = FcStrListCreate (config->cacheDirs);
if (!list)
return FcFalse;
- while ((test_dir = FcStrListNext (list))) {
- if (access ((char *) test_dir, W_OK) == 0)
+ while ((test_dir = FcStrListNext (list)))
+ {
+ if (d)
+ FcStrFree (d);
+ if (sysroot)
+ d = FcStrBuildFilename (sysroot, test_dir, NULL);
+ else
+ d = FcStrCopyFilename (test_dir);
+
+ if (access ((char *) d, W_OK) == 0)
{
- cache_dir = test_dir;
+ cache_dir = FcStrCopyFilename (d);
break;
}
else
@@ -883,35 +902,38 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
/*
* If the directory doesn't exist, try to create it
*/
- if (access ((char *) test_dir, F_OK) == -1) {
- if (FcMakeDirectory (test_dir))
+ if (access ((char *) d, F_OK) == -1) {
+ if (FcMakeDirectory (d))
{
- cache_dir = test_dir;
+ cache_dir = FcStrCopyFilename (d);
/* Create CACHEDIR.TAG */
- FcDirCacheCreateTagFile (cache_dir);
+ FcDirCacheCreateTagFile (d);
break;
}
}
/*
* Otherwise, try making it writable
*/
- else if (chmod ((char *) test_dir, 0755) == 0)
+ else if (chmod ((char *) d, 0755) == 0)
{
- cache_dir = test_dir;
+ cache_dir = FcStrCopyFilename (d);
/* Try to create CACHEDIR.TAG too */
- FcDirCacheCreateTagFile (cache_dir);
+ FcDirCacheCreateTagFile (d);
break;
}
}
}
+ if (d)
+ FcStrFree (d);
FcStrListDone (list);
if (!cache_dir)
return FcFalse;
FcDirCacheBasename (dir, cache_base);
- cache_hashed = FcStrPlus (cache_dir, cache_base);
+ cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL);
if (!cache_hashed)
return FcFalse;
+ FcStrFree (cache_dir);
if (FcDebug () & FC_DBG_CACHE)
printf ("FcDirCacheWriteDir dir \"%s\" file \"%s\"\n",
@@ -989,31 +1011,37 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
{
DIR *d;
struct dirent *ent;
- FcChar8 *dir_base;
+ FcChar8 *dir;
FcBool ret = FcTrue;
FcBool remove;
FcCache *cache;
struct stat target_stat;
+ const FcChar8 *sysroot;
- dir_base = FcStrPlus (cache_dir, (FcChar8 *) FC_DIR_SEPARATOR_S);
- if (!dir_base)
+ /* FIXME: this API needs to support non-current FcConfig */
+ sysroot = FcConfigGetSysRoot (NULL);
+ if (sysroot)
+ dir = FcStrBuildFilename (sysroot, cache_dir, NULL);
+ else
+ dir = FcStrCopyFilename (cache_dir);
+ if (!dir)
{
fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir);
return FcFalse;
}
- if (access ((char *) cache_dir, W_OK) != 0)
+ if (access ((char *) dir, W_OK) != 0)
{
if (verbose || FcDebug () & FC_DBG_CACHE)
- printf ("%s: not cleaning %s cache directory\n", cache_dir,
- access ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent");
+ printf ("%s: not cleaning %s cache directory\n", dir,
+ access ((char *) dir, F_OK) == 0 ? "unwritable" : "non-existent");
goto bail0;
}
if (verbose || FcDebug () & FC_DBG_CACHE)
- printf ("%s: cleaning cache directory\n", cache_dir);
- d = opendir ((char *) cache_dir);
+ printf ("%s: cleaning cache directory\n", dir);
+ d = opendir ((char *) dir);
if (!d)
{
- perror ((char *) cache_dir);
+ perror ((char *) dir);
ret = FcFalse;
goto bail0;
}
@@ -1030,10 +1058,10 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX))
continue;
- file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name);
+ file_name = FcStrBuildFilename (dir, (FcChar8 *)ent->d_name, NULL);
if (!file_name)
{
- fprintf (stderr, "Fontconfig error: %s: allocation failure\n", cache_dir);
+ fprintf (stderr, "Fontconfig error: %s: allocation failure\n", dir);
ret = FcFalse;
break;
}
@@ -1042,7 +1070,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
if (!cache)
{
if (verbose || FcDebug () & FC_DBG_CACHE)
- printf ("%s: invalid cache file: %s\n", cache_dir, ent->d_name);
+ printf ("%s: invalid cache file: %s\n", dir, ent->d_name);
remove = FcTrue;
}
else
@@ -1052,7 +1080,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
{
if (verbose || FcDebug () & FC_DBG_CACHE)
printf ("%s: %s: missing directory: %s \n",
- cache_dir, ent->d_name, target_dir);
+ dir, ent->d_name, target_dir);
remove = FcTrue;
}
FcDirCacheUnload (cache);
@@ -1070,7 +1098,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose)
closedir (d);
bail0:
- FcStrFree (dir_base);
+ FcStrFree (dir);
return ret;
}
@@ -1394,7 +1422,7 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir)
if (access ((char *) cache_dir, W_OK) == 0)
{
/* Create CACHEDIR.TAG */
- cache_tag = FcStrPlus (cache_dir, (const FcChar8 *) FC_DIR_SEPARATOR_S "CACHEDIR.TAG");
+ cache_tag = FcStrBuildFilename (cache_dir, "CACHEDIR.TAG", NULL);
if (!cache_tag)
return FcFalse;
atomic = FcAtomicCreate ((FcChar8 *)cache_tag);
@@ -1438,8 +1466,9 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir)
void
FcCacheCreateTagFile (const FcConfig *config)
{
- FcChar8 *cache_dir = NULL;
+ FcChar8 *cache_dir = NULL, *d = NULL;
FcStrList *list;
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
list = FcConfigGetCacheDirs (config);
if (!list)
@@ -1447,9 +1476,17 @@ FcCacheCreateTagFile (const FcConfig *config)
while ((cache_dir = FcStrListNext (list)))
{
- if (FcDirCacheCreateTagFile (cache_dir))
+ if (d)
+ FcStrFree (d);
+ if (sysroot)
+ d = FcStrBuildFilename (sysroot, cache_dir, NULL);
+ else
+ d = FcStrCopyFilename (cache_dir);
+ if (FcDirCacheCreateTagFile (d))
break;
}
+ if (d)
+ FcStrFree (d);
FcStrListDone (list);
}
diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c
index db878d5f4..b762376ae 100644
--- a/fontconfig/src/fccfg.c
+++ b/fontconfig/src/fccfg.c
@@ -123,6 +123,8 @@ FcConfigCreate (void)
config->expr_pool = NULL;
+ config->sysRoot = NULL;
+
FcRefInit (&config->ref, 1);
return config;
@@ -292,6 +294,8 @@ FcConfigDestroy (FcConfig *config)
free (page);
page = next;
}
+ if (config->sysRoot)
+ FcStrFree (config->sysRoot);
free (config);
}
@@ -2309,6 +2313,59 @@ FcConfigAcceptFont (FcConfig *config,
return FcFalse;
return FcTrue;
}
+
+const FcChar8 *
+FcConfigGetSysRoot (const FcConfig *config)
+{
+ if (!config)
+ {
+ config = FcConfigGetCurrent ();
+ if (!config)
+ return NULL;
+ }
+
+ return config->sysRoot;
+}
+
+void
+FcConfigSetSysRoot (FcConfig *config,
+ const FcChar8 *sysroot)
+{
+ FcChar8 *s;
+ FcBool init = FcFalse;
+
+ if (!config)
+ {
+ /* We can't use FcConfigGetCurrent() here to ensure
+ * the sysroot is set prior to initialize FcConfig,
+ * to avoid loading caches from non-sysroot dirs.
+ * So postpone the initialization later.
+ */
+ config = fc_atomic_ptr_get (&_fcConfig);
+ if (!config)
+ {
+ config = FcConfigCreate ();
+ if (!config)
+ return;
+ init = FcTrue;
+ }
+ }
+
+ s = FcStrCopyFilename (sysroot);
+ if (!s)
+ return;
+
+ if (config->sysRoot)
+ FcStrFree (config->sysRoot);
+
+ config->sysRoot = s;
+ if (init)
+ {
+ config = FcInitLoadOwnConfigAndFonts (config);
+ FcConfigSetCurrent (config);
+ }
+}
+
#define __fccfg__
#include "fcaliastail.h"
#undef __fccfg__
diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c
index 2360764fc..b8d5d060c 100644
--- a/fontconfig/src/fcinit.c
+++ b/fontconfig/src/fcinit.c
@@ -65,14 +65,16 @@ FcGetVersion (void)
* Load the configuration files
*/
FcConfig *
-FcInitLoadConfig (void)
+FcInitLoadOwnConfig (FcConfig *config)
{
- FcConfig *config;
+ if (!config)
+ {
+ config = FcConfigCreate ();
+ if (!config)
+ return NULL;
+ }
FcInitDebug ();
- config = FcConfigCreate ();
- if (!config)
- return NULL;
if (!FcConfigParseAndLoad (config, 0, FcTrue))
{
@@ -120,15 +122,19 @@ FcInitLoadConfig (void)
return config;
}
+FcConfig *
+FcInitLoadConfig (void)
+{
+ return FcInitLoadOwnConfig (NULL);
+}
+
/*
* Load the configuration files and scan for available fonts
*/
FcConfig *
-FcInitLoadConfigAndFonts (void)
+FcInitLoadOwnConfigAndFonts (FcConfig *config)
{
- FcConfig *config = FcInitLoadConfig ();
-
- FcInitDebug ();
+ config = FcInitLoadOwnConfig (config);
if (!config)
return 0;
if (!FcConfigBuildFonts (config))
@@ -139,6 +145,12 @@ FcInitLoadConfigAndFonts (void)
return config;
}
+FcConfig *
+FcInitLoadConfigAndFonts (void)
+{
+ return FcInitLoadOwnConfigAndFonts (NULL);
+}
+
/*
* Initialize the default library configuration
*/
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index 4eac6105a..d5a7217cc 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -501,7 +501,9 @@ struct _FcConfig {
FcRef ref; /* reference count */
- FcExprPage *expr_pool; /* pool of FcExpr's */
+ FcExprPage *expr_pool; /* pool of FcExpr's */
+
+ FcChar8 *sysRoot; /* override the system root directory */
};
typedef struct _FcFileTime {
@@ -819,6 +821,13 @@ FcHashGetSHA256Digest (const FcChar8 *input_strings,
FcPrivate FcChar8 *
FcHashGetSHA256DigestFromFile (const FcChar8 *filename);
+/* fcinit.c */
+FcPrivate FcConfig *
+FcInitLoadOwnConfig (FcConfig *config);
+
+FcPrivate FcConfig *
+FcInitLoadOwnConfigAndFonts (FcConfig *config);
+
/* fcxml.c */
FcPrivate void
FcTestDestroy (FcTest *test);
@@ -1073,6 +1082,10 @@ FcPrivate FcBool
FcStrUsesHome (const FcChar8 *s);
FcPrivate FcChar8 *
+FcStrBuildFilename (const FcChar8 *path,
+ ...);
+
+FcPrivate FcChar8 *
FcStrLastSlash (const FcChar8 *path);
FcPrivate FcChar32
diff --git a/fontconfig/src/fclang.c b/fontconfig/src/fclang.c
index 8e9b094b2..9f685f6fd 100644
--- a/fontconfig/src/fclang.c
+++ b/fontconfig/src/fclang.c
@@ -1027,9 +1027,11 @@ FcLangSetOperate(const FcLangSet *a,
const FcChar8 *s))
{
FcLangSet *langset = FcLangSetCopy (a);
- FcStrList *sl = FcStrListCreate (FcLangSetGetLangs (b));
+ FcStrSet *set = FcLangSetGetLangs (b);
+ FcStrList *sl = FcStrListCreate (set);
FcChar8 *str;
+ FcStrSetDestroy (set);
while ((str = FcStrListNext (sl)))
{
func (langset, str);
diff --git a/fontconfig/src/fcstr.c b/fontconfig/src/fcstr.c
index 414d6dd6b..4d11a4c65 100644
--- a/fontconfig/src/fcstr.c
+++ b/fontconfig/src/fcstr.c
@@ -30,6 +30,7 @@
#include <regex.h>
#endif
+
/* Objects MT-safe for readonly access. */
FcChar8 *
@@ -864,6 +865,64 @@ FcStrUsesHome (const FcChar8 *s)
}
FcChar8 *
+FcStrBuildFilename (const FcChar8 *path,
+ ...)
+{
+ va_list ap;
+ FcStrSet *sset = FcStrSetCreate ();
+ FcStrList *list;
+ FcChar8 *s, *ret = NULL, *p;
+ size_t len = 0;
+
+ if (!sset || !path)
+ return NULL;
+
+ if (!FcStrSetAdd (sset, path))
+ goto bail0;
+
+ va_start (ap, path);
+ while (1)
+ {
+ s = (FcChar8 *)va_arg (ap, FcChar8 *);
+ if (!s)
+ break;
+ if (!FcStrSetAdd (sset, s))
+ goto bail1;
+ }
+ list = FcStrListCreate (sset);
+ while ((s = FcStrListNext (list)))
+ {
+ len += strlen ((const char *)s) + 1;
+ }
+ list->n = 0;
+ ret = malloc (sizeof (FcChar8) * (len + 1));
+ if (!ret)
+ goto bail2;
+ p = ret;
+ while ((s = FcStrListNext (list)))
+ {
+ if (p != ret)
+ {
+ p[0] = FC_DIR_SEPARATOR;
+ p++;
+ }
+ len = strlen ((const char *)s);
+ memcpy (p, s, len);
+ p += len;
+ }
+ *p = 0;
+
+bail2:
+ FcStrListDone (list);
+bail1:
+ va_end (ap);
+bail0:
+ FcStrSetDestroy (sset);
+
+ return ret;
+}
+
+FcChar8 *
FcStrCopyFilename (const FcChar8 *s)
{
FcChar8 *new;
@@ -1052,8 +1111,7 @@ FcStrCanonFilename (const FcChar8 *s)
FcChar8 cwd[FC_MAX_FILE_LEN + 2];
if (getcwd ((char *) cwd, FC_MAX_FILE_LEN) == NULL)
return NULL;
- strcat ((char *) cwd, "/");
- full = FcStrPlus (cwd, s);
+ full = FcStrBuildFilename (cwd, s, NULL);
file = FcStrCanonAbsoluteFilename (full);
FcStrFree (full);
return file;