]> git.wh0rd.org - fontconfig.git/blob - fc-cache/fc-cache.c
Build fclang.h before building library This required compiling the charset
[fontconfig.git] / fc-cache / fc-cache.c
1 /*
2 * $XFree86: xc/lib/fontconfig/fc-cache/fc-cache.c,v 1.8tsi Exp $
3 *
4 * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
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 Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes 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 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD 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 <fontconfig/fontconfig.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #else
35 #ifdef linux
36 #define HAVE_GETOPT_LONG 1
37 #endif
38 #define HAVE_GETOPT 1
39 #endif
40
41 #ifndef HAVE_GETOPT
42 #define HAVE_GETOPT 0
43 #endif
44 #ifndef HAVE_GETOPT_LONG
45 #define HAVE_GETOPT_LONG 0
46 #endif
47
48 #if HAVE_GETOPT_LONG
49 #undef _GNU_SOURCE
50 #define _GNU_SOURCE
51 #include <getopt.h>
52 const struct option longopts[] = {
53 {"force", 0, 0, 'f'},
54 {"version", 0, 0, 'V'},
55 {"verbose", 0, 0, 'v'},
56 {"help", 0, 0, '?'},
57 {NULL,0,0,0},
58 };
59 #else
60 #if HAVE_GETOPT
61 extern char *optarg;
62 extern int optind, opterr, optopt;
63 #endif
64 #endif
65
66 static void
67 usage (char *program)
68 {
69 fprintf (stderr, "usage: %s [-fvV?] [--force] [--verbose] [--version] [--help] [dirs]\n",
70 program);
71 fprintf (stderr, "Build font information caches in [dirs]\n"
72 "(all directories in font configuration by default).\n");
73 fprintf (stderr, "\n");
74 fprintf (stderr, " -f, --force scan directories with apparently valid caches\n");
75 fprintf (stderr, " -v, --verbose display status information while busy\n");
76 fprintf (stderr, " -V, --version display font config version and exit\n");
77 fprintf (stderr, " -?, --help display this help and exit\n");
78 exit (1);
79 }
80
81 static int
82 nsubdirs (FcStrSet *set)
83 {
84 FcStrList *list;
85 int n = 0;
86
87 list = FcStrListCreate (set);
88 if (!list)
89 return 0;
90 while (FcStrListNext (list))
91 n++;
92 FcStrListDone (list);
93 return n;
94 }
95
96 static int
97 scanDirs (FcStrList *list, FcConfig *config, char *program, FcBool force, FcBool verbose)
98 {
99 int ret = 0;
100 FcChar8 *dir;
101 FcFontSet *set;
102 FcStrSet *subdirs;
103 FcStrList *sublist;
104 struct stat statb;
105
106 /*
107 * Now scan all of the directories into separate databases
108 * and write out the results
109 */
110 while ((dir = FcStrListNext (list)))
111 {
112 if (verbose)
113 {
114 printf ("%s: \"%s\": ", program, dir);
115 fflush (stdout);
116 }
117 set = FcFontSetCreate ();
118 if (!set)
119 {
120 fprintf (stderr, "Can't create font set\n");
121 ret++;
122 continue;
123 }
124 subdirs = FcStrSetCreate ();
125 if (!subdirs)
126 {
127 fprintf (stderr, "Can't create directory set\n");
128 ret++;
129 continue;
130 }
131
132 if (stat ((char *) dir, &statb) == -1)
133 {
134 if (errno == ENOENT || errno == ENOTDIR)
135 {
136 if (verbose)
137 printf ("no such directory, skipping\n");
138 }
139 else
140 {
141 fprintf (stderr, "\"%s\": ", dir);
142 perror ("");
143 ret++;
144 }
145 continue;
146 }
147 if (!S_ISDIR (statb.st_mode))
148 {
149 fprintf (stderr, "\"%s\": not a directory, skipping\n", dir);
150 continue;
151 }
152 if (!FcDirScan (set, subdirs, 0, FcConfigGetBlanks (config), dir, force))
153 {
154 fprintf (stderr, "\"%s\": error scanning\n", dir);
155 ret++;
156 continue;
157 }
158 if (!force && FcDirCacheValid (dir))
159 {
160 if (verbose)
161 printf ("skipping, %d fonts, %d dirs\n",
162 set->nfont, nsubdirs(subdirs));
163 }
164 else
165 {
166 if (verbose)
167 printf ("caching, %d fonts, %d dirs\n",
168 set->nfont, nsubdirs (subdirs));
169 if (!FcDirSave (set, subdirs, dir))
170 {
171 fprintf (stderr, "Can't save cache in \"%s\"\n", dir);
172 ret++;
173 }
174 }
175 FcFontSetDestroy (set);
176 sublist = FcStrListCreate (subdirs);
177 if (!sublist)
178 {
179 fprintf (stderr, "Can't create subdir list in \"%s\"\n", dir);
180 ret++;
181 continue;
182 }
183 ret += scanDirs (sublist, config, program, force, verbose);
184 FcStrSetDestroy (subdirs);
185 }
186 FcStrListDone (list);
187 return ret;
188 }
189
190 int
191 main (int argc, char **argv)
192 {
193 FcStrSet *dirs;
194 FcStrList *list;
195 FcBool verbose = FcFalse;
196 FcBool force = FcFalse;
197 FcConfig *config;
198 int i;
199 int ret;
200 #if HAVE_GETOPT_LONG || HAVE_GETOPT
201 int c;
202
203 #if HAVE_GETOPT_LONG
204 while ((c = getopt_long (argc, argv, "fVv?", longopts, NULL)) != -1)
205 #else
206 while ((c = getopt (argc, argv, "fVv?")) != -1)
207 #endif
208 {
209 switch (c) {
210 case 'f':
211 force = FcTrue;
212 break;
213 case 'V':
214 fprintf (stderr, "fontconfig version %d.%d.%d\n",
215 FC_MAJOR, FC_MINOR, FC_REVISION);
216 exit (0);
217 case 'v':
218 verbose = FcTrue;
219 break;
220 default:
221 usage (argv[0]);
222 }
223 }
224 i = optind;
225 #else
226 i = 1;
227 #endif
228
229 config = FcInitLoadConfig ();
230 if (!config)
231 {
232 fprintf (stderr, "%s: Can't init font config library\n", argv[0]);
233 return 1;
234 }
235 if (argv[i])
236 {
237 dirs = FcStrSetCreate ();
238 if (!dirs)
239 {
240 fprintf (stderr, "%s: Can't create list of directories\n",
241 argv[0]);
242 return 1;
243 }
244 while (argv[i])
245 {
246 if (!FcStrSetAdd (dirs, (FcChar8 *) argv[i]))
247 {
248 fprintf (stderr, "%s: Can't add directory\n", argv[0]);
249 return 1;
250 }
251 i++;
252 }
253 list = FcStrListCreate (dirs);
254 FcStrSetDestroy (dirs);
255 }
256 else
257 list = FcConfigGetConfigDirs (config);
258 ret = scanDirs (list, config, argv[0], force, verbose);
259 if (verbose)
260 printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded");
261 return ret;
262 }