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