{
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)
if (!d)
{
perror ((char *) dir);
- FcStrFree (dir_base);
return FcFalse;
}
while ((ent = readdir (d)))
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);
}
closedir (d);
- FcStrFree (dir_base);
return ret;
}
FcPublic FcChar8 *
FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic FcChar8 *
+FcStrPathPlus (const FcChar8 *s1, ...);
FcPublic void
FcStrFree (FcChar8 *s);
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;
#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
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)
{