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

View File

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

View File

@ -2627,6 +2627,14 @@ FcConfigGetFilename (FcConfig *config,
if (FcStrIsAbsoluteFilename(url)) 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); file = FcConfigFileExists (sysroot, url);
goto bail; goto bail;
} }

View File

@ -201,8 +201,9 @@ FcDirScanConfig (FcFontSet *set,
DIR *d; DIR *d;
struct dirent *e; struct dirent *e;
FcStrSet *files; FcStrSet *files;
FcChar8 *file; FcChar8 *file_prefix, *s_dir = NULL;
FcChar8 *base; FcChar8 *base;
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
FcBool ret = FcTrue; FcBool ret = FcTrue;
int i; int i;
@ -213,20 +214,28 @@ FcDirScanConfig (FcFontSet *set,
return FcTrue; return FcTrue;
/* freed below */ /* freed below */
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1); file_prefix = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
if (!file) { 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; ret = FcFalse;
goto bail; goto bail;
} }
strcpy ((char *) file, (char *) dir);
strcat ((char *) file, "/");
base = file + strlen ((char *) file);
if (FcDebug () & FC_DBG_SCAN) 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) if (!d)
{ {
/* Don't complain about missing directories */ /* 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) if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
{ {
strcpy ((char *) base, (char *) e->d_name); strcpy ((char *) base, (char *) e->d_name);
if (!FcStrSetAdd (files, file)) { if (!FcStrSetAdd (files, file_prefix)) {
ret = FcFalse; ret = FcFalse;
goto bail2; goto bail2;
} }
@ -269,8 +278,10 @@ bail2:
bail1: bail1:
closedir (d); closedir (d);
bail: bail:
if (file) if (s_dir)
free (file); free (s_dir);
if (file_prefix)
free (file_prefix);
return ret; return ret;
} }
@ -339,7 +350,8 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
/* /*
* Scan the dir * 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; goto bail2;
/* /*
@ -404,7 +416,8 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
/* /*
* Scan the dir * 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; goto bail1;
/* /*
* Rebuild the cache object * Rebuild the cache object