xref: /openbmc/linux/drivers/tty/vt/conmakehash.c (revision 8dd06ef34b6e2f41b29fbf5fc1663780f2524285)
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