xref: /linux/drivers/tty/vt/conmakehash.c (revision 4484aa800ac588a1fe2175cd53076c21067f44b4)
1*a25d83ebSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * conmakehash.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Create arrays for initializing the kernel folded tables (using a hash
61da177e4SLinus Torvalds  * table turned out to be to limiting...)  Unfortunately we can't simply
71da177e4SLinus Torvalds  * preinitialize the tables at compile time since kfree() cannot accept
81da177e4SLinus Torvalds  * memory not allocated by kmalloc(), and doing our own memory management
91da177e4SLinus Torvalds  * just for this seems like massive overkill.
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  * Copyright (C) 1995-1997 H. Peter Anvin
121da177e4SLinus Torvalds  */
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds #include <stdio.h>
151da177e4SLinus Torvalds #include <stdlib.h>
161da177e4SLinus Torvalds #include <sysexits.h>
171da177e4SLinus Torvalds #include <string.h>
181da177e4SLinus Torvalds #include <ctype.h>
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds #define MAX_FONTLEN 256
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds typedef unsigned short unicode;
231da177e4SLinus Torvalds 
245c725138STrevor Keith static void usage(char *argv0)
251da177e4SLinus Torvalds {
261da177e4SLinus Torvalds   fprintf(stderr, "Usage: \n"
271da177e4SLinus Torvalds          "        %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
281da177e4SLinus Torvalds   exit(EX_USAGE);
291da177e4SLinus Torvalds }
301da177e4SLinus Torvalds 
315c725138STrevor Keith static int getunicode(char **p0)
321da177e4SLinus Torvalds {
3361d9cdf2SJ.A. Magallon   char *p = *p0;
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds   while (*p == ' ' || *p == '\t')
361da177e4SLinus Torvalds     p++;
371da177e4SLinus Torvalds   if (*p != 'U' || p[1] != '+' ||
381da177e4SLinus Torvalds       !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
391da177e4SLinus Torvalds       !isxdigit(p[5]) || isxdigit(p[6]))
401da177e4SLinus Torvalds     return -1;
411da177e4SLinus Torvalds   *p0 = p+6;
421da177e4SLinus Torvalds   return strtol(p+2,0,16);
431da177e4SLinus Torvalds }
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds unicode unitable[MAX_FONTLEN][255];
461da177e4SLinus Torvalds 				/* Massive overkill, but who cares? */
471da177e4SLinus Torvalds int unicount[MAX_FONTLEN];
481da177e4SLinus Torvalds 
495c725138STrevor Keith static void addpair(int fp, int un)
501da177e4SLinus Torvalds {
511da177e4SLinus Torvalds   int i;
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds   if ( un <= 0xfffe )
541da177e4SLinus Torvalds     {
551da177e4SLinus Torvalds       /* Check it isn't a duplicate */
561da177e4SLinus Torvalds 
571da177e4SLinus Torvalds       for ( i = 0 ; i < unicount[fp] ; i++ )
581da177e4SLinus Torvalds 	if ( unitable[fp][i] == un )
591da177e4SLinus Torvalds 	  return;
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds       /* Add to list */
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds       if ( unicount[fp] > 254 )
641da177e4SLinus Torvalds 	{
651da177e4SLinus Torvalds 	  fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n");
661da177e4SLinus Torvalds 	  exit(EX_DATAERR);
671da177e4SLinus Torvalds 	}
681da177e4SLinus Torvalds 
691da177e4SLinus Torvalds       unitable[fp][unicount[fp]] = un;
701da177e4SLinus Torvalds       unicount[fp]++;
711da177e4SLinus Torvalds     }
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds   /* otherwise: ignore */
741da177e4SLinus Torvalds }
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds int main(int argc, char *argv[])
771da177e4SLinus Torvalds {
781da177e4SLinus Torvalds   FILE *ctbl;
791da177e4SLinus Torvalds   char *tblname;
801da177e4SLinus Torvalds   char buffer[65536];
811da177e4SLinus Torvalds   int fontlen;
821da177e4SLinus Torvalds   int i, nuni, nent;
831da177e4SLinus Torvalds   int fp0, fp1, un0, un1;
841da177e4SLinus Torvalds   char *p, *p1;
851da177e4SLinus Torvalds 
861da177e4SLinus Torvalds   if ( argc < 2 || argc > 5 )
871da177e4SLinus Torvalds     usage(argv[0]);
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds   if ( !strcmp(argv[1],"-") )
901da177e4SLinus Torvalds     {
911da177e4SLinus Torvalds       ctbl = stdin;
921da177e4SLinus Torvalds       tblname = "stdin";
931da177e4SLinus Torvalds     }
941da177e4SLinus Torvalds   else
951da177e4SLinus Torvalds     {
961da177e4SLinus Torvalds       ctbl = fopen(tblname = argv[1], "r");
971da177e4SLinus Torvalds       if ( !ctbl )
981da177e4SLinus Torvalds 	{
991da177e4SLinus Torvalds 	  perror(tblname);
1001da177e4SLinus Torvalds 	  exit(EX_NOINPUT);
1011da177e4SLinus Torvalds 	}
1021da177e4SLinus Torvalds     }
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds   /* For now we assume the default font is always 256 characters. */
1051da177e4SLinus Torvalds   fontlen = 256;
1061da177e4SLinus Torvalds 
1071da177e4SLinus Torvalds   /* Initialize table */
1081da177e4SLinus Torvalds 
1091da177e4SLinus Torvalds   for ( i = 0 ; i < fontlen ; i++ )
1101da177e4SLinus Torvalds     unicount[i] = 0;
1111da177e4SLinus Torvalds 
1121da177e4SLinus Torvalds   /* Now we come to the tricky part.  Parse the input table. */
1131da177e4SLinus Torvalds 
1141da177e4SLinus Torvalds   while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
1151da177e4SLinus Torvalds     {
1161da177e4SLinus Torvalds       if ( (p = strchr(buffer, '\n')) != NULL )
1171da177e4SLinus Torvalds 	*p = '\0';
1181da177e4SLinus Torvalds       else
1191da177e4SLinus Torvalds 	fprintf(stderr, "%s: Warning: line too long\n", tblname);
1201da177e4SLinus Torvalds 
1211da177e4SLinus Torvalds       p = buffer;
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds /*
1241da177e4SLinus Torvalds  * Syntax accepted:
1251da177e4SLinus Torvalds  *	<fontpos>	<unicode> <unicode> ...
1261da177e4SLinus Torvalds  *	<range>		idem
1271da177e4SLinus Torvalds  *	<range>		<unicode range>
1281da177e4SLinus Torvalds  *
1291da177e4SLinus Torvalds  * where <range> ::= <fontpos>-<fontpos>
1301da177e4SLinus Torvalds  * and <unicode> ::= U+<h><h><h><h>
1311da177e4SLinus Torvalds  * and <h> ::= <hexadecimal digit>
1321da177e4SLinus Torvalds  */
1331da177e4SLinus Torvalds 
1341da177e4SLinus Torvalds       while (*p == ' ' || *p == '\t')
1351da177e4SLinus Torvalds 	p++;
1361da177e4SLinus Torvalds       if (!*p || *p == '#')
1371da177e4SLinus Torvalds 	continue;	/* skip comment or blank line */
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds       fp0 = strtol(p, &p1, 0);
1401da177e4SLinus Torvalds       if (p1 == p)
1411da177e4SLinus Torvalds 	{
1421da177e4SLinus Torvalds 	  fprintf(stderr, "Bad input line: %s\n", buffer);
1431da177e4SLinus Torvalds 	  exit(EX_DATAERR);
1441da177e4SLinus Torvalds         }
1451da177e4SLinus Torvalds       p = p1;
1461da177e4SLinus Torvalds 
1471da177e4SLinus Torvalds       while (*p == ' ' || *p == '\t')
1481da177e4SLinus Torvalds 	p++;
1491da177e4SLinus Torvalds       if (*p == '-')
1501da177e4SLinus Torvalds 	{
1511da177e4SLinus Torvalds 	  p++;
1521da177e4SLinus Torvalds 	  fp1 = strtol(p, &p1, 0);
1531da177e4SLinus Torvalds 	  if (p1 == p)
1541da177e4SLinus Torvalds 	    {
1551da177e4SLinus Torvalds 	      fprintf(stderr, "Bad input line: %s\n", buffer);
1561da177e4SLinus Torvalds 	      exit(EX_DATAERR);
1571da177e4SLinus Torvalds 	    }
1581da177e4SLinus Torvalds 	  p = p1;
1591da177e4SLinus Torvalds         }
1601da177e4SLinus Torvalds       else
1611da177e4SLinus Torvalds 	fp1 = 0;
1621da177e4SLinus Torvalds 
1631da177e4SLinus Torvalds       if ( fp0 < 0 || fp0 >= fontlen )
1641da177e4SLinus Torvalds 	{
1651da177e4SLinus Torvalds 	    fprintf(stderr,
1661da177e4SLinus Torvalds 		    "%s: Glyph number (0x%x) larger than font length\n",
1671da177e4SLinus Torvalds 		    tblname, fp0);
1681da177e4SLinus Torvalds 	    exit(EX_DATAERR);
1691da177e4SLinus Torvalds 	}
1701da177e4SLinus Torvalds       if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
1711da177e4SLinus Torvalds 	{
1721da177e4SLinus Torvalds 	    fprintf(stderr,
1731da177e4SLinus Torvalds 		    "%s: Bad end of range (0x%x)\n",
1741da177e4SLinus Torvalds 		    tblname, fp1);
1751da177e4SLinus Torvalds 	    exit(EX_DATAERR);
1761da177e4SLinus Torvalds 	}
1771da177e4SLinus Torvalds 
1781da177e4SLinus Torvalds       if (fp1)
1791da177e4SLinus Torvalds 	{
1801da177e4SLinus Torvalds 	  /* we have a range; expect the word "idem" or a Unicode range of the
1811da177e4SLinus Torvalds 	     same length */
1821da177e4SLinus Torvalds 	  while (*p == ' ' || *p == '\t')
1831da177e4SLinus Torvalds 	    p++;
1841da177e4SLinus Torvalds 	  if (!strncmp(p, "idem", 4))
1851da177e4SLinus Torvalds 	    {
1861da177e4SLinus Torvalds 	      for (i=fp0; i<=fp1; i++)
1871da177e4SLinus Torvalds 		addpair(i,i);
1881da177e4SLinus Torvalds 	      p += 4;
1891da177e4SLinus Torvalds 	    }
1901da177e4SLinus Torvalds 	  else
1911da177e4SLinus Torvalds 	    {
1921da177e4SLinus Torvalds 	      un0 = getunicode(&p);
1931da177e4SLinus Torvalds 	      while (*p == ' ' || *p == '\t')
1941da177e4SLinus Torvalds 		p++;
1951da177e4SLinus Torvalds 	      if (*p != '-')
1961da177e4SLinus Torvalds 		{
1971da177e4SLinus Torvalds 		  fprintf(stderr,
1981da177e4SLinus Torvalds "%s: Corresponding to a range of font positions, there should be a Unicode range\n",
1991da177e4SLinus Torvalds 			  tblname);
2001da177e4SLinus Torvalds 		  exit(EX_DATAERR);
2011da177e4SLinus Torvalds 	        }
2021da177e4SLinus Torvalds 	      p++;
2031da177e4SLinus Torvalds 	      un1 = getunicode(&p);
2041da177e4SLinus Torvalds 	      if (un0 < 0 || un1 < 0)
2051da177e4SLinus Torvalds 		{
2061da177e4SLinus Torvalds 		  fprintf(stderr,
2071da177e4SLinus Torvalds "%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
2081da177e4SLinus Torvalds 			  tblname, fp0, fp1);
2091da177e4SLinus Torvalds 		  exit(EX_DATAERR);
2101da177e4SLinus Torvalds 	        }
2111da177e4SLinus Torvalds 	      if (un1 - un0 != fp1 - fp0)
2121da177e4SLinus Torvalds 		{
2131da177e4SLinus Torvalds 		  fprintf(stderr,
2141da177e4SLinus Torvalds "%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
2151da177e4SLinus Torvalds 			  tblname, un0, un1, fp0, fp1);
2161da177e4SLinus Torvalds 		  exit(EX_DATAERR);
2171da177e4SLinus Torvalds 	        }
2181da177e4SLinus Torvalds 	      for(i=fp0; i<=fp1; i++)
2191da177e4SLinus Torvalds 		addpair(i,un0-fp0+i);
2201da177e4SLinus Torvalds 	    }
2211da177e4SLinus Torvalds         }
2221da177e4SLinus Torvalds       else
2231da177e4SLinus Torvalds 	{
2241da177e4SLinus Torvalds 	    /* no range; expect a list of unicode values for a single font position */
2251da177e4SLinus Torvalds 
2261da177e4SLinus Torvalds 	    while ( (un0 = getunicode(&p)) >= 0 )
2271da177e4SLinus Torvalds 	      addpair(fp0, un0);
2281da177e4SLinus Torvalds 	}
2291da177e4SLinus Torvalds       while (*p == ' ' || *p == '\t')
2301da177e4SLinus Torvalds 	p++;
2311da177e4SLinus Torvalds       if (*p && *p != '#')
2321da177e4SLinus Torvalds 	fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
2331da177e4SLinus Torvalds     }
2341da177e4SLinus Torvalds 
2351da177e4SLinus Torvalds   /* Okay, we hit EOF, now output hash table */
2361da177e4SLinus Torvalds 
2371da177e4SLinus Torvalds   fclose(ctbl);
2381da177e4SLinus Torvalds 
2391da177e4SLinus Torvalds 
2401da177e4SLinus Torvalds   /* Compute total size of Unicode list */
2411da177e4SLinus Torvalds   nuni = 0;
2421da177e4SLinus Torvalds   for ( i = 0 ; i < fontlen ; i++ )
2431da177e4SLinus Torvalds     nuni += unicount[i];
2441da177e4SLinus Torvalds 
2451da177e4SLinus Torvalds   printf("\
2461da177e4SLinus Torvalds /*\n\
2471da177e4SLinus Torvalds  * Do not edit this file; it was automatically generated by\n\
2481da177e4SLinus Torvalds  *\n\
2491da177e4SLinus Torvalds  * conmakehash %s > [this file]\n\
2501da177e4SLinus Torvalds  *\n\
2511da177e4SLinus Torvalds  */\n\
2521da177e4SLinus Torvalds \n\
2531da177e4SLinus Torvalds #include <linux/types.h>\n\
2541da177e4SLinus Torvalds \n\
2551da177e4SLinus Torvalds u8 dfont_unicount[%d] = \n\
2561da177e4SLinus Torvalds {\n\t", argv[1], fontlen);
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds   for ( i = 0 ; i < fontlen ; i++ )
2591da177e4SLinus Torvalds     {
2601da177e4SLinus Torvalds       printf("%3d", unicount[i]);
2611da177e4SLinus Torvalds       if ( i == fontlen-1 )
2621da177e4SLinus Torvalds         printf("\n};\n");
2631da177e4SLinus Torvalds       else if ( i % 8 == 7 )
2641da177e4SLinus Torvalds         printf(",\n\t");
2651da177e4SLinus Torvalds       else
2661da177e4SLinus Torvalds         printf(", ");
2671da177e4SLinus Torvalds     }
2681da177e4SLinus Torvalds 
2691da177e4SLinus Torvalds   printf("\nu16 dfont_unitable[%d] = \n{\n\t", nuni);
2701da177e4SLinus Torvalds 
2711da177e4SLinus Torvalds   fp0 = 0;
2721da177e4SLinus Torvalds   nent = 0;
2731da177e4SLinus Torvalds   for ( i = 0 ; i < nuni ; i++ )
2741da177e4SLinus Torvalds     {
2751da177e4SLinus Torvalds       while ( nent >= unicount[fp0] )
2761da177e4SLinus Torvalds 	{
2771da177e4SLinus Torvalds 	  fp0++;
2781da177e4SLinus Torvalds 	  nent = 0;
2791da177e4SLinus Torvalds 	}
2801da177e4SLinus Torvalds       printf("0x%04x", unitable[fp0][nent++]);
2811da177e4SLinus Torvalds       if ( i == nuni-1 )
2821da177e4SLinus Torvalds          printf("\n};\n");
2831da177e4SLinus Torvalds        else if ( i % 8 == 7 )
2841da177e4SLinus Torvalds          printf(",\n\t");
2851da177e4SLinus Torvalds        else
2861da177e4SLinus Torvalds          printf(", ");
2871da177e4SLinus Torvalds     }
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds   exit(EX_OK);
2901da177e4SLinus Torvalds }
291