root/drivers/char/conmakehash.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usage
  2. getunicode
  3. addpair
  4. main

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

/* [<][>][^][v][top][bottom][index][help] */