0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <stdio.h>
0015 #include <stdlib.h>
0016 #include <sysexits.h>
0017 #include <string.h>
0018 #include <ctype.h>
0019
0020 #define MAX_FONTLEN 256
0021
0022 typedef unsigned short unicode;
0023
0024 static void usage(char *argv0)
0025 {
0026 fprintf(stderr, "Usage: \n"
0027 " %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
0028 exit(EX_USAGE);
0029 }
0030
0031 static int getunicode(char **p0)
0032 {
0033 char *p = *p0;
0034
0035 while (*p == ' ' || *p == '\t')
0036 p++;
0037 if (*p != 'U' || p[1] != '+' ||
0038 !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
0039 !isxdigit(p[5]) || isxdigit(p[6]))
0040 return -1;
0041 *p0 = p+6;
0042 return strtol(p+2,0,16);
0043 }
0044
0045 unicode unitable[MAX_FONTLEN][255];
0046
0047 int unicount[MAX_FONTLEN];
0048
0049 static void addpair(int fp, int un)
0050 {
0051 int i;
0052
0053 if ( un <= 0xfffe )
0054 {
0055
0056
0057 for ( i = 0 ; i < unicount[fp] ; i++ )
0058 if ( unitable[fp][i] == un )
0059 return;
0060
0061
0062
0063 if ( unicount[fp] > 254 )
0064 {
0065 fprintf(stderr, "ERROR: Only 255 unicodes/glyph permitted!\n");
0066 exit(EX_DATAERR);
0067 }
0068
0069 unitable[fp][unicount[fp]] = un;
0070 unicount[fp]++;
0071 }
0072
0073
0074 }
0075
0076 int main(int argc, char *argv[])
0077 {
0078 FILE *ctbl;
0079 char *tblname;
0080 char buffer[65536];
0081 int fontlen;
0082 int i, nuni, nent;
0083 int fp0, fp1, un0, un1;
0084 char *p, *p1;
0085
0086 if ( argc < 2 || argc > 5 )
0087 usage(argv[0]);
0088
0089 if ( !strcmp(argv[1],"-") )
0090 {
0091 ctbl = stdin;
0092 tblname = "stdin";
0093 }
0094 else
0095 {
0096 ctbl = fopen(tblname = argv[1], "r");
0097 if ( !ctbl )
0098 {
0099 perror(tblname);
0100 exit(EX_NOINPUT);
0101 }
0102 }
0103
0104
0105 fontlen = 256;
0106
0107
0108
0109 for ( i = 0 ; i < fontlen ; i++ )
0110 unicount[i] = 0;
0111
0112
0113
0114 while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
0115 {
0116 if ( (p = strchr(buffer, '\n')) != NULL )
0117 *p = '\0';
0118 else
0119 fprintf(stderr, "%s: Warning: line too long\n", tblname);
0120
0121 p = buffer;
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 while (*p == ' ' || *p == '\t')
0135 p++;
0136 if (!*p || *p == '#')
0137 continue;
0138
0139 fp0 = strtol(p, &p1, 0);
0140 if (p1 == p)
0141 {
0142 fprintf(stderr, "Bad input line: %s\n", buffer);
0143 exit(EX_DATAERR);
0144 }
0145 p = p1;
0146
0147 while (*p == ' ' || *p == '\t')
0148 p++;
0149 if (*p == '-')
0150 {
0151 p++;
0152 fp1 = strtol(p, &p1, 0);
0153 if (p1 == p)
0154 {
0155 fprintf(stderr, "Bad input line: %s\n", buffer);
0156 exit(EX_DATAERR);
0157 }
0158 p = p1;
0159 }
0160 else
0161 fp1 = 0;
0162
0163 if ( fp0 < 0 || fp0 >= fontlen )
0164 {
0165 fprintf(stderr,
0166 "%s: Glyph number (0x%x) larger than font length\n",
0167 tblname, fp0);
0168 exit(EX_DATAERR);
0169 }
0170 if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
0171 {
0172 fprintf(stderr,
0173 "%s: Bad end of range (0x%x)\n",
0174 tblname, fp1);
0175 exit(EX_DATAERR);
0176 }
0177
0178 if (fp1)
0179 {
0180
0181
0182 while (*p == ' ' || *p == '\t')
0183 p++;
0184 if (!strncmp(p, "idem", 4))
0185 {
0186 for (i=fp0; i<=fp1; i++)
0187 addpair(i,i);
0188 p += 4;
0189 }
0190 else
0191 {
0192 un0 = getunicode(&p);
0193 while (*p == ' ' || *p == '\t')
0194 p++;
0195 if (*p != '-')
0196 {
0197 fprintf(stderr,
0198 "%s: Corresponding to a range of font positions, there should be a Unicode range\n",
0199 tblname);
0200 exit(EX_DATAERR);
0201 }
0202 p++;
0203 un1 = getunicode(&p);
0204 if (un0 < 0 || un1 < 0)
0205 {
0206 fprintf(stderr,
0207 "%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
0208 tblname, fp0, fp1);
0209 exit(EX_DATAERR);
0210 }
0211 if (un1 - un0 != fp1 - fp0)
0212 {
0213 fprintf(stderr,
0214 "%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
0215 tblname, un0, un1, fp0, fp1);
0216 exit(EX_DATAERR);
0217 }
0218 for(i=fp0; i<=fp1; i++)
0219 addpair(i,un0-fp0+i);
0220 }
0221 }
0222 else
0223 {
0224
0225
0226 while ( (un0 = getunicode(&p)) >= 0 )
0227 addpair(fp0, un0);
0228 }
0229 while (*p == ' ' || *p == '\t')
0230 p++;
0231 if (*p && *p != '#')
0232 fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
0233 }
0234
0235
0236
0237 fclose(ctbl);
0238
0239
0240
0241 nuni = 0;
0242 for ( i = 0 ; i < fontlen ; i++ )
0243 nuni += unicount[i];
0244
0245 printf("\
0246 /*\n\
0247 * Do not edit this file; it was automatically generated by\n\
0248 *\n\
0249 * conmakehash %s > [this file]\n\
0250 *\n\
0251 */\n\
0252 \n\
0253 #include <linux/types.h>\n\
0254 \n\
0255 u8 dfont_unicount[%d] = \n\
0256 {\n\t", argv[1], fontlen);
0257
0258 for ( i = 0 ; i < fontlen ; i++ )
0259 {
0260 printf("%3d", unicount[i]);
0261 if ( i == fontlen-1 )
0262 printf("\n};\n");
0263 else if ( i % 8 == 7 )
0264 printf(",\n\t");
0265 else
0266 printf(", ");
0267 }
0268
0269 printf("\nu16 dfont_unitable[%d] = \n{\n\t", nuni);
0270
0271 fp0 = 0;
0272 nent = 0;
0273 for ( i = 0 ; i < nuni ; i++ )
0274 {
0275 while ( nent >= unicount[fp0] )
0276 {
0277 fp0++;
0278 nent = 0;
0279 }
0280 printf("0x%04x", unitable[fp0][nent++]);
0281 if ( i == nuni-1 )
0282 printf("\n};\n");
0283 else if ( i % 8 == 7 )
0284 printf(",\n\t");
0285 else
0286 printf(", ");
0287 }
0288
0289 exit(EX_OK);
0290 }