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