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