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