1*4484aa80SMasahiro Yamada // SPDX-License-Identifier: GPL-2.0-or-later
2*4484aa80SMasahiro Yamada /*
3*4484aa80SMasahiro Yamada * conmakehash.c
4*4484aa80SMasahiro Yamada *
5*4484aa80SMasahiro Yamada * Create arrays for initializing the kernel folded tables (using a hash
6*4484aa80SMasahiro Yamada * table turned out to be to limiting...) Unfortunately we can't simply
7*4484aa80SMasahiro Yamada * preinitialize the tables at compile time since kfree() cannot accept
8*4484aa80SMasahiro Yamada * memory not allocated by kmalloc(), and doing our own memory management
9*4484aa80SMasahiro Yamada * just for this seems like massive overkill.
10*4484aa80SMasahiro Yamada *
11*4484aa80SMasahiro Yamada * Copyright (C) 1995-1997 H. Peter Anvin
12*4484aa80SMasahiro Yamada */
13*4484aa80SMasahiro Yamada
14*4484aa80SMasahiro Yamada #include <stdio.h>
15*4484aa80SMasahiro Yamada #include <stdlib.h>
16*4484aa80SMasahiro Yamada #include <sysexits.h>
17*4484aa80SMasahiro Yamada #include <string.h>
18*4484aa80SMasahiro Yamada #include <ctype.h>
19*4484aa80SMasahiro Yamada
20*4484aa80SMasahiro Yamada #define MAX_FONTLEN 256
21*4484aa80SMasahiro Yamada
22*4484aa80SMasahiro Yamada typedef unsigned short unicode;
23*4484aa80SMasahiro Yamada
usage(char * argv0)24*4484aa80SMasahiro Yamada static void usage(char *argv0)
25*4484aa80SMasahiro Yamada {
26*4484aa80SMasahiro Yamada fprintf(stderr, "Usage: \n"
27*4484aa80SMasahiro Yamada " %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
28*4484aa80SMasahiro Yamada exit(EX_USAGE);
29*4484aa80SMasahiro Yamada }
30*4484aa80SMasahiro Yamada
getunicode(char ** p0)31*4484aa80SMasahiro Yamada static int getunicode(char **p0)
32*4484aa80SMasahiro Yamada {
33*4484aa80SMasahiro Yamada char *p = *p0;
34*4484aa80SMasahiro Yamada
35*4484aa80SMasahiro Yamada while (*p == ' ' || *p == '\t')
36*4484aa80SMasahiro Yamada p++;
37*4484aa80SMasahiro Yamada if (*p != 'U' || p[1] != '+' ||
38*4484aa80SMasahiro Yamada !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
39*4484aa80SMasahiro Yamada !isxdigit(p[5]) || isxdigit(p[6]))
40*4484aa80SMasahiro Yamada return -1;
41*4484aa80SMasahiro Yamada *p0 = p+6;
42*4484aa80SMasahiro Yamada return strtol(p+2,0,16);
43*4484aa80SMasahiro Yamada }
44*4484aa80SMasahiro Yamada
45*4484aa80SMasahiro Yamada unicode unitable[MAX_FONTLEN][255];
46*4484aa80SMasahiro Yamada /* Massive overkill, but who cares? */
47*4484aa80SMasahiro Yamada int unicount[MAX_FONTLEN];
48*4484aa80SMasahiro Yamada
addpair(int fp,int un)49*4484aa80SMasahiro Yamada static void addpair(int fp, int un)
50*4484aa80SMasahiro Yamada {
51*4484aa80SMasahiro Yamada int i;
52*4484aa80SMasahiro Yamada
53*4484aa80SMasahiro Yamada if ( un <= 0xfffe )
54*4484aa80SMasahiro Yamada {
55*4484aa80SMasahiro Yamada /* Check it isn't a duplicate */
56*4484aa80SMasahiro Yamada
57*4484aa80SMasahiro Yamada for ( i = 0 ; i < unicount[fp] ; i++ )
58*4484aa80SMasahiro Yamada if ( unitable[fp][i] == un )
59*4484aa80SMasahiro Yamada return;
60*4484aa80SMasahiro Yamada
61*4484aa80SMasahiro Yamada /* Add to list */
62*4484aa80SMasahiro Yamada
63*4484aa80SMasahiro Yamada if ( unicount[fp] > 254 )
64*4484aa80SMasahiro Yamada {
65*4484aa80SMasahiro Yamada fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n");
66*4484aa80SMasahiro Yamada exit(EX_DATAERR);
67*4484aa80SMasahiro Yamada }
68*4484aa80SMasahiro Yamada
69*4484aa80SMasahiro Yamada unitable[fp][unicount[fp]] = un;
70*4484aa80SMasahiro Yamada unicount[fp]++;
71*4484aa80SMasahiro Yamada }
72*4484aa80SMasahiro Yamada
73*4484aa80SMasahiro Yamada /* otherwise: ignore */
74*4484aa80SMasahiro Yamada }
75*4484aa80SMasahiro Yamada
main(int argc,char * argv[])76*4484aa80SMasahiro Yamada int main(int argc, char *argv[])
77*4484aa80SMasahiro Yamada {
78*4484aa80SMasahiro Yamada FILE *ctbl;
79*4484aa80SMasahiro Yamada char *tblname;
80*4484aa80SMasahiro Yamada char buffer[65536];
81*4484aa80SMasahiro Yamada int fontlen;
82*4484aa80SMasahiro Yamada int i, nuni, nent;
83*4484aa80SMasahiro Yamada int fp0, fp1, un0, un1;
84*4484aa80SMasahiro Yamada char *p, *p1;
85*4484aa80SMasahiro Yamada
86*4484aa80SMasahiro Yamada if ( argc < 2 || argc > 5 )
87*4484aa80SMasahiro Yamada usage(argv[0]);
88*4484aa80SMasahiro Yamada
89*4484aa80SMasahiro Yamada if ( !strcmp(argv[1],"-") )
90*4484aa80SMasahiro Yamada {
91*4484aa80SMasahiro Yamada ctbl = stdin;
92*4484aa80SMasahiro Yamada tblname = "stdin";
93*4484aa80SMasahiro Yamada }
94*4484aa80SMasahiro Yamada else
95*4484aa80SMasahiro Yamada {
96*4484aa80SMasahiro Yamada ctbl = fopen(tblname = argv[1], "r");
97*4484aa80SMasahiro Yamada if ( !ctbl )
98*4484aa80SMasahiro Yamada {
99*4484aa80SMasahiro Yamada perror(tblname);
100*4484aa80SMasahiro Yamada exit(EX_NOINPUT);
101*4484aa80SMasahiro Yamada }
102*4484aa80SMasahiro Yamada }
103*4484aa80SMasahiro Yamada
104*4484aa80SMasahiro Yamada /* For now we assume the default font is always 256 characters. */
105*4484aa80SMasahiro Yamada fontlen = 256;
106*4484aa80SMasahiro Yamada
107*4484aa80SMasahiro Yamada /* Initialize table */
108*4484aa80SMasahiro Yamada
109*4484aa80SMasahiro Yamada for ( i = 0 ; i < fontlen ; i++ )
110*4484aa80SMasahiro Yamada unicount[i] = 0;
111*4484aa80SMasahiro Yamada
112*4484aa80SMasahiro Yamada /* Now we come to the tricky part. Parse the input table. */
113*4484aa80SMasahiro Yamada
114*4484aa80SMasahiro Yamada while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
115*4484aa80SMasahiro Yamada {
116*4484aa80SMasahiro Yamada if ( (p = strchr(buffer, '\n')) != NULL )
117*4484aa80SMasahiro Yamada *p = '\0';
118*4484aa80SMasahiro Yamada else
119*4484aa80SMasahiro Yamada fprintf(stderr, "%s: Warning: line too long\n", tblname);
120*4484aa80SMasahiro Yamada
121*4484aa80SMasahiro Yamada p = buffer;
122*4484aa80SMasahiro Yamada
123*4484aa80SMasahiro Yamada /*
124*4484aa80SMasahiro Yamada * Syntax accepted:
125*4484aa80SMasahiro Yamada * <fontpos> <unicode> <unicode> ...
126*4484aa80SMasahiro Yamada * <range> idem
127*4484aa80SMasahiro Yamada * <range> <unicode range>
128*4484aa80SMasahiro Yamada *
129*4484aa80SMasahiro Yamada * where <range> ::= <fontpos>-<fontpos>
130*4484aa80SMasahiro Yamada * and <unicode> ::= U+<h><h><h><h>
131*4484aa80SMasahiro Yamada * and <h> ::= <hexadecimal digit>
132*4484aa80SMasahiro Yamada */
133*4484aa80SMasahiro Yamada
134*4484aa80SMasahiro Yamada while (*p == ' ' || *p == '\t')
135*4484aa80SMasahiro Yamada p++;
136*4484aa80SMasahiro Yamada if (!*p || *p == '#')
137*4484aa80SMasahiro Yamada continue; /* skip comment or blank line */
138*4484aa80SMasahiro Yamada
139*4484aa80SMasahiro Yamada fp0 = strtol(p, &p1, 0);
140*4484aa80SMasahiro Yamada if (p1 == p)
141*4484aa80SMasahiro Yamada {
142*4484aa80SMasahiro Yamada fprintf(stderr, "Bad input line: %s\n", buffer);
143*4484aa80SMasahiro Yamada exit(EX_DATAERR);
144*4484aa80SMasahiro Yamada }
145*4484aa80SMasahiro Yamada p = p1;
146*4484aa80SMasahiro Yamada
147*4484aa80SMasahiro Yamada while (*p == ' ' || *p == '\t')
148*4484aa80SMasahiro Yamada p++;
149*4484aa80SMasahiro Yamada if (*p == '-')
150*4484aa80SMasahiro Yamada {
151*4484aa80SMasahiro Yamada p++;
152*4484aa80SMasahiro Yamada fp1 = strtol(p, &p1, 0);
153*4484aa80SMasahiro Yamada if (p1 == p)
154*4484aa80SMasahiro Yamada {
155*4484aa80SMasahiro Yamada fprintf(stderr, "Bad input line: %s\n", buffer);
156*4484aa80SMasahiro Yamada exit(EX_DATAERR);
157*4484aa80SMasahiro Yamada }
158*4484aa80SMasahiro Yamada p = p1;
159*4484aa80SMasahiro Yamada }
160*4484aa80SMasahiro Yamada else
161*4484aa80SMasahiro Yamada fp1 = 0;
162*4484aa80SMasahiro Yamada
163*4484aa80SMasahiro Yamada if ( fp0 < 0 || fp0 >= fontlen )
164*4484aa80SMasahiro Yamada {
165*4484aa80SMasahiro Yamada fprintf(stderr,
166*4484aa80SMasahiro Yamada "%s: Glyph number (0x%x) larger than font length\n",
167*4484aa80SMasahiro Yamada tblname, fp0);
168*4484aa80SMasahiro Yamada exit(EX_DATAERR);
169*4484aa80SMasahiro Yamada }
170*4484aa80SMasahiro Yamada if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
171*4484aa80SMasahiro Yamada {
172*4484aa80SMasahiro Yamada fprintf(stderr,
173*4484aa80SMasahiro Yamada "%s: Bad end of range (0x%x)\n",
174*4484aa80SMasahiro Yamada tblname, fp1);
175*4484aa80SMasahiro Yamada exit(EX_DATAERR);
176*4484aa80SMasahiro Yamada }
177*4484aa80SMasahiro Yamada
178*4484aa80SMasahiro Yamada if (fp1)
179*4484aa80SMasahiro Yamada {
180*4484aa80SMasahiro Yamada /* we have a range; expect the word "idem" or a Unicode range of the
181*4484aa80SMasahiro Yamada same length */
182*4484aa80SMasahiro Yamada while (*p == ' ' || *p == '\t')
183*4484aa80SMasahiro Yamada p++;
184*4484aa80SMasahiro Yamada if (!strncmp(p, "idem", 4))
185*4484aa80SMasahiro Yamada {
186*4484aa80SMasahiro Yamada for (i=fp0; i<=fp1; i++)
187*4484aa80SMasahiro Yamada addpair(i,i);
188*4484aa80SMasahiro Yamada p += 4;
189*4484aa80SMasahiro Yamada }
190*4484aa80SMasahiro Yamada else
191*4484aa80SMasahiro Yamada {
192*4484aa80SMasahiro Yamada un0 = getunicode(&p);
193*4484aa80SMasahiro Yamada while (*p == ' ' || *p == '\t')
194*4484aa80SMasahiro Yamada p++;
195*4484aa80SMasahiro Yamada if (*p != '-')
196*4484aa80SMasahiro Yamada {
197*4484aa80SMasahiro Yamada fprintf(stderr,
198*4484aa80SMasahiro Yamada "%s: Corresponding to a range of font positions, there should be a Unicode range\n",
199*4484aa80SMasahiro Yamada tblname);
200*4484aa80SMasahiro Yamada exit(EX_DATAERR);
201*4484aa80SMasahiro Yamada }
202*4484aa80SMasahiro Yamada p++;
203*4484aa80SMasahiro Yamada un1 = getunicode(&p);
204*4484aa80SMasahiro Yamada if (un0 < 0 || un1 < 0)
205*4484aa80SMasahiro Yamada {
206*4484aa80SMasahiro Yamada fprintf(stderr,
207*4484aa80SMasahiro Yamada "%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
208*4484aa80SMasahiro Yamada tblname, fp0, fp1);
209*4484aa80SMasahiro Yamada exit(EX_DATAERR);
210*4484aa80SMasahiro Yamada }
211*4484aa80SMasahiro Yamada if (un1 - un0 != fp1 - fp0)
212*4484aa80SMasahiro Yamada {
213*4484aa80SMasahiro Yamada fprintf(stderr,
214*4484aa80SMasahiro Yamada "%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
215*4484aa80SMasahiro Yamada tblname, un0, un1, fp0, fp1);
216*4484aa80SMasahiro Yamada exit(EX_DATAERR);
217*4484aa80SMasahiro Yamada }
218*4484aa80SMasahiro Yamada for(i=fp0; i<=fp1; i++)
219*4484aa80SMasahiro Yamada addpair(i,un0-fp0+i);
220*4484aa80SMasahiro Yamada }
221*4484aa80SMasahiro Yamada }
222*4484aa80SMasahiro Yamada else
223*4484aa80SMasahiro Yamada {
224*4484aa80SMasahiro Yamada /* no range; expect a list of unicode values for a single font position */
225*4484aa80SMasahiro Yamada
226*4484aa80SMasahiro Yamada while ( (un0 = getunicode(&p)) >= 0 )
227*4484aa80SMasahiro Yamada addpair(fp0, un0);
228*4484aa80SMasahiro Yamada }
229*4484aa80SMasahiro Yamada while (*p == ' ' || *p == '\t')
230*4484aa80SMasahiro Yamada p++;
231*4484aa80SMasahiro Yamada if (*p && *p != '#')
232*4484aa80SMasahiro Yamada fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
233*4484aa80SMasahiro Yamada }
234*4484aa80SMasahiro Yamada
235*4484aa80SMasahiro Yamada /* Okay, we hit EOF, now output hash table */
236*4484aa80SMasahiro Yamada
237*4484aa80SMasahiro Yamada fclose(ctbl);
238*4484aa80SMasahiro Yamada
239*4484aa80SMasahiro Yamada
240*4484aa80SMasahiro Yamada /* Compute total size of Unicode list */
241*4484aa80SMasahiro Yamada nuni = 0;
242*4484aa80SMasahiro Yamada for ( i = 0 ; i < fontlen ; i++ )
243*4484aa80SMasahiro Yamada nuni += unicount[i];
244*4484aa80SMasahiro Yamada
245*4484aa80SMasahiro Yamada printf("\
246*4484aa80SMasahiro Yamada /*\n\
247*4484aa80SMasahiro Yamada * Do not edit this file; it was automatically generated by\n\
248*4484aa80SMasahiro Yamada *\n\
249*4484aa80SMasahiro Yamada * conmakehash %s > [this file]\n\
250*4484aa80SMasahiro Yamada *\n\
251*4484aa80SMasahiro Yamada */\n\
252*4484aa80SMasahiro Yamada \n\
253*4484aa80SMasahiro Yamada #include <linux/types.h>\n\
254*4484aa80SMasahiro Yamada \n\
255*4484aa80SMasahiro Yamada u8 dfont_unicount[%d] = \n\
256*4484aa80SMasahiro Yamada {\n\t", argv[1], fontlen);
257*4484aa80SMasahiro Yamada
258*4484aa80SMasahiro Yamada for ( i = 0 ; i < fontlen ; i++ )
259*4484aa80SMasahiro Yamada {
260*4484aa80SMasahiro Yamada printf("%3d", unicount[i]);
261*4484aa80SMasahiro Yamada if ( i == fontlen-1 )
262*4484aa80SMasahiro Yamada printf("\n};\n");
263*4484aa80SMasahiro Yamada else if ( i % 8 == 7 )
264*4484aa80SMasahiro Yamada printf(",\n\t");
265*4484aa80SMasahiro Yamada else
266*4484aa80SMasahiro Yamada printf(", ");
267*4484aa80SMasahiro Yamada }
268*4484aa80SMasahiro Yamada
269*4484aa80SMasahiro Yamada printf("\nu16 dfont_unitable[%d] = \n{\n\t", nuni);
270*4484aa80SMasahiro Yamada
271*4484aa80SMasahiro Yamada fp0 = 0;
272*4484aa80SMasahiro Yamada nent = 0;
273*4484aa80SMasahiro Yamada for ( i = 0 ; i < nuni ; i++ )
274*4484aa80SMasahiro Yamada {
275*4484aa80SMasahiro Yamada while ( nent >= unicount[fp0] )
276*4484aa80SMasahiro Yamada {
277*4484aa80SMasahiro Yamada fp0++;
278*4484aa80SMasahiro Yamada nent = 0;
279*4484aa80SMasahiro Yamada }
280*4484aa80SMasahiro Yamada printf("0x%04x", unitable[fp0][nent++]);
281*4484aa80SMasahiro Yamada if ( i == nuni-1 )
282*4484aa80SMasahiro Yamada printf("\n};\n");
283*4484aa80SMasahiro Yamada else if ( i % 8 == 7 )
284*4484aa80SMasahiro Yamada printf(",\n\t");
285*4484aa80SMasahiro Yamada else
286*4484aa80SMasahiro Yamada printf(", ");
287*4484aa80SMasahiro Yamada }
288*4484aa80SMasahiro Yamada
289*4484aa80SMasahiro Yamada exit(EX_OK);
290*4484aa80SMasahiro Yamada }
291