fc-scan: add --sysroot option

and fix scanning to get things work with sysroot

Fixes https://gitlab.freedesktop.org/fontconfig/fontconfig/-/issues/225
This commit is contained in:
Akira TAGOH 2020-09-15 18:15:37 +09:00
parent 9d419e22d6
commit 76f88e780a
4 changed files with 56 additions and 23 deletions

View File

@ -66,6 +66,7 @@
static const struct option longopts[] = {
{"brief", 0, 0, 'b'},
{"format", 1, 0, 'f'},
{"sysroot", required_argument, 0, 'y'},
{"version", 0, 0, 'V'},
{"help", 0, 0, 'h'},
{NULL,0,0,0},
@ -82,10 +83,10 @@ usage (char *program, int error)
{
FILE *file = error ? stderr : stdout;
#if HAVE_GETOPT_LONG
fprintf (file, _("usage: %s [-bVh] [-f FORMAT] [--brief] [--format FORMAT] [--version] [--help] font-file...\n"),
fprintf (file, _("usage: %s [-bcVh] [-f FORMAT] [-y SYSROOT] [--brief] [--format FORMAT] [--version] [--help] font-file...\n"),
program);
#else
fprintf (file, _("usage: %s [-bVh] [-f FORMAT] font-file...\n"),
fprintf (file, _("usage: %s [-bcVh] [-f FORMAT] [-y SYSROOT] font-file...\n"),
program);
#endif
fprintf (file, _("Scan font files and directories, and print resulting pattern(s)\n"));
@ -93,11 +94,13 @@ usage (char *program, int error)
#if HAVE_GETOPT_LONG
fprintf (file, _(" -b, --brief display font pattern briefly\n"));
fprintf (file, _(" -f, --format=FORMAT use the given output format\n"));
fprintf (file, _(" -y, --sysroot=SYSROOT prepend SYSROOT to all paths for scanning\n"));
fprintf (file, _(" -V, --version display font config version and exit\n"));
fprintf (file, _(" -h, --help display this help and exit\n"));
#else
fprintf (file, _(" -b (brief) display font pattern briefly\n"));
fprintf (file, _(" -f FORMAT (format) use the given output format\n"));
fprintf (file, _(" -y SYSROOT (sysroot) prepend SYSROOT to all paths for scanning\n"));
fprintf (file, _(" -V (version) display font config version and exit\n"));
fprintf (file, _(" -h (help) display this help and exit\n"));
#endif
@ -108,7 +111,7 @@ int
main (int argc, char **argv)
{
int brief = 0;
FcChar8 *format = NULL;
FcChar8 *format = NULL, *sysroot = NULL;
int i;
FcFontSet *fs;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
@ -116,9 +119,9 @@ main (int argc, char **argv)
setlocale (LC_ALL, "");
#if HAVE_GETOPT_LONG
while ((c = getopt_long (argc, argv, "bf:Vh", longopts, NULL)) != -1)
while ((c = getopt_long (argc, argv, "bf:y:Vh", longopts, NULL)) != -1)
#else
while ((c = getopt (argc, argv, "bf:Vh")) != -1)
while ((c = getopt (argc, argv, "bf:y:Vh")) != -1)
#endif
{
switch (c) {
@ -128,6 +131,9 @@ main (int argc, char **argv)
case 'f':
format = (FcChar8 *) strdup (optarg);
break;
case 'y':
sysroot = FcStrCopy ((const FcChar8 *) optarg);
break;
case 'V':
fprintf (stderr, "fontconfig version %d.%d.%d\n",
FC_MAJOR, FC_MINOR, FC_REVISION);
@ -146,6 +152,11 @@ main (int argc, char **argv)
if (i == argc)
usage (argv[0], 1);
if (sysroot)
{
FcConfigSetSysRoot (NULL, sysroot);
FcStrFree (sysroot);
}
fs = FcFontSetCreate ();
for (; i < argc; i++)

View File

@ -79,6 +79,7 @@ AM_CPPFLAGS = \
$(EXPAT_CFLAGS) \
$(WARN_CFLAGS) \
-DFC_CACHEDIR='"$(FC_CACHEDIR)"' \
-DCONFIGDIR='"$(CONFIGDIR)"' \
-DFONTCONFIG_PATH='"$(BASECONFIGDIR)"' \
-DFC_TEMPLATEDIR='"$(TEMPLATEDIR)"'
LDADD = $(LIBINTL)

View File

@ -2627,6 +2627,14 @@ FcConfigGetFilename (FcConfig *config,
if (FcStrIsAbsoluteFilename(url))
{
if (sysroot)
{
size_t len = strlen ((const char *) sysroot);
/* Workaround to avoid adding sysroot repeatedly */
if (strncmp ((const char *) url, (const char *) sysroot, len) == 0)
sysroot = NULL;
}
file = FcConfigFileExists (sysroot, url);
goto bail;
}

View File

@ -201,8 +201,9 @@ FcDirScanConfig (FcFontSet *set,
DIR *d;
struct dirent *e;
FcStrSet *files;
FcChar8 *file;
FcChar8 *file_prefix, *s_dir = NULL;
FcChar8 *base;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcBool ret = FcTrue;
int i;
@ -213,20 +214,28 @@ FcDirScanConfig (FcFontSet *set,
return FcTrue;
/* freed below */
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
if (!file) {
file_prefix = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
if (!file_prefix) {
ret = FcFalse;
goto bail;
}
strcpy ((char *) file_prefix, (char *) dir);
strcat ((char *) file_prefix, FC_DIR_SEPARATOR_S);
base = file_prefix + strlen ((char *) file_prefix);
if (sysroot)
s_dir = FcStrBuildFilename (sysroot, dir, NULL);
else
s_dir = FcStrdup (dir);
if (!s_dir) {
ret = FcFalse;
goto bail;
}
strcpy ((char *) file, (char *) dir);
strcat ((char *) file, "/");
base = file + strlen ((char *) file);
if (FcDebug () & FC_DBG_SCAN)
printf ("\tScanning dir %s\n", dir);
printf ("\tScanning dir %s\n", s_dir);
d = opendir ((char *) dir);
d = opendir ((char *) s_dir);
if (!d)
{
/* Don't complain about missing directories */
@ -246,7 +255,7 @@ FcDirScanConfig (FcFontSet *set,
if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
{
strcpy ((char *) base, (char *) e->d_name);
if (!FcStrSetAdd (files, file)) {
if (!FcStrSetAdd (files, file_prefix)) {
ret = FcFalse;
goto bail2;
}
@ -269,8 +278,10 @@ bail2:
bail1:
closedir (d);
bail:
if (file)
free (file);
if (s_dir)
free (s_dir);
if (file_prefix)
free (file_prefix);
return ret;
}
@ -339,7 +350,8 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
/*
* Scan the dir
*/
if (!FcDirScanConfig (set, dirs, d, FcTrue, config))
/* Do not pass sysroot here. FcDirScanConfig() do take care of it */
if (!FcDirScanConfig (set, dirs, dir, FcTrue, config))
goto bail2;
/*
@ -404,7 +416,8 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
/*
* Scan the dir
*/
if (!FcDirScanConfig (NULL, dirs, d, FcTrue, config))
/* Do not pass sysroot here. FcDirScanConfig() do take care of it */
if (!FcDirScanConfig (NULL, dirs, dir, FcTrue, config))
goto bail1;
/*
* Rebuild the cache object