Fix unused-parameter warnings
[platform/upstream/fontconfig.git] / src / fcdir.c
1 /*
2  * fontconfig/src/fcdir.c
3  *
4  * Copyright © 2000 Keith Packard
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the author(s) not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission.  The authors make no
13  * representations about the suitability of this software for any purpose.  It
14  * is provided "as is" without express or implied warranty.
15  *
16  * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #include "fcint.h"
26 #include <dirent.h>
27
28 FcBool
29 FcFileIsDir (const FcChar8 *file)
30 {
31     struct stat     statb;
32
33     if (FcStat (file, &statb) != 0)
34         return FcFalse;
35     return S_ISDIR(statb.st_mode);
36 }
37
38 FcBool
39 FcFileIsLink (const FcChar8 *file)
40 {
41 #if HAVE_LSTAT
42     struct stat statb;
43
44     if (lstat ((const char *)file, &statb) != 0)
45         return FcFalse;
46     return S_ISLNK (statb.st_mode);
47 #else
48     return FcFalse;
49 #endif
50 }
51
52 static FcBool
53 FcFileScanFontConfig (FcFontSet         *set,
54                       FcBlanks          *blanks,
55                       const FcChar8     *file,
56                       FcConfig          *config)
57 {
58     FcPattern   *font;
59     FcBool      ret = FcTrue;
60     int         id;
61     int         count = 0;
62
63     id = 0;
64     do
65     {
66         font = 0;
67         /*
68          * Nothing in the cache, scan the file
69          */
70         if (FcDebug () & FC_DBG_SCAN)
71         {
72             printf ("\tScanning file %s...", file);
73             fflush (stdout);
74         }
75         font = FcFreeTypeQuery (file, id, blanks, &count);
76         if (FcDebug () & FC_DBG_SCAN)
77             printf ("done\n");
78
79         /*
80          * Edit pattern with user-defined rules
81          */
82         if (font && config && !FcConfigSubstitute (config, font, FcMatchScan))
83         {
84             FcPatternDestroy (font);
85             font = NULL;
86             ret = FcFalse;
87         }
88
89         /*
90          * Add the font
91          */
92         if (font)
93         {
94             if (FcDebug() & FC_DBG_SCANV)
95             {
96                 printf ("Final font pattern:\n");
97                 FcPatternPrint (font);
98             }
99             if (!FcFontSetAdd (set, font))
100             {
101                 FcPatternDestroy (font);
102                 font = NULL;
103                 ret = FcFalse;
104             }
105         }
106         else if (font)
107             FcPatternDestroy (font);
108         id++;
109     } while (font && ret && id < count);
110     return ret;
111 }
112
113 FcBool
114 FcFileScanConfig (FcFontSet     *set,
115                   FcStrSet      *dirs,
116                   FcBlanks      *blanks,
117                   const FcChar8 *file,
118                   FcConfig      *config)
119 {
120     if (FcFileIsDir (file))
121         return FcStrSetAdd (dirs, file);
122     else
123         return FcFileScanFontConfig (set, blanks, file, config);
124 }
125
126 FcBool
127 FcFileScan (FcFontSet       *set,
128             FcStrSet        *dirs,
129             FcFileCache     *cache FC_UNUSED,
130             FcBlanks        *blanks,
131             const FcChar8   *file,
132             FcBool          force FC_UNUSED)
133 {
134     return FcFileScanConfig (set, dirs, blanks, file, FcConfigGetCurrent ());
135 }
136
137 /*
138  * Strcmp helper that takes pointers to pointers, copied from qsort(3) manpage
139  */
140 static int
141 cmpstringp(const void *p1, const void *p2)
142 {
143     return strcmp(* (char **) p1, * (char **) p2);
144 }
145
146 FcBool
147 FcDirScanConfig (FcFontSet      *set,
148                  FcStrSet       *dirs,
149                  FcBlanks       *blanks,
150                  const FcChar8  *dir,
151                  FcBool         force, /* XXX unused */
152                  FcConfig       *config)
153 {
154     DIR                 *d;
155     struct dirent       *e;
156     FcStrSet            *files;
157     FcChar8             *file;
158     FcChar8             *base;
159     FcBool              ret = FcTrue;
160     int                 i;
161
162     if (!force)
163         return FcFalse;
164
165     if (!set && !dirs)
166         return FcTrue;
167
168     if (!blanks)
169         blanks = FcConfigGetBlanks (config);
170
171     /* freed below */
172     file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
173     if (!file) {
174         ret = FcFalse;
175         goto bail;
176     }
177
178     strcpy ((char *) file, (char *) dir);
179     strcat ((char *) file, "/");
180     base = file + strlen ((char *) file);
181
182     if (FcDebug () & FC_DBG_SCAN)
183         printf ("\tScanning dir %s\n", dir);
184         
185     d = opendir ((char *) dir);
186     if (!d)
187     {
188         /* Don't complain about missing directories */
189         if (errno != ENOENT)
190             ret = FcFalse;
191         goto bail;
192     }
193
194     files = FcStrSetCreate ();
195     if (!files)
196     {
197         ret = FcFalse;
198         goto bail1;
199     }
200     while ((e = readdir (d)))
201     {
202         if (e->d_name[0] != '.' && strlen (e->d_name) < FC_MAX_FILE_LEN)
203         {
204             strcpy ((char *) base, (char *) e->d_name);
205             if (!FcStrSetAdd (files, file)) {
206                 ret = FcFalse;
207                 goto bail2;
208             }
209         }
210     }
211
212     /*
213      * Sort files to make things prettier
214      */
215     qsort(files->strs, files->num, sizeof(FcChar8 *), cmpstringp);
216
217     /*
218      * Scan file files to build font patterns
219      */
220     for (i = 0; i < files->num; i++)
221         FcFileScanConfig (set, dirs, blanks, files->strs[i], config);
222
223 bail2:
224     FcStrSetDestroy (files);
225 bail1:
226     closedir (d);
227 bail:
228     if (file)
229         free (file);
230
231     return ret;
232 }
233
234 FcBool
235 FcDirScan (FcFontSet        *set,
236            FcStrSet         *dirs,
237            FcFileCache      *cache, /* XXX unused */
238            FcBlanks         *blanks,
239            const FcChar8    *dir,
240            FcBool           force /* XXX unused */)
241 {
242     if (cache || !force)
243         return FcFalse;
244
245     return FcDirScanConfig (set, dirs, blanks, dir, force, FcConfigGetCurrent ());
246 }
247
248 /*
249  * Scan the specified directory and construct a cache of its contents
250  */
251 FcCache *
252 FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
253 {
254     FcStrSet            *dirs;
255     FcFontSet           *set;
256     FcCache             *cache = NULL;
257     struct stat         dir_stat;
258
259     if (FcDebug () & FC_DBG_FONTSET)
260         printf ("cache scan dir %s\n", dir);
261
262     if (FcStatChecksum (dir, &dir_stat) < 0)
263         goto bail;
264
265     set = FcFontSetCreate();
266     if (!set)
267         goto bail;
268
269     dirs = FcStrSetCreate ();
270     if (!dirs)
271         goto bail1;
272
273     /*
274      * Scan the dir
275      */
276     if (!FcDirScanConfig (set, dirs, NULL, dir, FcTrue, config))
277         goto bail2;
278
279     /*
280      * Build the cache object
281      */
282     cache = FcDirCacheBuild (set, dir, &dir_stat, dirs);
283     if (!cache)
284         goto bail2;
285
286     /*
287      * Write out the cache file, ignoring any troubles
288      */
289     FcDirCacheWrite (cache, config);
290
291  bail2:
292     FcStrSetDestroy (dirs);
293  bail1:
294     FcFontSetDestroy (set);
295  bail:
296     return cache;
297 }
298
299 /*
300  * Read (or construct) the cache for a directory
301  */
302 FcCache *
303 FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config)
304 {
305     FcCache             *cache = NULL;
306
307     /* Try to use existing cache file */
308     if (!force)
309         cache = FcDirCacheLoad (dir, config, NULL);
310
311     /* Not using existing cache file, construct new cache */
312     if (!cache)
313         cache = FcDirCacheScan (dir, config);
314
315     return cache;
316 }
317
318 FcBool
319 FcDirSave (FcFontSet *set FC_UNUSED, FcStrSet * dirs FC_UNUSED, const FcChar8 *dir FC_UNUSED)
320 {
321     return FcFalse; /* XXX deprecated */
322 }
323 #define __fcdir__
324 #include "fcaliastail.h"
325 #undef __fcdir__