This source file includes following definitions.
- usage
- getunicode
- addpair
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <sysexits.h>
17 #include <string.h>
18 #include <ctype.h>
19
20 typedef unsigned short unicode;
21
22 struct unipair
23 {
24 unsigned short glyph;
25 unicode uc;
26 };
27
28 void usage(char *argv0)
29 {
30 fprintf(stderr, "Usage: \n"
31 " %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
32 exit(EX_USAGE);
33 }
34
35 int getunicode(char **p0)
36 {
37 char *p = *p0;
38
39 while (*p == ' ' || *p == '\t')
40 p++;
41 if (*p != 'U' || p[1] != '+' ||
42 !isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
43 !isxdigit(p[5]) || isxdigit(p[6]))
44 return -1;
45 *p0 = p+6;
46 return strtol(p+2,0,16);
47 }
48
49 struct unipair *hashtable;
50 int hashsize = 641;
51 int hashstep = 189;
52 int maxhashlevel = 6;
53 int hashlevel = 0;
54
55 void addpair(int fp, int un)
56 {
57 int i, lct;
58 unicode hu;
59
60 if ( un <= 0xFFFE )
61 {
62
63
64 i = un % hashsize;
65 lct = 1;
66
67 while ( (hu = hashtable[i].uc) != 0xffff && hu != un )
68 {
69 if (lct++ >= maxhashlevel)
70 {
71 fprintf(stderr, "ERROR: Hash table overflow\n");
72 exit(EX_DATAERR);
73 }
74 i += hashstep;
75 if ( i >= hashsize )
76 i -= hashsize;
77 }
78 if ( lct > hashlevel )
79 hashlevel = lct;
80
81 hashtable[i].uc = un;
82 hashtable[i].glyph = fp;
83 }
84
85
86 }
87
88 int main(int argc, char *argv[])
89 {
90 FILE *ctbl;
91 char *tblname;
92 char buffer[65536];
93 int fontlen;
94 int i;
95 int fp0, fp1, un0, un1;
96 char *p, *p1;
97
98 if ( argc < 2 || argc > 5 )
99 usage(argv[0]);
100
101 if ( !strcmp(argv[1],"-") )
102 {
103 ctbl = stdin;
104 tblname = "stdin";
105 }
106 else
107 {
108 ctbl = fopen(tblname = argv[1], "r");
109 if ( !ctbl )
110 {
111 perror(tblname);
112 exit(EX_NOINPUT);
113 }
114 }
115
116 if ( argc > 2 )
117 {
118 hashsize = atoi(argv[2]);
119 if ( hashsize < 256 || hashsize > 2048 )
120 {
121 fprintf(stderr, "Illegal hash size\n");
122 exit(EX_USAGE);
123 }
124 }
125
126 if ( argc > 3 )
127 {
128 hashstep = atoi(argv[3]) % hashsize;
129 if ( hashstep < 0 ) hashstep += hashsize;
130 if ( hashstep < 16 || hashstep >= hashsize-16 )
131 {
132 fprintf(stderr, "Bad hash step\n");
133 exit(EX_USAGE);
134 }
135 }
136
137
138
139
140 for ( i = hashstep ; i > 1 ; i-- )
141 {
142 if ( hashstep % i == 0 && hashsize % i == 0 )
143 break;
144 }
145
146 if ( i > 1 )
147 {
148 fprintf(stderr,
149 "WARNING: hashsize and hashstep have common factors (gcd = %d)\n", i);
150 }
151
152 if ( argc > 4 )
153 {
154 maxhashlevel = atoi(argv[4]);
155 if ( maxhashlevel < 1 || maxhashlevel > hashsize )
156 {
157 fprintf(stderr, "Illegal max hash level\n");
158 exit(EX_USAGE);
159 }
160 }
161
162
163 fontlen = 256;
164
165
166
167 hashtable = malloc(hashsize * sizeof(struct unipair));
168 if ( !hashtable )
169 {
170 fprintf(stderr, "Could not allocate memory for hash table\n");
171 exit(EX_OSERR);
172 }
173
174 for ( i = 0 ; i < hashsize ; i++ )
175 {
176 hashtable[i].uc = 0xffff;
177 hashtable[i].glyph = 0;
178 }
179
180
181
182 while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
183 {
184 if ( (p = strchr(buffer, '\n')) != NULL )
185 *p = '\0';
186 else
187 fprintf(stderr, "%s: Warning: line too long\n", tblname);
188
189 p = buffer;
190
191
192
193
194
195
196
197
198
199
200
201
202 while (*p == ' ' || *p == '\t')
203 p++;
204 if (!*p || *p == '#')
205 continue;
206
207 fp0 = strtol(p, &p1, 0);
208 if (p1 == p)
209 {
210 fprintf(stderr, "Bad input line: %s\n", buffer);
211 exit(EX_DATAERR);
212 }
213 p = p1;
214
215 while (*p == ' ' || *p == '\t')
216 p++;
217 if (*p == '-')
218 {
219 p++;
220 fp1 = strtol(p, &p1, 0);
221 if (p1 == p)
222 {
223 fprintf(stderr, "Bad input line: %s\n", buffer);
224 exit(EX_DATAERR);
225 }
226 p = p1;
227 }
228 else
229 fp1 = 0;
230
231 if ( fp0 < 0 || fp0 >= fontlen )
232 {
233 fprintf(stderr,
234 "%s: Glyph number (0x%x) larger than font length\n",
235 tblname, fp0);
236 exit(EX_DATAERR);
237 }
238 if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
239 {
240 fprintf(stderr,
241 "%s: Bad end of range (0x%x)\n",
242 tblname, fp1);
243 exit(EX_DATAERR);
244 }
245
246 if (fp1)
247 {
248
249
250 while (*p == ' ' || *p == '\t')
251 p++;
252 if (!strncmp(p, "idem", 4))
253 {
254 for (i=fp0; i<=fp1; i++)
255 addpair(i,i);
256 p += 4;
257 }
258 else
259 {
260 un0 = getunicode(&p);
261 while (*p == ' ' || *p == '\t')
262 p++;
263 if (*p != '-')
264 {
265 fprintf(stderr,
266 "%s: Corresponding to a range of font positions, there should be a Unicode range\n",
267 tblname);
268 exit(EX_DATAERR);
269 }
270 p++;
271 un1 = getunicode(&p);
272 if (un0 < 0 || un1 < 0)
273 {
274 fprintf(stderr,
275 "%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
276 tblname, fp0, fp1);
277 exit(EX_DATAERR);
278 }
279 if (un1 - un0 != fp1 - fp0)
280 {
281 fprintf(stderr,
282 "%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
283 tblname, un0, un1, fp0, fp1);
284 exit(EX_DATAERR);
285 }
286 for(i=fp0; i<=fp1; i++)
287 addpair(i,un0-fp0+i);
288 }
289 }
290 else
291 {
292
293
294 while ( (un0 = getunicode(&p)) >= 0 )
295 addpair(fp0, un0);
296 }
297 while (*p == ' ' || *p == '\t')
298 p++;
299 if (*p && *p != '#')
300 fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
301 }
302
303
304
305 fclose(ctbl);
306
307 printf("\
308 /*\n\
309 * uni_hash_tbl.h\n\
310 *\n\
311 * Do not edit this file; it was automatically generated by\n\
312 *\n\
313 * conmakehash %s %d %d %d > uni_hash_tbl.h\n\
314 *\n\
315 */\n\
316 \n\
317 #include <linux/kd.h>\n\
318 \n\
319 #define HASHSIZE %d\n\
320 #define HASHSTEP %d\n\
321 #define MAXHASHLEVEL %d\n\
322 #define DEF_HASHLEVEL %d\n\
323 \n\
324 static unsigned int hashsize = HASHSIZE;\n\
325 static unsigned int hashstep = HASHSTEP;\n\
326 static unsigned int maxhashlevel = MAXHASHLEVEL;\n\
327 static unsigned int hashlevel = DEF_HASHLEVEL;\n\
328 \n\
329 static struct unipair hashtable[HASHSIZE] =\n\
330 {\n\t", argv[1], hashsize, hashstep, maxhashlevel,
331 hashsize, hashstep, maxhashlevel, hashlevel);
332
333 for ( i = 0 ; i < hashsize ; i++ )
334 {
335 printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph);
336 if ( i == hashsize-1 )
337 printf("\n};\n");
338 else if ( i % 4 == 3 )
339 printf(",\n\t");
340 else
341 printf(", ");
342 }
343
344 printf("\n\
345 #ifdef NEED_BACKUP_HASHTABLE\n\
346 \n\
347 static const struct unipair backup_hashtable[HASHSIZE] = \n{\n\t");
348
349 for ( i = 0 ; i < hashsize ; i++ )
350 {
351 printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph);
352 if ( i == hashsize-1 )
353 printf("\n};\n#endif\n");
354 else if ( i % 4 == 3 )
355 printf(",\n\t");
356 else
357 printf(", ");
358 }
359
360 exit(EX_OK);
361 }