test-bz106632.c revision a32e9e42
1/* 2 * fontconfig/test/test-bz89617.c 3 * 4 * Copyright © 2000 Keith Packard 5 * Copyright © 2018 Akira TAGOH 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and its 8 * documentation for any purpose is hereby granted without fee, provided that 9 * the above copyright notice appear in all copies and that both that 10 * copyright notice and this permission notice appear in supporting 11 * documentation, and that the name of the author(s) not be used in 12 * advertising or publicity pertaining to distribution of the software without 13 * specific, written prior permission. The authors make no 14 * representations about the suitability of this software for any purpose. It 15 * is provided "as is" without express or implied warranty. 16 * 17 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23 * PERFORMANCE OF THIS SOFTWARE. 24 */ 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28#include <stdlib.h> 29#include <dirent.h> 30#ifndef HAVE_STRUCT_DIRENT_D_TYPE 31#include <sys/types.h> 32#include <sys/stat.h> 33#include <unistd.h> 34#endif 35#include "fcstr.c" 36#undef FcConfigBuildFonts 37#undef FcConfigCreate 38#undef FcConfigGetCurrent 39#undef FcConfigParseAndLoadFromMemory 40#undef FcConfigUptoDate 41#undef FcFontList 42#undef FcInitReinitialize 43#undef FcPatternCreate 44#undef FcPatternDestroy 45#include <fontconfig/fontconfig.h> 46 47#ifdef HAVE_MKDTEMP 48#define fc_mkdtemp mkdtemp 49#else 50char * 51fc_mkdtemp (char *template) 52{ 53 if (!mktemp (template) || mkdir (template, 0700)) 54 return NULL; 55 56 return template; 57} 58#endif 59 60FcBool 61mkdir_p (const char *dir) 62{ 63 char *parent; 64 FcBool ret; 65 66 if (strlen (dir) == 0) 67 return FcFalse; 68 parent = (char *) FcStrDirname ((const FcChar8 *) dir); 69 if (!parent) 70 return FcFalse; 71 if (access (parent, F_OK) == 0) 72 ret = mkdir (dir, 0755) == 0 && chmod (dir, 0755) == 0; 73 else if (access (parent, F_OK) == -1) 74 ret = mkdir_p (parent) && (mkdir (dir, 0755) == 0) && chmod (dir, 0755) == 0; 75 else 76 ret = FcFalse; 77 free (parent); 78 79 return ret; 80} 81 82FcBool 83unlink_dirs (const char *dir) 84{ 85 DIR *d = opendir (dir); 86 struct dirent *e; 87 size_t len = strlen (dir); 88 char *n = NULL; 89 FcBool ret = FcTrue; 90#ifndef HAVE_STRUCT_DIRENT_D_TYPE 91 struct stat statb; 92#endif 93 94 if (!d) 95 return FcFalse; 96 while ((e = readdir (d)) != NULL) 97 { 98 size_t l; 99 100 if (strcmp (e->d_name, ".") == 0 || 101 strcmp (e->d_name, "..") == 0) 102 continue; 103 l = strlen (e->d_name) + 1; 104 if (n) 105 free (n); 106 n = malloc (l + len + 1); 107 if (!n) 108 { 109 ret = FcFalse; 110 break; 111 } 112 strcpy (n, dir); 113 n[len] = FC_DIR_SEPARATOR; 114 strcpy (&n[len + 1], e->d_name); 115#ifdef HAVE_STRUCT_DIRENT_D_TYPE 116 if (e->d_type == DT_DIR) 117#else 118 if (stat (n, &statb) == -1) 119 { 120 fprintf (stderr, "E: %s\n", n); 121 ret = FcFalse; 122 break; 123 } 124 if (S_ISDIR (statb.st_mode)) 125#endif 126 { 127 if (!unlink_dirs (n)) 128 { 129 fprintf (stderr, "E: %s\n", n); 130 ret = FcFalse; 131 break; 132 } 133 } 134 else 135 { 136 if (unlink (n) == -1) 137 { 138 fprintf (stderr, "E: %s\n", n); 139 ret = FcFalse; 140 break; 141 } 142 } 143 } 144 if (n) 145 free (n); 146 closedir (d); 147 148 if (rmdir (dir) == -1) 149 { 150 fprintf (stderr, "E: %s\n", dir); 151 return FcFalse; 152 } 153 154 return ret; 155} 156 157FcChar8 * 158FcLangNormalize (const FcChar8 *lang) 159{ 160 return NULL; 161} 162 163FcChar8 * 164FcConfigHome (void) 165{ 166 return NULL; 167} 168 169int 170main (void) 171{ 172 FcChar8 *fontdir = NULL, *cachedir = NULL, *fontname; 173 char *basedir, template[512] = "/tmp/bz106632-XXXXXX"; 174 char cmd[512]; 175 FcConfig *config; 176 const FcChar8 *tconf = "<fontconfig>\n" 177 " <dir>%s</dir>\n" 178 " <cachedir>%s</cachedir>\n" 179 "</fontconfig>\n"; 180 char conf[1024]; 181 int ret = 0; 182 FcFontSet *fs; 183 FcPattern *pat; 184 185 fprintf (stderr, "D: Creating tmp dir\n"); 186 basedir = fc_mkdtemp (template); 187 if (!basedir) 188 { 189 fprintf (stderr, "%s: %s\n", template, strerror (errno)); 190 goto bail; 191 } 192 fontdir = FcStrBuildFilename (basedir, "fonts", NULL); 193 cachedir = FcStrBuildFilename (basedir, "cache", NULL); 194 fprintf (stderr, "D: Creating %s\n", fontdir); 195 mkdir_p (fontdir); 196 fprintf (stderr, "D: Creating %s\n", cachedir); 197 mkdir_p (cachedir); 198 199 fprintf (stderr, "D: Copying %s to %s\n", FONTFILE, fontdir); 200 snprintf (cmd, 512, "cp -a %s %s", FONTFILE, fontdir); 201 system (cmd); 202 203 fprintf (stderr, "D: Loading a config\n"); 204 snprintf (conf, 1024, tconf, fontdir, cachedir); 205 config = FcConfigCreate (); 206 if (!FcConfigParseAndLoadFromMemory (config, conf, FcTrue)) 207 { 208 printf ("E: Unable to load config\n"); 209 ret = 1; 210 goto bail; 211 } 212 if (!FcConfigBuildFonts (config)) 213 { 214 printf ("E: unable to build fonts\n"); 215 ret = 1; 216 goto bail; 217 } 218 fprintf (stderr, "D: Obtaining fonts information\n"); 219 pat = FcPatternCreate (); 220 fs = FcFontList (config, pat, NULL); 221 FcPatternDestroy (pat); 222 if (!fs || fs->nfont != 1) 223 { 224 printf ("E: Unexpected the number of fonts: %d\n", !fs ? -1 : fs->nfont); 225 ret = 1; 226 goto bail; 227 } 228 fprintf (stderr, "D: Removing %s\n", fontdir); 229 snprintf (cmd, 512, "rm -f %s%s*", fontdir, FC_DIR_SEPARATOR_S); 230 system (cmd); 231 fprintf (stderr, "D: Reinitializing\n"); 232 if (!FcConfigUptoDate (config) || !FcInitReinitialize ()) 233 { 234 fprintf (stderr, "E: Unable to reinitialize\n"); 235 ret = 2; 236 goto bail; 237 } 238 if (FcConfigGetCurrent () == config) 239 { 240 fprintf (stderr, "E: config wasn't reloaded\n"); 241 ret = 3; 242 goto bail; 243 } 244 config = FcConfigCreate (); 245 if (!FcConfigParseAndLoadFromMemory (config, conf, FcTrue)) 246 { 247 printf ("E: Unable to load config again\n"); 248 ret = 4; 249 goto bail; 250 } 251 if (!FcConfigBuildFonts (config)) 252 { 253 printf ("E: unable to build fonts again\n"); 254 ret = 5; 255 goto bail; 256 } 257 fprintf (stderr, "D: Obtaining fonts information again\n"); 258 pat = FcPatternCreate (); 259 fs = FcFontList (config, pat, NULL); 260 FcPatternDestroy (pat); 261 if (!fs || fs->nfont != 0) 262 { 263 printf ("E: Unexpected the number of fonts: %d\n", !fs ? -1 : fs->nfont); 264 ret = 1; 265 goto bail; 266 } 267 fprintf (stderr, "D: Copying %s to %s\n", FONTFILE, fontdir); 268 snprintf (cmd, 512, "cp -a %s %s", FONTFILE, fontdir); 269 system (cmd); 270 fprintf (stderr, "D: Reinitializing\n"); 271 if (!FcConfigUptoDate (config) || !FcInitReinitialize ()) 272 { 273 fprintf (stderr, "E: Unable to reinitialize\n"); 274 ret = 2; 275 goto bail; 276 } 277 if (FcConfigGetCurrent () == config) 278 { 279 fprintf (stderr, "E: config wasn't reloaded\n"); 280 ret = 3; 281 goto bail; 282 } 283 config = FcConfigCreate (); 284 if (!FcConfigParseAndLoadFromMemory (config, conf, FcTrue)) 285 { 286 printf ("E: Unable to load config again\n"); 287 ret = 4; 288 goto bail; 289 } 290 if (!FcConfigBuildFonts (config)) 291 { 292 printf ("E: unable to build fonts again\n"); 293 ret = 5; 294 goto bail; 295 } 296 fprintf (stderr, "D: Obtaining fonts information\n"); 297 pat = FcPatternCreate (); 298 fs = FcFontList (config, pat, NULL); 299 FcPatternDestroy (pat); 300 if (!fs || fs->nfont != 1) 301 { 302 printf ("E: Unexpected the number of fonts: %d\n", !fs ? -1 : fs->nfont); 303 ret = 1; 304 goto bail; 305 } 306 307bail: 308 fprintf (stderr, "Cleaning up\n"); 309 unlink_dirs (basedir); 310 if (fontdir) 311 FcStrFree (fontdir); 312 if (cachedir) 313 FcStrFree (cachedir); 314 315 return ret; 316} 317