yacc.y revision 1.12 1 /* $NetBSD: yacc.y,v 1.12 2003/03/03 08:30:21 tshiozak Exp $ */
2
3 %{
4 /*-
5 * Copyright (c) 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Paul Borman at Krystal Technologies.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40 #if HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43
44 #include <sys/cdefs.h>
45 #if defined(LIBC_SCCS) && !defined(lint)
46 #if 0
47 static char sccsid[] = "@(#)yacc.y 8.1 (Berkeley) 6/6/93";
48 static char rcsid[] = "$FreeBSD$";
49 #else
50 __RCSID("$NetBSD: yacc.y,v 1.12 2003/03/03 08:30:21 tshiozak Exp $");
51 #endif
52 #endif /* LIBC_SCCS and not lint */
53
54 #include <sys/types.h>
55 #include <netinet/in.h> /* Needed by <arpa/inet.h> on NetBSD 1.5. */
56 #include <arpa/inet.h> /* Needed for htonl on POSIX systems. */
57
58 #if defined(__FreeBSD__)
59 #define _DONT_USE_CTYPE_INLINE_
60 #endif
61 #include <ctype.h>
62 #include <err.h>
63 #if !defined(__FreeBSD__)
64 #define _BSD_RUNE_T_ int
65 #define _BSD_CT_RUNE_T_ rune_t
66 #include "rune.h"
67 #else
68 #include <rune.h>
69 #endif
70 #include <stddef.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include <string.h>
74 #include <unistd.h>
75
76 #include "ldef.h"
77
78 const char *locale_file = "<stdout>";
79
80 rune_map maplower = { { 0, }, };
81 rune_map mapupper = { { 0, }, };
82 rune_map types = { { 0, }, };
83
84 _RuneLocale new_locale = { { 0, }, };
85
86 rune_t charsetbits = (rune_t)0x00000000;
87 #if 0
88 rune_t charsetmask = (rune_t)0x0000007f;
89 #endif
90 rune_t charsetmask = (rune_t)0xffffffff;
91
92 void set_map __P((rune_map *, rune_list *, u_int32_t));
93 void set_digitmap __P((rune_map *, rune_list *));
94 void add_map __P((rune_map *, rune_list *, u_int32_t));
95
96 int main __P((int, char *[]));
97 int yyerror __P((const char *s));
98 void *xmalloc __P((unsigned int sz));
99 u_int32_t *xlalloc __P((unsigned int sz));
100 u_int32_t *xrelalloc __P((u_int32_t *old, unsigned int sz));
101 void dump_tables __P((void));
102 int yyparse __P((void));
103 extern int yylex __P((void));
104 %}
105
106 %union {
107 rune_t rune;
108 int i;
109 char *str;
110
111 rune_list *list;
112 }
113
114 %token <rune> RUNE
115 %token LBRK
116 %token RBRK
117 %token THRU
118 %token MAPLOWER
119 %token MAPUPPER
120 %token DIGITMAP
121 %token <i> LIST
122 %token <str> VARIABLE
123 %token CHARSET
124 %token ENCODING
125 %token INVALID
126 %token <str> STRING
127
128 %type <list> list
129 %type <list> map
130
131
132 %%
133
134 locale : /* empty */
135 | table
136 { dump_tables(); }
137 ;
138
139 table : entry
140 | table entry
141 ;
142
143 entry : ENCODING STRING
144 { strncpy(new_locale.rl_encoding, $2, sizeof(new_locale.rl_encoding)); }
145 | VARIABLE
146 { new_locale.rl_variable_len = strlen($1) + 1;
147 new_locale.rl_variable =
148 malloc(new_locale.rl_variable_len);
149 strcpy((char *)new_locale.rl_variable, $1);
150 }
151 | CHARSET RUNE
152 { charsetbits = $2; charsetmask = 0x0000007f; }
153 | CHARSET RUNE RUNE
154 { charsetbits = $2; charsetmask = $3; }
155 | CHARSET STRING
156 { int final = $2[strlen($2) - 1] & 0x7f;
157 charsetbits = final << 24;
158 if ($2[0] == '$') {
159 charsetmask = 0x00007f7f;
160 if (strchr(",-./", $2[1]))
161 charsetbits |= 0x80;
162 if (0xd0 <= final && final <= 0xdf)
163 charsetmask |= 0x007f0000;
164 } else {
165 charsetmask = 0x0000007f;
166 if (strchr(",-./", $2[0]))
167 charsetbits |= 0x80;
168 if (strlen($2) == 2 && $2[0] == '!')
169 charsetbits |= ((0x80 | $2[0]) << 16);
170 }
171
172 /*
173 * special rules
174 */
175 if (charsetbits == ('B' << 24)
176 && charsetmask == 0x0000007f) {
177 /*ASCII: 94B*/
178 charsetbits = 0;
179 charsetmask = 0x0000007f;
180 } else if (charsetbits == (('A' << 24) | 0x80)
181 && charsetmask == 0x0000007f) {
182 /*Latin1: 96A*/
183 charsetbits = 0x80;
184 charsetmask = 0x0000007f;
185 }
186 }
187 | INVALID RUNE
188 { new_locale.rl_invalid_rune = $2; }
189 | LIST list
190 { set_map(&types, $2, $1); }
191 | MAPLOWER map
192 { set_map(&maplower, $2, 0); }
193 | MAPUPPER map
194 { set_map(&mapupper, $2, 0); }
195 | DIGITMAP map
196 { set_digitmap(&types, $2); }
197 ;
198
199 list : RUNE
200 {
201 $$ = (rune_list *)malloc(sizeof(rune_list));
202 $$->min = ($1 & charsetmask) | charsetbits;
203 $$->max = ($1 & charsetmask) | charsetbits;
204 $$->next = 0;
205 }
206 | RUNE THRU RUNE
207 {
208 $$ = (rune_list *)malloc(sizeof(rune_list));
209 $$->min = ($1 & charsetmask) | charsetbits;
210 $$->max = ($3 & charsetmask) | charsetbits;
211 $$->next = 0;
212 }
213 | list RUNE
214 {
215 $$ = (rune_list *)malloc(sizeof(rune_list));
216 $$->min = ($2 & charsetmask) | charsetbits;
217 $$->max = ($2 & charsetmask) | charsetbits;
218 $$->next = $1;
219 }
220 | list RUNE THRU RUNE
221 {
222 $$ = (rune_list *)malloc(sizeof(rune_list));
223 $$->min = ($2 & charsetmask) | charsetbits;
224 $$->max = ($4 & charsetmask) | charsetbits;
225 $$->next = $1;
226 }
227 ;
228
229 map : LBRK RUNE RUNE RBRK
230 {
231 $$ = (rune_list *)malloc(sizeof(rune_list));
232 $$->min = ($2 & charsetmask) | charsetbits;
233 $$->max = ($2 & charsetmask) | charsetbits;
234 $$->map = $3;
235 $$->next = 0;
236 }
237 | map LBRK RUNE RUNE RBRK
238 {
239 $$ = (rune_list *)malloc(sizeof(rune_list));
240 $$->min = ($3 & charsetmask) | charsetbits;
241 $$->max = ($3 & charsetmask) | charsetbits;
242 $$->map = $4;
243 $$->next = $1;
244 }
245 | LBRK RUNE THRU RUNE ':' RUNE RBRK
246 {
247 $$ = (rune_list *)malloc(sizeof(rune_list));
248 $$->min = ($2 & charsetmask) | charsetbits;
249 $$->max = ($4 & charsetmask) | charsetbits;
250 $$->map = $6;
251 $$->next = 0;
252 }
253 | map LBRK RUNE THRU RUNE ':' RUNE RBRK
254 {
255 $$ = (rune_list *)malloc(sizeof(rune_list));
256 $$->min = ($3 & charsetmask) | charsetbits;
257 $$->max = ($5 & charsetmask) | charsetbits;
258 $$->map = $7;
259 $$->next = $1;
260 }
261 ;
262 %%
263
264 int debug = 0;
265 FILE *ofile;
266
267 int
268 main(ac, av)
269 int ac;
270 char *av[];
271 {
272 int x;
273
274 extern char *optarg;
275 extern int optind;
276
277 while ((x = getopt(ac, av, "do:")) != EOF) {
278 switch(x) {
279 case 'd':
280 debug = 1;
281 break;
282 case 'o':
283 locale_file = optarg;
284 if ((ofile = fopen(locale_file, "w")) == 0)
285 err(1, "unable to open output file %s", locale_file);
286 break;
287 default:
288 usage:
289 fprintf(stderr, "Usage: mklocale [-d] [-o output] [source]\n");
290 exit(1);
291 }
292 }
293
294 switch (ac - optind) {
295 case 0:
296 break;
297 case 1:
298 if (freopen(av[optind], "r", stdin) == 0)
299 err(1, "unable to open input file %s", av[optind]);
300 break;
301 default:
302 goto usage;
303 }
304 for (x = 0; x < _CACHED_RUNES; ++x) {
305 mapupper.map[x] = x;
306 maplower.map[x] = x;
307 }
308 new_locale.rl_invalid_rune = _DEFAULT_INVALID_RUNE;
309 memcpy(new_locale.rl_magic, _RUNE_MAGIC_1, sizeof(new_locale.rl_magic));
310
311 yyparse();
312
313 return 0;
314 }
315
316 int
317 yyerror(s)
318 const char *s;
319 {
320 fprintf(stderr, "%s\n", s);
321
322 return 0;
323 }
324
325 void *
326 xmalloc(sz)
327 unsigned int sz;
328 {
329 void *r = malloc(sz);
330 if (!r) {
331 perror("xmalloc");
332 abort();
333 }
334 return(r);
335 }
336
337 u_int32_t *
338 xlalloc(sz)
339 unsigned int sz;
340 {
341 u_int32_t *r = (u_int32_t *)malloc(sz * sizeof(u_int32_t));
342 if (!r) {
343 perror("xlalloc");
344 abort();
345 }
346 return(r);
347 }
348
349 u_int32_t *
350 xrelalloc(old, sz)
351 u_int32_t *old;
352 unsigned int sz;
353 {
354 u_int32_t *r = (u_int32_t *)realloc((char *)old,
355 sz * sizeof(u_int32_t));
356 if (!r) {
357 perror("xrelalloc");
358 abort();
359 }
360 return(r);
361 }
362
363 void
364 set_map(map, list, flag)
365 rune_map *map;
366 rune_list *list;
367 u_int32_t flag;
368 {
369 list->map &= charsetmask;
370 list->map |= charsetbits;
371 while (list) {
372 rune_list *nlist = list->next;
373 add_map(map, list, flag);
374 list = nlist;
375 }
376 }
377
378 void
379 set_digitmap(map, list)
380 rune_map *map;
381 rune_list *list;
382 {
383 rune_t i;
384
385 while (list) {
386 rune_list *nlist = list->next;
387 for (i = list->min; i <= list->max; ++i) {
388 if (list->map + (i - list->min)) {
389 rune_list *tmp = (rune_list *)xmalloc(sizeof(rune_list));
390 tmp->min = i;
391 tmp->max = i;
392 add_map(map, tmp, list->map + (i - list->min));
393 }
394 }
395 free(list);
396 list = nlist;
397 }
398 }
399
400 void
401 add_map(map, list, flag)
402 rune_map *map;
403 rune_list *list;
404 u_int32_t flag;
405 {
406 rune_t i;
407 rune_list *lr = 0;
408 rune_list *r;
409 rune_t run;
410
411 while (list->min < _CACHED_RUNES && list->min <= list->max) {
412 if (flag)
413 map->map[list->min++] |= flag;
414 else
415 map->map[list->min++] = list->map++;
416 }
417
418 if (list->min > list->max) {
419 free(list);
420 return;
421 }
422
423 run = list->max - list->min + 1;
424
425 if (!(r = map->root) || (list->max < r->min - 1)
426 || (!flag && list->max == r->min - 1)) {
427 if (flag) {
428 list->types = xlalloc(run);
429 for (i = 0; i < run; ++i)
430 list->types[i] = flag;
431 }
432 list->next = map->root;
433 map->root = list;
434 return;
435 }
436
437 for (r = map->root; r && r->max + 1 < list->min; r = r->next)
438 lr = r;
439
440 if (!r) {
441 /*
442 * We are off the end.
443 */
444 if (flag) {
445 list->types = xlalloc(run);
446 for (i = 0; i < run; ++i)
447 list->types[i] = flag;
448 }
449 list->next = 0;
450 lr->next = list;
451 return;
452 }
453
454 if (list->max < r->min - 1) {
455 /*
456 * We come before this range and we do not intersect it.
457 * We are not before the root node, it was checked before the loop
458 */
459 if (flag) {
460 list->types = xlalloc(run);
461 for (i = 0; i < run; ++i)
462 list->types[i] = flag;
463 }
464 list->next = lr->next;
465 lr->next = list;
466 return;
467 }
468
469 /*
470 * At this point we have found that we at least intersect with
471 * the range pointed to by `r', we might intersect with one or
472 * more ranges beyond `r' as well.
473 */
474
475 if (!flag && list->map - list->min != r->map - r->min) {
476 /*
477 * There are only two cases when we are doing case maps and
478 * our maps needn't have the same offset. When we are adjoining
479 * but not intersecting.
480 */
481 if (list->max + 1 == r->min) {
482 lr->next = list;
483 list->next = r;
484 return;
485 }
486 if (list->min - 1 == r->max) {
487 list->next = r->next;
488 r->next = list;
489 return;
490 }
491 fprintf(stderr, "Error: conflicting map entries\n");
492 exit(1);
493 }
494
495 if (list->min >= r->min && list->max <= r->max) {
496 /*
497 * Subset case.
498 */
499
500 if (flag) {
501 for (i = list->min; i <= list->max; ++i)
502 r->types[i - r->min] |= flag;
503 }
504 free(list);
505 return;
506 }
507 if (list->min <= r->min && list->max >= r->max) {
508 /*
509 * Superset case. Make him big enough to hold us.
510 * We might need to merge with the guy after him.
511 */
512 if (flag) {
513 list->types = xlalloc(list->max - list->min + 1);
514
515 for (i = list->min; i <= list->max; ++i)
516 list->types[i - list->min] = flag;
517
518 for (i = r->min; i <= r->max; ++i)
519 list->types[i - list->min] |= r->types[i - r->min];
520
521 free(r->types);
522 r->types = list->types;
523 } else {
524 r->map = list->map;
525 }
526 r->min = list->min;
527 r->max = list->max;
528 free(list);
529 } else if (list->min < r->min) {
530 /*
531 * Our tail intersects his head.
532 */
533 if (flag) {
534 list->types = xlalloc(r->max - list->min + 1);
535
536 for (i = r->min; i <= r->max; ++i)
537 list->types[i - list->min] = r->types[i - r->min];
538
539 for (i = list->min; i < r->min; ++i)
540 list->types[i - list->min] = flag;
541
542 for (i = r->min; i <= list->max; ++i)
543 list->types[i - list->min] |= flag;
544
545 free(r->types);
546 r->types = list->types;
547 } else {
548 r->map = list->map;
549 }
550 r->min = list->min;
551 free(list);
552 return;
553 } else {
554 /*
555 * Our head intersects his tail.
556 * We might need to merge with the guy after him.
557 */
558 if (flag) {
559 r->types = xrelalloc(r->types, list->max - r->min + 1);
560
561 for (i = list->min; i <= r->max; ++i)
562 r->types[i - r->min] |= flag;
563
564 for (i = r->max+1; i <= list->max; ++i)
565 r->types[i - r->min] = flag;
566 }
567 r->max = list->max;
568 free(list);
569 }
570
571 /*
572 * Okay, check to see if we grew into the next guy(s)
573 */
574 while ((lr = r->next) && r->max >= lr->min) {
575 if (flag) {
576 if (r->max >= lr->max) {
577 /*
578 * Good, we consumed all of him.
579 */
580 for (i = lr->min; i <= lr->max; ++i)
581 r->types[i - r->min] |= lr->types[i - lr->min];
582 } else {
583 /*
584 * "append" him on to the end of us.
585 */
586 r->types = xrelalloc(r->types, lr->max - r->min + 1);
587
588 for (i = lr->min; i <= r->max; ++i)
589 r->types[i - r->min] |= lr->types[i - lr->min];
590
591 for (i = r->max+1; i <= lr->max; ++i)
592 r->types[i - r->min] = lr->types[i - lr->min];
593
594 r->max = lr->max;
595 }
596 } else {
597 if (lr->max > r->max)
598 r->max = lr->max;
599 }
600
601 r->next = lr->next;
602
603 if (flag)
604 free(lr->types);
605 free(lr);
606 }
607 }
608
609 void
610 dump_tables()
611 {
612 int x, n;
613 rune_list *list;
614 _FileRuneLocale file_new_locale;
615 FILE *fp = (ofile ? ofile : stdout);
616
617 memset(&file_new_locale, 0, sizeof(file_new_locale));
618
619 /*
620 * See if we can compress some of the istype arrays
621 */
622 for(list = types.root; list; list = list->next) {
623 list->map = list->types[0];
624 for (x = 1; x < list->max - list->min + 1; ++x) {
625 if (list->types[x] != list->map) {
626 list->map = 0;
627 break;
628 }
629 }
630 }
631
632 memcpy(&file_new_locale.frl_magic, new_locale.rl_magic,
633 sizeof(file_new_locale.frl_magic));
634 memcpy(&file_new_locale.frl_encoding, new_locale.rl_encoding,
635 sizeof(file_new_locale.frl_encoding));
636
637 file_new_locale.frl_invalid_rune = htonl(new_locale.rl_invalid_rune);
638
639 /*
640 * Fill in our tables. Do this in network order so that
641 * diverse machines have a chance of sharing data.
642 * (Machines like Crays cannot share with little machines due to
643 * word size. Sigh. We tried.)
644 */
645 for (x = 0; x < _CACHED_RUNES; ++x) {
646 file_new_locale.frl_runetype[x] = htonl(types.map[x]);
647 file_new_locale.frl_maplower[x] = htonl(maplower.map[x]);
648 file_new_locale.frl_mapupper[x] = htonl(mapupper.map[x]);
649 }
650
651 /*
652 * Count up how many ranges we will need for each of the extents.
653 */
654 list = types.root;
655
656 while (list) {
657 new_locale.rl_runetype_ext.rr_nranges++;
658 list = list->next;
659 }
660 file_new_locale.frl_runetype_ext.frr_nranges =
661 htonl(new_locale.rl_runetype_ext.rr_nranges);
662
663 list = maplower.root;
664
665 while (list) {
666 new_locale.rl_maplower_ext.rr_nranges++;
667 list = list->next;
668 }
669 file_new_locale.frl_maplower_ext.frr_nranges =
670 htonl(new_locale.rl_maplower_ext.rr_nranges);
671
672 list = mapupper.root;
673
674 while (list) {
675 new_locale.rl_mapupper_ext.rr_nranges++;
676 list = list->next;
677 }
678 file_new_locale.frl_mapupper_ext.frr_nranges =
679 htonl(new_locale.rl_mapupper_ext.rr_nranges);
680
681 file_new_locale.frl_variable_len = htonl(new_locale.rl_variable_len);
682
683 /*
684 * Okay, we are now ready to write the new locale file.
685 */
686
687 /*
688 * PART 1: The _RuneLocale structure
689 */
690 if (fwrite((char *)&file_new_locale, sizeof(file_new_locale), 1, fp) != 1)
691 err(1, "writing _RuneLocale to %s", locale_file);
692 /*
693 * PART 2: The runetype_ext structures (not the actual tables)
694 */
695 for (list = types.root, n = 0; list != NULL; list = list->next, n++) {
696 _FileRuneEntry re;
697
698 re.fre_min = htonl(list->min);
699 re.fre_max = htonl(list->max);
700 re.fre_map = htonl(list->map);
701
702 if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
703 err(1, "writing runetype_ext #%d to %s", n, locale_file);
704 }
705 /*
706 * PART 3: The maplower_ext structures
707 */
708 for (list = maplower.root, n = 0; list != NULL; list = list->next, n++) {
709 _FileRuneEntry re;
710
711 re.fre_min = htonl(list->min);
712 re.fre_max = htonl(list->max);
713 re.fre_map = htonl(list->map);
714
715 if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
716 err(1, "writing maplower_ext #%d to %s", n, locale_file);
717 }
718 /*
719 * PART 4: The mapupper_ext structures
720 */
721 for (list = mapupper.root, n = 0; list != NULL; list = list->next, n++) {
722 _FileRuneEntry re;
723
724 re.fre_min = htonl(list->min);
725 re.fre_max = htonl(list->max);
726 re.fre_map = htonl(list->map);
727
728 if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
729 err(1, "writing mapupper_ext #%d to %s", n, locale_file);
730 }
731 /*
732 * PART 5: The runetype_ext tables
733 */
734 for (list = types.root, n = 0; list != NULL; list = list->next, n++) {
735 for (x = 0; x < list->max - list->min + 1; ++x)
736 list->types[x] = htonl(list->types[x]);
737
738 if (!list->map) {
739 if (fwrite((char *)list->types,
740 (list->max - list->min + 1) * sizeof(u_int32_t),
741 1, fp) != 1)
742 err(1, "writing runetype_ext table #%d to %s", n, locale_file);
743 }
744 }
745 /*
746 * PART 5: And finally the variable data
747 */
748 if (new_locale.rl_variable_len != 0 &&
749 fwrite((char *)new_locale.rl_variable,
750 new_locale.rl_variable_len, 1, fp) != 1)
751 err(1, "writing variable data to %s", locale_file);
752 fclose(fp);
753
754 if (!debug)
755 return;
756
757 if (new_locale.rl_encoding[0])
758 fprintf(stderr, "ENCODING %s\n", new_locale.rl_encoding);
759 if (new_locale.rl_variable)
760 fprintf(stderr, "VARIABLE %s\n",
761 (char *)new_locale.rl_variable);
762
763 fprintf(stderr, "\nMAPLOWER:\n\n");
764
765 for (x = 0; x < _CACHED_RUNES; ++x) {
766 if (isprint(maplower.map[x]))
767 fprintf(stderr, " '%c'", (int)maplower.map[x]);
768 else if (maplower.map[x])
769 fprintf(stderr, "%04x", maplower.map[x]);
770 else
771 fprintf(stderr, "%4x", 0);
772 if ((x & 0xf) == 0xf)
773 fprintf(stderr, "\n");
774 else
775 fprintf(stderr, " ");
776 }
777 fprintf(stderr, "\n");
778
779 for (list = maplower.root; list; list = list->next)
780 fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map);
781
782 fprintf(stderr, "\nMAPUPPER:\n\n");
783
784 for (x = 0; x < _CACHED_RUNES; ++x) {
785 if (isprint(mapupper.map[x]))
786 fprintf(stderr, " '%c'", (int)mapupper.map[x]);
787 else if (mapupper.map[x])
788 fprintf(stderr, "%04x", mapupper.map[x]);
789 else
790 fprintf(stderr, "%4x", 0);
791 if ((x & 0xf) == 0xf)
792 fprintf(stderr, "\n");
793 else
794 fprintf(stderr, " ");
795 }
796 fprintf(stderr, "\n");
797
798 for (list = mapupper.root; list; list = list->next)
799 fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map);
800
801
802 fprintf(stderr, "\nTYPES:\n\n");
803
804 for (x = 0; x < _CACHED_RUNES; ++x) {
805 u_int32_t r = types.map[x];
806
807 if (r) {
808 if (isprint(x))
809 fprintf(stderr, " '%c':%2d", x, (int)(r & 0xff));
810 else
811 fprintf(stderr, "%04x:%2d", x, (int)(r & 0xff));
812
813 fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : "");
814 fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : "");
815 fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : "");
816 fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : "");
817 fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : "");
818 fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : "");
819 fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : "");
820 fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : "");
821 fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : "");
822 fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : "");
823 fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : "");
824 fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : "");
825 fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : "");
826 fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : "");
827 fprintf(stderr, "\n");
828 }
829 }
830
831 for (list = types.root; list; list = list->next) {
832 if (list->map && list->min + 3 < list->max) {
833 u_int32_t r = list->map;
834
835 fprintf(stderr, "%04x:%2d", list->min, r & 0xff);
836
837 fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : "");
838 fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : "");
839 fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : "");
840 fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : "");
841 fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : "");
842 fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : "");
843 fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : "");
844 fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : "");
845 fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : "");
846 fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : "");
847 fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : "");
848 fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : "");
849 fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : "");
850 fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : "");
851 fprintf(stderr, "\n...\n");
852
853 fprintf(stderr, "%04x:%2d", list->max, r & 0xff);
854
855 fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : "");
856 fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : "");
857 fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : "");
858 fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : "");
859 fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : "");
860 fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : "");
861 fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : "");
862 fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : "");
863 fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : "");
864 fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : "");
865 fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : "");
866 fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : "");
867 fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : "");
868 fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : "");
869 fprintf(stderr, " %1u", ((unsigned)r&_CTYPE_SWM)>>_CTYPE_SWS);
870 fprintf(stderr, "\n");
871 } else
872 for (x = list->min; x <= list->max; ++x) {
873 u_int32_t r = ntohl(list->types[x - list->min]);
874
875 if (r) {
876 fprintf(stderr, "%04x:%2d", x, (int)(r & 0xff));
877
878 fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : "");
879 fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : "");
880 fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : "");
881 fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : "");
882 fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : "");
883 fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : "");
884 fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : "");
885 fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : "");
886 fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : "");
887 fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : "");
888 fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : "");
889 fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : "");
890 fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : "");
891 fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : "");
892 fprintf(stderr, " %1u", ((unsigned)r&_CTYPE_SWM)>>_CTYPE_SWS);
893 fprintf(stderr, "\n");
894 }
895 }
896 }
897 }
898