[Fontconfig] [PATCH 1/3] FcStrPathPlus: new helper function

Mike Frysinger vapier at gentoo.org
Mon Nov 7 21:24:59 PST 2011


This is like FcStrPlus, except that it takes an arbitrary number of
additional strings to append, and it handles the path separator.

Signed-off-by: Mike Frysinger <vapier at gentoo.org>
---
 fc-cache/fc-cache.c     |   12 +----------
 fontconfig/fontconfig.h |    3 ++
 src/fccfg.c             |   31 +--------------------------
 src/fcint.h             |    2 +
 src/fcstr.c             |   51 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 59 insertions(+), 40 deletions(-)

diff --git a/fc-cache/fc-cache.c b/fc-cache/fc-cache.c
index d265350..98039f7 100644
--- a/fc-cache/fc-cache.c
+++ b/fc-cache/fc-cache.c
@@ -253,24 +253,16 @@ cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose)
 {
     DIR		*d;
     struct dirent *ent;
-    FcChar8	*dir_base;
     FcBool	ret = FcTrue;
     FcBool	remove;
     FcCache	*cache;
     struct stat	target_stat;
 
-    dir_base = FcStrPlus (dir, (FcChar8 *) "/");
-    if (!dir_base)
-    {
-	fprintf (stderr, "%s: out of memory\n", dir);
-	return FcFalse;
-    }
     if (access ((char *) dir, W_OK) != 0)
     {
 	if (verbose)
 	    printf ("%s: not cleaning %s cache directory\n", dir,
 		    access ((char *) dir, F_OK) == 0 ? "unwritable" : "non-existent");
-	FcStrFree (dir_base);
 	return FcTrue;
     }
     if (verbose)
@@ -279,7 +271,6 @@ cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose)
     if (!d)
     {
 	perror ((char *) dir);
-	FcStrFree (dir_base);
 	return FcFalse;
     }
     while ((ent = readdir (d)))
@@ -295,7 +286,7 @@ cleanCacheDirectory (FcConfig *config, FcChar8 *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 = FcStrPathPlus (dir, (const FcChar8 *) ent->d_name, NULL);
 	if (!file_name)
 	{
 	    fprintf (stderr, "%s: allocation failure\n", dir);
@@ -334,7 +325,6 @@ cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose)
     }
     
     closedir (d);
-    FcStrFree (dir_base);
     return ret;
 }
 
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 23ea222..254acc3 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -860,6 +860,9 @@ FcStrCopyFilename (const FcChar8 *s);
     
 FcPublic FcChar8 *
 FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic FcChar8 *
+FcStrPathPlus (const FcChar8 *s1, ...);
     
 FcPublic void
 FcStrFree (FcChar8 *s);
diff --git a/src/fccfg.c b/src/fccfg.c
index 09c5991..6d55f17 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -1689,38 +1689,11 @@ static FcChar8 *
 FcConfigFileExists (const FcChar8 *dir, const FcChar8 *file)
 {
     FcChar8    *path;
-    int         size;
 
     if (!dir)
-	dir = (FcChar8 *) "";
+	dir = (const FcChar8 *) "";
 
-    size = strlen ((char *) dir) + 1 + strlen ((char *) file) + 1;
-    /*
-     * workaround valgrind warning because glibc takes advantage of how it knows memory is
-     * allocated to implement strlen by reading in groups of 4
-     */
-    size = (size + 3) & ~3;
-
-    path = malloc (size);
-    if (!path)
-	return 0;
-
-    strcpy ((char *) path, (const char *) dir);
-    /* make sure there's a single separator */
-#ifdef _WIN32
-    if ((!path[0] || (path[strlen((char *) path)-1] != '/' &&
-		      path[strlen((char *) path)-1] != '\\')) &&
-	!(file[0] == '/' ||
-	  file[0] == '\\' ||
-	  (isalpha (file[0]) && file[1] == ':' && (file[2] == '/' || file[2] == '\\'))))
-	strcat ((char *) path, "\\");
-#else
-    if ((!path[0] || path[strlen((char *) path)-1] != '/') && file[0] != '/')
-	strcat ((char *) path, "/");
-#endif
-    strcat ((char *) path, (char *) file);
-
-    FcMemAlloc (FC_MEM_STRING, size);
+    path = FcStrPathPlus (dir, file, NULL);
     if (access ((char *) path, R_OK) == 0)
 	return path;
 
diff --git a/src/fcint.h b/src/fcint.h
index 8179195..0a1a90e 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -56,8 +56,10 @@
 
 #ifdef _WIN32
 #define FC_SEARCH_PATH_SEPARATOR ';'
+#define FC_DIR_SEPARATOR '\\'
 #else
 #define FC_SEARCH_PATH_SEPARATOR ':'
+#define FC_DIR_SEPARATOR '/'
 #endif
 
 #define FC_DBG_MATCH	1
diff --git a/src/fcstr.c b/src/fcstr.c
index b712e5d..0510c21 100644
--- a/src/fcstr.c
+++ b/src/fcstr.c
@@ -63,6 +63,57 @@ FcStrPlus (const FcChar8 *s1, const FcChar8 *s2)
     return s;
 }
 
+FcChar8 *
+FcStrPathPlus (const FcChar8 *s1, ...)
+{
+    va_list ap;
+    const FcChar8 *arg;
+    FcChar8 *s;
+    FcBool addSep;
+    int l;
+    int al;
+
+    va_start (ap, s1);
+    arg = s1;
+    s = NULL;
+    l = 0;
+    do {
+	if (!arg)
+	    break;
+	al = strlen ((char *) arg);
+
+	/* make sure there's a single separator */
+	addSep = FcFalse;
+#ifdef _WIN32
+	if ((!arg[0] || (arg[al - 1] != '/' && arg[al - 1] != '\\')) &&
+	    !(file[0] == '/' ||
+	  file[0] == '\\' ||
+	  (isalpha (file[0]) && file[1] == ':' && (file[2] == '/' || file[2] == '\\'))))
+	addSep = FcTrue;
+#else
+	if (s && (s[l] != FC_DIR_SEPARATOR && arg[0] != FC_DIR_SEPARATOR))
+	    addSep = FcTrue;
+#endif
+
+	if (addSep)
+	    l += 1;
+	s = realloc (s, l + al + 1);
+	if (!s)
+	    return 0;
+	if (addSep)
+	    s[l - 1] = FC_DIR_SEPARATOR;
+	memcpy (s + l, arg, al + 1);
+	l += al;
+
+	arg = va_arg (ap, const FcChar8 *);
+    } while (1);
+    va_end (ap);
+
+    if (l)
+	FcMemAlloc (FC_MEM_STRING, l + 1);
+    return s;
+}
+
 void
 FcStrFree (FcChar8 *s)
 {
-- 
1.7.6.1



More information about the Fontconfig mailing list