From 76f88e780ae29cab1452dd397eec4f9501d385ab Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Tue, 15 Sep 2020 18:15:37 +0900 Subject: [PATCH] fc-scan: add --sysroot option and fix scanning to get things work with sysroot Fixes https://gitlab.freedesktop.org/fontconfig/fontconfig/-/issues/225 --- fc-scan/fc-scan.c | 29 ++++++++++++++++++++--------- src/Makefile.am | 1 + src/fccfg.c | 8 ++++++++ src/fcdir.c | 41 +++++++++++++++++++++++++++-------------- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/fc-scan/fc-scan.c b/fc-scan/fc-scan.c index 02831e0..dca1cd5 100644 --- a/fc-scan/fc-scan.c +++ b/fc-scan/fc-scan.c @@ -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,22 +83,24 @@ 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")); fprintf (file, "\n"); #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, _(" -V, --version display font config version and exit\n")); - fprintf (file, _(" -h, --help display this help and exit\n")); + 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++) diff --git a/src/Makefile.am b/src/Makefile.am index 89330c0..4ddcb1a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -79,6 +79,7 @@ AM_CPPFLAGS = \ $(EXPAT_CFLAGS) \ $(WARN_CFLAGS) \ -DFC_CACHEDIR='"$(FC_CACHEDIR)"' \ + -DCONFIGDIR='"$(CONFIGDIR)"' \ -DFONTCONFIG_PATH='"$(BASECONFIGDIR)"' \ -DFC_TEMPLATEDIR='"$(TEMPLATEDIR)"' LDADD = $(LIBINTL) diff --git a/src/fccfg.c b/src/fccfg.c index 9e747cb..1c62cad 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -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; } diff --git a/src/fcdir.c b/src/fcdir.c index 0f60f87..e332897 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -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