patch-1.3.28 linux/drivers/char/conmakehash.c

Next file: linux/drivers/char/console.c
Previous file: linux/drivers/char/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.27/linux/drivers/char/conmakehash.c linux/drivers/char/conmakehash.c
@@ -1,14 +1,17 @@
 /*
  * conmakehash.c
  *
- * Create a pre-initialized kernel Unicode hash table
+ * Create arrays for initializing the kernel folded tables (using a hash
+ * table turned out to be to limiting...)  Unfortunately we can't simply
+ * preinitialize the tables at compile time since kfree() cannot accept
+ * memory not allocated by kmalloc(), and doing our own memory management
+ * just for this seems like massive overkill.
  *
  * Copyright (C) 1995 H. Peter Anvin
  *
- * This program may be freely copied under the terms of the GNU
- * General Public License (GPL), version 2, or at your option
- * any later version.
- *
+ * This program is a part of the Linux kernel, and may be freely
+ * copied under the terms of the GNU General Public License (GPL),
+ * version 2, or at your option any later version.
  */
 
 #include <stdio.h>
@@ -17,13 +20,9 @@
 #include <string.h>
 #include <ctype.h>
 
-typedef unsigned short unicode;
+#define MAX_FONTLEN 256
 
-struct unipair
-{
-  unsigned short glyph;		/* Glyph code */
-  unicode uc;			/* Unicode listed */
-};
+typedef unsigned short unicode;
 
 void usage(char *argv0)
 {
@@ -46,40 +45,33 @@
   return strtol(p+2,0,16);
 }
 
-struct unipair *hashtable;
-int hashsize = 641;		/* Size of hash table */
-int hashstep = 189;		/* Hash stepping */
-int maxhashlevel = 6;		/* Maximum hash depth */
-int hashlevel = 0;		/* Actual hash depth */
+unicode unitable[MAX_FONTLEN][255];
+				/* Massive overkill, but who cares? */
+int unicount[MAX_FONTLEN];
 
 void addpair(int fp, int un)
 {
-  int i, lct;
+  int i;
   unicode hu;
 
-  if ( un <= 0xFFFE )
+  if ( un <= 0xfffe )
     {
-      /* Add to hash table */
+      /* Check it isn't a duplicate */
+
+      for ( i = 0 ; i < unicount[fp] ; i++ )
+	if ( unitable[fp][i] == un )
+	  return;
+
+      /* Add to list */
 
-      i = un % hashsize;
-      lct = 1;
-      
-      while ( (hu = hashtable[i].uc) != 0xffff && hu != un )
+      if ( unicount[fp] > 254 )
 	{
-	  if (lct++ >= maxhashlevel)
-	    {
-	      fprintf(stderr, "ERROR: Hash table overflow\n");
-	      exit(EX_DATAERR);
-	    }
-	  i += hashstep;
-	  if ( i >= hashsize )
-	    i -= hashsize;
+	  fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n");
+	  exit(EX_DATAERR);
 	}
-      if ( lct > hashlevel )
-	hashlevel = lct;
 
-      hashtable[i].uc = un;
-      hashtable[i].glyph = fp;
+      unitable[fp][unicount[fp]] = un;
+      unicount[fp]++;
     }
 
   /* otherwise: ignore */
@@ -91,7 +83,7 @@
   char *tblname;
   char buffer[65536];
   int fontlen;
-  int i;
+  int i, nuni, nent;
   int fp0, fp1, un0, un1;
   char *p, *p1;
 
@@ -113,69 +105,13 @@
 	}
     }
 
-  if ( argc > 2 )
-    {
-      hashsize = atoi(argv[2]);
-      if ( hashsize < 256 || hashsize > 2048 )
-	{
-	  fprintf(stderr, "Illegal hash size\n");
-	  exit(EX_USAGE);
-	}
-    }
-  
-  if ( argc > 3 )
-    {
-      hashstep = atoi(argv[3]) % hashsize;
-      if ( hashstep < 0 ) hashstep += hashsize;
-      if ( hashstep < 16 || hashstep >= hashsize-16 )
-	{
-	  fprintf(stderr, "Bad hash step\n");
-	  exit(EX_USAGE);
-	}
-    }
-
-  /* Warn the user in case the hashstep and hashsize are not relatively
-     prime -- this algorithm could be massively improved */
-
-  for ( i = hashstep ; i > 1 ; i-- )
-    {
-      if ( hashstep % i == 0 && hashsize % i == 0 )
-	break;			/* Found GCD */
-    }
-
-  if ( i > 1 )
-    {
-      fprintf(stderr,
-      "WARNING: hashsize and hashstep have common factors (gcd = %d)\n", i);
-    }
-
-  if ( argc > 4 )
-    {
-      maxhashlevel = atoi(argv[4]);
-      if ( maxhashlevel < 1 || maxhashlevel > hashsize )
-	{
-	  fprintf(stderr, "Illegal max hash level\n");
-	  exit(EX_USAGE);
-	}
-    }
-
-  /* For now we assume the default font is always 256 characters */
+  /* For now we assume the default font is always 256 characters. */    
   fontlen = 256;
 
-  /* Initialize hash table */
-
-  hashtable = malloc(hashsize * sizeof(struct unipair));
-  if ( !hashtable )
-    {
-      fprintf(stderr, "Could not allocate memory for hash table\n");
-      exit(EX_OSERR);
-    }
+  /* Initialize table */
 
-  for ( i = 0 ; i < hashsize ; i++ )
-    {
-      hashtable[i].uc = 0xffff;
-      hashtable[i].glyph = 0;
-    }
+  for ( i = 0 ; i < fontlen ; i++ )
+    unicount[i] = 0;
 
   /* Now we come to the tricky part.  Parse the input table. */
 
@@ -304,57 +240,57 @@
   
   fclose(ctbl);
   
+
+  /* Compute total size of Unicode list */
+  nuni = 0;
+  for ( i = 0 ; i < fontlen ; i++ )
+    nuni += unicount[i];
+  
   printf("\
 /*\n\
  * uni_hash.tbl\n\
  *\n\
  * Do not edit this file; it was automatically generated by\n\
  *\n\
- * conmakehash %s %d %d %d > uni_hash.tbl\n\
+ * conmakehash %s > uni_hash.tbl\n\
  *\n\
  */\n\
 \n\
+#include <linux/types.h>\n\
 #include <linux/kd.h>\n\
 \n\
-#define HASHSIZE      %d\n\
-#define HASHSTEP      %d\n\
-#define MAXHASHLEVEL  %d\n\
-#define DEF_HASHLEVEL %d\n\
-\n\
-static unsigned int hashsize     = HASHSIZE;\n\
-static unsigned int hashstep     = HASHSTEP;\n\
-static unsigned int maxhashlevel = MAXHASHLEVEL;\n\
-static unsigned int hashlevel    = DEF_HASHLEVEL;\n\
-\n\
-static struct unipair hashtable[HASHSIZE] =\n\
-{\n\t", argv[1], hashsize, hashstep, maxhashlevel,
-	 hashsize, hashstep, maxhashlevel, hashlevel);
-  
-  for ( i = 0 ; i < hashsize ; i++ )
+static u8 dfont_unicount[%d] = \n\
+{\n\t", argv[1], fontlen);
+
+  for ( i = 0 ; i < fontlen ; i++ )
     {
-      printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph);
-      if ( i == hashsize-1 )
-	printf("\n};\n");
-      else if ( i % 4 == 3 )
-	printf(",\n\t");
+      printf("%3d", unicount[i]);
+      if ( i == fontlen-1 )
+        printf("\n};\n");
+      else if ( i % 8 == 7 )
+        printf(",\n\t");
       else
-	printf(", ");
+        printf(", ");
     }
 
-  printf("\n\
-#ifdef NEED_BACKUP_HASHTABLE\n\
-\n\
-static const struct unipair backup_hashtable[HASHSIZE] = \n{\n\t");
- 
-  for ( i = 0 ; i < hashsize ; i++ )
-    {
-      printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph);
-      if ( i == hashsize-1 )
-	printf("\n};\n#endif\n");
-      else if ( i % 4 == 3 )
-	printf(",\n\t");
-      else
-	printf(", ");
+  printf("\nstatic u16 dfont_unitable[%d] = \n{\n\t", nuni);
+
+  fp0 = 0;
+  nent = 0;
+  for ( i = 0 ; i < nuni ; i++ )
+    {
+       while ( nent >= unicount[fp0] )
+         {
+            fp0++;
+            nent = 0;
+         }
+       printf("0x%04x", unitable[fp0][nent++]);
+       if ( i == nuni-1 )
+         printf("\n};");
+       else if ( i % 8 == 7 )
+         printf(",\n\t");
+       else
+         printf(", ");
     }
 
   exit(EX_OK);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this