beta-0.89.2
[luatex.git] / source / texk / kpathsea / win32 / mktexmf.c
blobaf38fa50b6801459ff4511141c570a481e650533
1 /* mktexmf.c
3 Copyright 2000, 2015 Akira Kakuto.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include <kpathsea/kpathsea.h>
20 #include "mktex.h"
22 #define SBUF 512
24 static int
25 test_file(char c, char * name)
28 * c= 'z', 'f', 'd', 'r'
31 FILE *fp;
33 if (c == 'z') {
34 if (name == NULL) return 1;
35 else if (*name == '\0') return 1;
36 else if (_access(name, 0) != 0) return 1;
37 else if ((fp = (FILE *)fopen(name, "r")) == NULL) return 1;
38 else if (_filelength(_fileno(fp)) == 0L) {
39 fclose(fp);
40 return 1;
42 else {
43 fclose(fp);
44 return 0;
47 else if (c == 'f') {
48 if (name == NULL) return 0;
49 else if (*name == '\0') return 0;
50 else if (_access(name, 0) != 0) return 0;
51 else return 1;
53 else if (c == 'd') {
54 if (is_dir(name)) return 1;
55 else return 0;
57 else if (c == 'r') {
58 if (_access(name, 4) == 0) return 1;
59 else return 0;
61 /* never reaches here */
62 return 0;
65 static void
66 usage(void)
68 fprintf(stderr, "Usage : mktexmf FONT.\n\n");
69 fprintf(stderr, "Makes the Metafont source file for FONT,"
70 " if possible. For example,\n");
71 fprintf(stderr, "`ecr12' or `cmr11'.\n");
75 * Split a .mf name into root part and point size part.
76 * Root and point size are optional (may be NULL).
79 static void
80 split_mf_name(string name, string *base, string *root, string *ptsize)
82 string p, q;
83 /* name = basename $1 .mf */
84 p = strrchr (name, '.');
85 if (p) {
86 if (stricmp (p, ".mf") == 0) *p = '\0';
88 p = name;
90 if (base)
91 *base = xstrdup(p);
92 /* rootname = `echo $name | sed 's/[0-9]*$//'` */
93 for (q = p + strlen(p); q > p && isdigit(q[-1]); q--);
94 /* ptsize = `echo $name | sed 's/^$rootname//'` */
95 if (ptsize)
96 *ptsize = xstrdup(q);
97 *q = '\0';
98 if (root)
99 *root = p;
100 else
101 free(p);
104 static void
105 relmem (char **v)
107 int j;
108 for (j = 0; j < 4; j++)
109 free (v[j]);
110 return;
114 main (int argc, char **argv)
116 string rootname, pointsize;
117 const_string realsize;
118 string name;
119 string sauterroot, rootfile;
120 string destdir = NULL;
121 FILE *f;
122 size_t ptsz_len;
123 char font[SBUF];
124 char *progname;
125 char mfname[SBUF];
126 char *arg[4];
127 int i;
128 char *ptr;
130 kpse_set_program_name (argv[0], NULL);
131 progname = kpse_program_name;
133 if (argc != 2) {
134 usage();
135 return 0;
138 if (strncmp(argv[1], "-v",2) == 0 || strncmp(argv[1], "--v",3) == 0) {
139 fprintf ( stderr, "%s, (C version 1.1 --ak 2006-2015)\n", progname);
140 return 0;
143 if (strncmp(argv[1], "-h",2) == 0 || strncmp(argv[1], "--h",3) == 0) {
144 fprintf ( stderr, "%s, Usage: %s FontBaseName\n", progname, progname);
145 return 0;
148 for (i=0; i < 4; i++) {
149 arg[i] = (char *)malloc(SBUF);
152 if(strlen(argv[1]) > SBUF - 1) {
153 fprintf(stderr, "\nToo long a font name.\n");
154 return 100;
157 strcpy (font, argv[1]);
159 split_mf_name(font, &name, &rootname, &pointsize);
162 fprintf(stderr, "name = %s, rootname = %s, pointsize = %s\n",
163 name, rootname, pointsize);
166 sauterroot = kpse_find_file(concat3("b-", rootname, ".mf"),
167 kpse_mf_format, false);
169 if (sauterroot && *sauterroot) {
170 rootfile = sauterroot;
171 rootname = concat("b-", rootname);
172 strcpy (arg[0], "Dummy");
173 strcpy (arg[1], "source");
174 strcpy (arg[2], sauterroot);
175 if (!(ptr = getdestdir (3, arg))) {
176 fprintf(stderr, "Cannot get destination directory name.\n");
177 relmem (arg);
178 return 100;
180 destdir = ptr;
182 else if (strlen(name) == 8
183 && FILESTRNCASEEQ(name, "csso12", 6)
184 && (name[6] >= '0' && name[6] <= '5')
185 && isdigit(name[7])) {
186 rootfile = xstrdup("");
188 else if (FILESTRNCASEEQ(rootname, "cs", 2)
189 || FILESTRNCASEEQ(rootname, "lcsss", 5)
190 || FILESTRNCASEEQ(rootname, "icscsc", 6)
191 || FILESTRNCASEEQ(rootname, "icstt", 5)
192 || FILESTRNCASEEQ(rootname, "ilcsss", 6)
194 rootfile = kpse_find_file("cscode.mf",
195 kpse_mf_format, false);
197 else if (strlen(rootname) >= 3
198 && ((FILESTRNCASEEQ(rootname, "wn", 2)
199 && strchr("bBcCdDfFiIrRsStTuUvV", rootname[2]))
200 || (FILESTRNCASEEQ(rootname, "rx", 2)
201 && strchr("bBcCdDfFiIoOrRsStTuUvVxX", rootname[2])
202 && strlen(rootname) >= 4
203 && strchr("bBcCfFhHiIlLmMoOsStTxX", rootname[3]))
204 || ((rootname[0] == 'l' || rootname[0] == 'L')
205 && strchr("aAbBcCdDhHlL", rootname[1])
206 && strchr("bBcCdDfFiIoOrRsStTuUvVxX", rootname[2])))) {
207 char lhprefix[64];
208 strncpy(lhprefix, name, 2);
209 lhprefix[2] = '\0';
210 strcat(lhprefix, "codes.mf");
211 rootfile = kpse_find_file(lhprefix, kpse_mf_format, false);
213 else {
214 string tem;
215 rootfile = kpse_find_file(tem = concat(rootname, ".mf"),
216 kpse_mf_format, false);
217 free(tem);
220 if (test_file('z', rootfile)) {
221 fprintf (stderr, "%s: empty or non-existent rootfile!\n", progname);
222 relmem (arg);
223 return 1;
225 if (!test_file('f', rootfile)) {
226 fprintf (stderr, "%s: rootfile %s does not exist!\n", progname, rootfile);
227 relmem (arg);
228 return 1;
231 if (!destdir) {
232 if (rootfile && *rootfile) {
233 strcpy (arg[0], "Dummy");
234 strcpy (arg[1], "source");
235 strcpy (arg[2], rootfile);
236 if (!(ptr = getdestdir (3, arg))) {
237 fprintf(stderr, "Cannot get destination directory name.\n");
238 relmem (arg);
239 return 1;
241 destdir = ptr;
245 if (!test_file('d', destdir)) {
246 relmem (arg);
247 return 1;
250 ptsz_len = strlen(pointsize);
251 if (ptsz_len == 0) {
252 fprintf(stderr, "%s: no pointsize.\n", progname);
253 relmem (arg);
254 return 1;
255 } else if (ptsz_len == 2) {
256 if (pointsize[0] == '1' && pointsize[1] == '1')
257 realsize = "10.95"; /* \magstephalf */
258 else if (pointsize[0] == '1' && pointsize[1] == '4')
259 realsize = "14.4"; /* \magstep2 */
260 else if (pointsize[0] == '1' && pointsize[1] == '7')
261 realsize = "17.28"; /* \magstep3 */
262 else if (pointsize[0] == '2' && pointsize[1] == '0')
263 realsize = "20.74"; /* \magstep4 */
264 else if (pointsize[0] == '2' && pointsize[1] == '5')
265 realsize = "24.88"; /* \magstep5 */
266 else if (pointsize[0] == '3' && pointsize[1] == '0')
267 realsize = "29.86"; /* \magstep6 */
268 else if (pointsize[0] == '3' && pointsize[1] == '6')
269 realsize = "35.83"; /* \magstep7 */
270 else
271 realsize = pointsize;
273 /* The new convention is to have three or four letters for the
274 font name and four digits for the pointsize. The number is
275 pointsize * 100. We effectively divide by 100 by inserting a
276 dot before the last two digits. */
277 else if (ptsz_len == 4 || ptsz_len == 5) {
278 /* realsize=`echo "$pointsize" | sed 's/\(..\)$/.\1/'` */
279 string tempsize = (string)xmalloc(ptsz_len + 2);
280 strcpy(tempsize, pointsize);
281 /* The script doesn't check for last chars being digits, but we do! */
282 if (isdigit(tempsize[ptsz_len-1])
283 && isdigit(tempsize[ptsz_len-2])) {
284 tempsize[ptsz_len+1] = '\0';
285 tempsize[ptsz_len] = tempsize[ptsz_len-1];
286 tempsize[ptsz_len-1] = tempsize[ptsz_len-2];
287 tempsize[ptsz_len-2] = '.';
288 free(pointsize);
290 realsize = tempsize;
291 } else realsize = pointsize;
293 /* mfname is the full name */
294 strcpy (mfname, destdir);
295 i = (int)strlen (mfname);
296 if (mfname[i-1] != '/') {
297 mfname[i] = '/';
298 mfname[i+1] = '\0';
301 strcat (mfname, name);
302 strcat (mfname, ".mf");
304 if (test_file('r', mfname)) {
305 fprintf(stderr, "%s: %s already exists.\n", progname, mfname);
306 fprintf(stdout, "%s\n", mfname);
307 if (destdir) free (destdir);
308 relmem (arg);
309 return 0;
312 if ((f = fopen(mfname, "wb")) == NULL) {
313 fprintf(stderr, "%s: can't write into the file %s/%s.\n",
314 progname, destdir, name);
315 if (destdir) free (destdir);
316 relmem (arg);
317 return 1;
320 if (FILESTRNCASEEQ(name, "ec", 2)
321 || FILESTRNCASEEQ(name, "tc", 2)) {
322 fprintf(f, "if unknown exbase: input exbase fi;\n");
323 fprintf(f, "gensize:=%s;\ngenerate %s;\n", realsize, rootname);
325 else if (FILESTRNCASEEQ(name, "dc", 2)) {
326 fprintf(f, "if unknown dxbase: input dxbase fi;\n");
327 fprintf(f, "gensize:=%s;\ngenerate %s;\n", realsize, rootname);
330 else if (FILESTRNCASEEQ(name, "cs", 2)
331 || FILESTRNCASEEQ(name, "lcsss", 5)
332 || FILESTRNCASEEQ(name, "icscsc", 6)
333 || FILESTRNCASEEQ(name, "icstt", 5)
334 || FILESTRNCASEEQ(name, "ilcsss", 6)
336 fprintf(f, "input cscode\nuse_driver;\n");
338 else if (strlen(name) >= 3
339 && ((FILESTRNCASEEQ(name, "wn", 2)
340 && strchr("bBcCdDfFiIrRsStTuUvV", name[2]))
341 || (FILESTRNCASEEQ(name, "rx", 2)
342 && strchr("bBcCdDfFiIoOrRsStTuUvVxX", name[2])
343 && strlen(name) >= 4
344 && strchr("bBcCfFhHiIlLmMoOsStTxX", name[3]))
345 || ((name[0] == 'l' || name[0] == 'L')
346 && strchr("aAbBcCdDhHlL", name[1])
347 && strchr("bBcCdDfFiIoOrRsStTuUvVxX", name[2])))) {
348 fprintf(f, "input fikparm;\n");
350 else if (strlen(name) >= 4 && strchr("gG", name[0])
351 && strchr("lLmMoOrRsStT", name[1])
352 && strchr("bBiIjJmMtTwWxX", name[2])
353 && strchr("cCiIlLnNoOrRuU", name[3])) {
354 /* A small superset of the names of the cbgreek fonts:
355 pattern `g[lmorst][bijmtwx][cilnou]*'.
356 This is only slightly more general than the exact set of patterns.
358 fprintf(f, "gensize:=%s;\ninput %s;\n", realsize, rootname);
360 else {
361 /* FIXME: this was in the previous versions */
362 /* fprintf(f, "if unknown %s: input %s fi;\n", base, base); */
363 fprintf(f, "design_size := %s;\ninput %s;\n",
364 realsize, rootname);
367 fclose(f);
368 fprintf(stdout, "%s\n", mfname);
369 fprintf(stderr, "%s: %s: successfully generated.\n", progname, mfname);
370 mktexupd (mfname);
371 if (destdir) free (destdir);
372 relmem (arg);
373 return 0;