The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/scripts/conmakehash.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 1a7c81346fab91640058f66b38892cbf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.