Imported Upstream version 2.13.1
[platform/upstream/fontconfig.git] / test / test-bz106632.c
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
50 char *
51 fc_mkdtemp (char *template)
52 {
53     if (!mktemp (template) || mkdir (template, 0700))
54         return NULL;
55
56     return template;
57 }
58 #endif
59
60 FcBool
61 mkdir_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
82 FcBool
83 unlink_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
157 FcChar8 *
158 FcLangNormalize (const FcChar8 *lang)
159 {
160     return NULL;
161 }
162
163 FcChar8 *
164 FcConfigHome (void)
165 {
166     return NULL;
167 }
168
169 int
170 main (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
307 bail:
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 }