[Fontconfig] [RFC/PATCH 2/2] fc-cache: add a --root option

Mike Frysinger vapier at gentoo.org
Mon Nov 7 11:55:16 PST 2011


We have to add a few new helper options for setting/getting the config
root, and then hooking into the low level dir/file scanners to utilize
these new paths.

Signed-off-by: Mike Frysinger <vapier at gentoo.org>
---
 fc-cache/fc-cache.c     |   25 ++++++++++++++++++++-----
 fc-cache/fc-cache.sgml  |   11 ++++++++++-
 fontconfig/fontconfig.h |    9 +++++++++
 src/fccache.c           |   31 ++++++++++++++++++++++++++++---
 src/fccfg.c             |   23 +++++++++++++++++++++++
 src/fcdir.c             |   22 +++++++++++++++++++---
 src/fcxml.c             |   20 ++++++++++++++++++--
 7 files changed, 127 insertions(+), 14 deletions(-)

diff --git a/fc-cache/fc-cache.c b/fc-cache/fc-cache.c
index d265350..aedf4a1 100644
--- a/fc-cache/fc-cache.c
+++ b/fc-cache/fc-cache.c
@@ -69,6 +69,7 @@
 const struct option longopts[] = {
     {"force", 0, 0, 'f'},
     {"really-force", 0, 0, 'r'},
+    {"root", 1, 0, 'R'},
     {"system-only", 0, 0, 's'},
     {"version", 0, 0, 'V'},
     {"verbose", 0, 0, 'v'},
@@ -87,10 +88,10 @@ usage (char *program, int error)
 {
     FILE *file = error ? stderr : stdout;
 #if HAVE_GETOPT_LONG
-    fprintf (file, "usage: %s [-frsvVh] [--force|--really-force] [--system-only] [--verbose] [--version] [--help] [dirs]\n",
+    fprintf (file, "usage: %s [-frRsvVh] [--force|--really-force] [--root <root>] [--system-only] [--verbose] [--version] [--help] [dirs]\n",
 	     program);
 #else
-    fprintf (file, "usage: %s [-frsvVh] [dirs]\n",
+    fprintf (file, "usage: %s [-frRsvVh] [dirs]\n",
 	     program);
 #endif
     fprintf (file, "Build font information caches in [dirs]\n"
@@ -99,6 +100,7 @@ usage (char *program, int error)
 #if HAVE_GETOPT_LONG
     fprintf (file, "  -f, --force          scan directories with apparently valid caches\n");
     fprintf (file, "  -r, --really-force   erase all existing caches, then rescan\n");
+    fprintf (file, "  -R, --root <root>    change to <root> before loading files\n");
     fprintf (file, "  -s, --system-only    scan system-wide directories only\n");
     fprintf (file, "  -v, --verbose        display status information while busy\n");
     fprintf (file, "  -V, --version        display font config version and exit\n");
@@ -106,6 +108,7 @@ usage (char *program, int error)
 #else
     fprintf (file, "  -f         (force)   scan directories with apparently valid caches\n");
     fprintf (file, "  -r,   (really force) erase all existing caches, then rescan\n");
+    fprintf (file, "  -R <root>  (root)    change to <root> before loading files\n");
     fprintf (file, "  -s         (system)  scan system-wide directories only\n");
     fprintf (file, "  -v         (verbose) display status information while busy\n");
     fprintf (file, "  -V         (version) display font config version and exit\n");
@@ -254,6 +257,7 @@ cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose)
     DIR		*d;
     struct dirent *ent;
     FcChar8	*dir_base;
+    FcChar8	*fullDir;
     FcBool	ret = FcTrue;
     FcBool	remove;
     FcCache	*cache;
@@ -275,7 +279,14 @@ cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose)
     }
     if (verbose)
 	printf ("%s: cleaning cache directory\n", dir);
-    d = opendir ((char *) dir);
+    fullDir = FcConfigGetRootPlus (dir);
+    if (fullDir)
+    {
+	d = opendir ((char *) fullDir);
+	FcStrFree (fullDir);
+    }
+    else
+	d = opendir ((char *) dir);
     if (!d)
     {
 	perror ((char *) dir);
@@ -369,6 +380,7 @@ main (int argc, char **argv)
     FcBool	really_force = FcFalse;
     FcBool	systemOnly = FcFalse;
     FcConfig	*config;
+    const char	*rootDir;
     int		i;
     int		changed;
     int		ret;
@@ -376,9 +388,9 @@ main (int argc, char **argv)
     int		c;
 
 #if HAVE_GETOPT_LONG
-    while ((c = getopt_long (argc, argv, "frsVvh", longopts, NULL)) != -1)
+    while ((c = getopt_long (argc, argv, "frR:sVvh", longopts, NULL)) != -1)
 #else
-    while ((c = getopt (argc, argv, "frsVvh")) != -1)
+    while ((c = getopt (argc, argv, "frR:sVvh")) != -1)
 #endif
     {
 	switch (c) {
@@ -388,6 +400,9 @@ main (int argc, char **argv)
 	case 'f':
 	    force = FcTrue;
 	    break;
+	case 'R':
+	    FcConfigSetRoot (optarg);
+	    break;
 	case 's':
 	    systemOnly = FcTrue;
 	    break;
diff --git a/fc-cache/fc-cache.sgml b/fc-cache/fc-cache.sgml
index 3740be7..f5215df 100644
--- a/fc-cache/fc-cache.sgml
+++ b/fc-cache/fc-cache.sgml
@@ -63,9 +63,10 @@ manpage.1: manpage.sgml
     <cmdsynopsis>
       <command>&dhpackage;</command>
 
-      <arg><option>-frsvVh</option></arg>
+      <arg><option>-frRsvVh</option></arg>
       <arg><option>--force</option></arg>
       <arg><option>--really-force</option></arg>
+      <arg><option>--root</option></arg>
       <arg><option>--system-only</option></arg>
       <arg><option>--verbose</option></arg>
       <arg><option>--version</option></arg>
@@ -120,6 +121,14 @@ manpage.1: manpage.sgml
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term><option>-R</option>
+          <option>--root</option>
+        </term>
+        <listitem>
+          <para>Change to root before loading files.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
         <term><option>-s</option>
           <option>--system-only</option>
         </term>
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 465ffa1..3204e2f 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -409,6 +409,15 @@ FcConfigSubstitute (FcConfig	*config,
 		    FcPattern	*p,
 		    FcMatchKind	kind);
 
+void
+FcConfigSetRoot (const char	*path);
+
+const FcChar8 *
+FcConfigGetRoot (void);
+
+FcChar8 *
+FcConfigGetRootPlus (const FcChar8	*path);
+
 /* fccharset.c */
 FcPublic FcCharSet*
 FcCharSetCreate (void);
diff --git a/src/fccache.c b/src/fccache.c
index 2d4a437..169cc48 100644
--- a/src/fccache.c
+++ b/src/fccache.c
@@ -207,12 +207,20 @@ static int
 FcDirCacheOpenFile (const FcChar8 *cache_file, struct stat *file_stat)
 {
     int	fd;
+    FcChar8 *fullFile;
 
 #ifdef _WIN32
     if (FcStat (cache_file, file_stat) < 0)
         return -1;
 #endif
-    fd = open((char *) cache_file, O_RDONLY | O_BINARY);
+    fullFile = FcConfigGetRootPlus (cache_file);
+    if (fullFile)
+    {
+	fd = open ((char *) fullFile, O_RDONLY | O_BINARY);
+	FcStrFree (fullFile);
+    }
+    else
+	fd = open ((char *) cache_file, O_RDONLY | O_BINARY);
     if (fd < 0)
 	return fd;
 #ifndef _WIN32
@@ -856,6 +864,8 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     FcStrList	    *list;
     FcChar8	    *cache_dir = NULL;
     FcChar8	    *test_dir;
+    FcChar8	    *full_test_dir;
+    FcBool	    free_test_dir;
     FcCacheSkip     *skip;
     struct stat     cache_stat;
     int		    magic;
@@ -868,7 +878,19 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     list = FcStrListCreate (config->cacheDirs);
     if (!list)
 	return FcFalse;
+    free_test_dir = FcFalse;
     while ((test_dir = FcStrListNext (list))) {
+	if (free_test_dir)
+	    FcStrFree (full_test_dir);
+	free_test_dir = FcFalse;
+
+	full_test_dir = FcConfigGetRootPlus (test_dir);
+	if (full_test_dir)
+	{
+	    free_test_dir = FcTrue;
+	    test_dir = full_test_dir;
+	}
+
 	if (access ((char *) test_dir, W_OK|X_OK) == 0)
 	{
 	    cache_dir = test_dir;
@@ -898,12 +920,12 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     }
     FcStrListDone (list);
     if (!cache_dir)
-	return FcFalse;
+	goto bail0;
 
     FcDirCacheBasename (dir, cache_base);
     cache_hashed = FcStrPlus (cache_dir, cache_base);
     if (!cache_hashed)
-        return FcFalse;
+        goto bail0;
 
     if (FcDebug () & FC_DBG_CACHE)
         printf ("FcDirCacheWriteDir dir \"%s\" file \"%s\"\n",
@@ -970,6 +992,9 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config)
     FcAtomicDestroy (atomic);
  bail1:
     FcStrFree (cache_hashed);
+ bail0:
+    if (free_test_dir)
+	FcStrFree (full_test_dir);
     return FcFalse;
 }
 
diff --git a/src/fccfg.c b/src/fccfg.c
index 09c5991..226d198 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -2103,6 +2103,29 @@ FcConfigAcceptFont (FcConfig	    *config,
 	return FcFalse;
     return FcTrue;
 }
+
+static const FcChar8 *_fcRoot;
+
+void
+FcConfigSetRoot (const char *path)
+{
+    _fcRoot = strdup (path);
+}
+
+const FcChar8 *
+FcConfigGetRoot (void)
+{
+    return _fcRoot;
+}
+
+FcChar8 *
+FcConfigGetRootPlus (const FcChar8 *path)
+{
+    if (!_fcRoot)
+	return NULL;
+    return FcStrPlusPlus (_fcRoot, "/", path, NULL);
+}
+
 #define __fccfg__
 #include "fcaliastail.h"
 #undef __fccfg__
diff --git a/src/fcdir.c b/src/fcdir.c
index 8a2b976..fd3cc47 100644
--- a/src/fcdir.c
+++ b/src/fcdir.c
@@ -43,6 +43,7 @@ FcFileScanFontConfig (FcFontSet		*set,
 {
     FcPattern	*font;
     FcBool	ret = FcTrue;
+    FcChar8	*fullFile;
     int		id;
     int		count = 0;
 
@@ -58,7 +59,14 @@ FcFileScanFontConfig (FcFontSet		*set,
 	    printf ("\tScanning file %s...", file);
 	    fflush (stdout);
 	}
-	font = FcFreeTypeQuery (file, id, blanks, &count);
+	fullFile = FcConfigGetRootPlus (file);
+	if (fullFile)
+	{
+	    font = FcFreeTypeQuery (fullFile, id, blanks, &count);
+	    FcStrFree (fullFile);
+	}
+	else
+	    font = FcFreeTypeQuery (file, id, blanks, &count);
 	if (FcDebug () & FC_DBG_SCAN)
 	    printf ("done\n");
 
@@ -142,6 +150,7 @@ FcDirScanConfig (FcFontSet	*set,
     FcStrSet		*files;
     FcChar8		*file;
     FcChar8		*base;
+    FcChar8		*fullDir;
     FcBool		ret = FcTrue;
     int			i;
 
@@ -167,8 +176,15 @@ FcDirScanConfig (FcFontSet	*set,
 
     if (FcDebug () & FC_DBG_SCAN)
 	printf ("\tScanning dir %s\n", dir);
-	
-    d = opendir ((char *) dir);
+
+    fullDir = FcConfigGetRootPlus (dir);
+    if (fullDir)
+    {
+	d = opendir ((char *) fullDir);
+	FcStrFree (fullDir);
+    }
+    else
+	d = opendir ((char *) dir);
     if (!d)
     {
 	/* Don't complain about missing directories */
diff --git a/src/fcxml.c b/src/fcxml.c
index ff30b7b..b3251f5 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -2603,11 +2603,19 @@ FcConfigParseAndLoadDir (FcConfig	*config,
     DIR		    *d;
     struct dirent   *e;
     FcBool	    ret = FcTrue;
+    FcChar8	    *fullDir;
     FcChar8	    *file;
     FcChar8	    *base;
     FcStrSet	    *files;
 
-    d = opendir ((char *) dir);
+    fullDir = FcConfigGetRootPlus (dir);
+    if (fullDir)
+    {
+	d = opendir ((char *) fullDir);
+	FcStrFree (fullDir);
+    }
+    else
+	d = opendir ((char *) dir);
     if (!d)
     {
 	if (complain)
@@ -2685,6 +2693,7 @@ FcConfigParseAndLoad (FcConfig	    *config,
 
     XML_Parser	    p;
     FcChar8	    *filename;
+    FcChar8	    *fullFile;
     int		    fd;
     int		    len;
     FcConfigParse   parse;
@@ -2723,7 +2732,14 @@ FcConfigParseAndLoad (FcConfig	    *config,
     if (FcDebug () & FC_DBG_CONFIG)
 	printf ("\tLoading config file %s\n", filename);
 
-    fd = open ((char *) filename, O_RDONLY);
+    fullFile = FcConfigGetRootPlus (filename);
+    if (fullFile)
+    {
+	fd = open ((char *) fullFile, O_RDONLY);
+	FcStrFree (fullFile);
+    }
+    else
+	fd = open ((char *) filename, O_RDONLY);
     if (fd == -1) {
 	FcStrFree (filename);
 	goto bail0;
-- 
1.7.6.1



More information about the Fontconfig mailing list