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