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