conmakehash.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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