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