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