Annotation of src/usr.bin/mklocale/yacc.y, Revision 1.8
1.8 ! deraadt 1: /* $OpenBSD: yacc.y,v 1.7 2015/08/20 22:32:41 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.7 deraadt 173: $$ = 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.7 deraadt 181: $$ = 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.7 deraadt 189: $$ = 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.7 deraadt 197: $$ = 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.7 deraadt 207: $$ = 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.7 deraadt 215: $$ = 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.7 deraadt 223: $$ = 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.7 deraadt 231: $$ = 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;
1.8 ! deraadt 250:
! 251: if (pledge("stdio rpath wpath cpath", NULL) == -1)
! 252: perror("pledge");
1.1 espie 253:
1.2 deraadt 254: while ((x = getopt(ac, av, "do:")) != -1) {
1.1 espie 255: switch(x) {
256: case 'd':
257: debug = 1;
258: break;
259: case 'o':
260: locale_file = optarg;
261: if ((ofile = fopen(locale_file, "w")) == 0)
262: err(1, "unable to open output file %s", locale_file);
263: break;
264: default:
265: usage:
1.3 sobrado 266: fprintf(stderr,
267: "usage: mklocale [-d] [src-file] language/LC_CTYPE\n"
268: " mklocale [-d] -o language/LC_CTYPE src-file\n");
1.1 espie 269: exit(1);
270: }
271: }
272:
273: switch (ac - optind) {
274: case 0:
275: break;
276: case 1:
277: if (freopen(av[optind], "r", stdin) == 0)
278: err(1, "unable to open input file %s", av[optind]);
279: break;
280: default:
281: goto usage;
282: }
283: for (x = 0; x < _CACHED_RUNES; ++x) {
284: mapupper.map[x] = x;
285: maplower.map[x] = x;
286: }
287: new_locale.rl_invalid_rune = _DEFAULT_INVALID_RUNE;
288: memcpy(new_locale.rl_magic, _RUNE_MAGIC_1, sizeof(new_locale.rl_magic));
289:
290: yyparse();
291:
292: return 0;
293: }
294:
295: int
296: yyerror(const char *s)
297: {
298: fprintf(stderr, "%s\n", s);
299:
300: return 0;
301: }
302:
303: void *
304: xmalloc(size_t sz)
305: {
306: void *r = malloc(sz);
307: if (!r) {
308: perror("xmalloc");
309: abort();
310: }
311: return(r);
312: }
313:
314: u_int32_t *
315: xlalloc(size_t sz)
316: {
1.7 deraadt 317: u_int32_t *r = reallocarray(NULL, sz, sizeof(u_int32_t));
1.1 espie 318: if (!r) {
319: perror("xlalloc");
320: abort();
321: }
322: return(r);
323: }
324:
325: u_int32_t *
326: xrelalloc(u_int32_t *old, size_t sz)
327: {
1.7 deraadt 328: u_int32_t *r = reallocarray(old, sz, sizeof(u_int32_t));
1.1 espie 329: if (!r) {
330: perror("xrelalloc");
331: abort();
332: }
333: return(r);
334: }
335:
336: void
337: set_map(rune_map *map, rune_list *list, u_int32_t flag)
338: {
339: list->map &= charsetmask;
340: list->map |= charsetbits;
341: while (list) {
342: rune_list *nlist = list->next;
343: add_map(map, list, flag);
344: list = nlist;
345: }
346: }
347:
348: void
349: set_digitmap(rune_map *map, rune_list *list)
350: {
351: rune_t i;
352:
353: while (list) {
354: rune_list *nlist = list->next;
355: for (i = list->min; i <= list->max; ++i) {
356: if (list->map + (i - list->min)) {
1.7 deraadt 357: rune_list *tmp = xmalloc(sizeof(rune_list));
1.1 espie 358: tmp->min = i;
359: tmp->max = i;
360: add_map(map, tmp, list->map + (i - list->min));
361: }
362: }
363: free(list);
364: list = nlist;
365: }
366: }
367:
368: void
369: add_map(rune_map *map, rune_list *list, u_int32_t flag)
370: {
371: rune_t i;
372: rune_list *lr = 0;
373: rune_list *r;
374: rune_t run;
375:
376: while (list->min < _CACHED_RUNES && list->min <= list->max) {
377: if (flag)
378: map->map[list->min++] |= flag;
379: else
380: map->map[list->min++] = list->map++;
381: }
382:
383: if (list->min > list->max) {
384: free(list);
385: return;
386: }
387:
388: run = list->max - list->min + 1;
389:
390: if (!(r = map->root) || (list->max < r->min - 1)
391: || (!flag && list->max == r->min - 1)) {
392: if (flag) {
393: list->types = xlalloc(run);
394: for (i = 0; i < run; ++i)
395: list->types[i] = flag;
396: }
397: list->next = map->root;
398: map->root = list;
399: return;
400: }
401:
402: for (r = map->root; r && r->max + 1 < list->min; r = r->next)
403: lr = r;
404:
405: if (!r) {
406: /*
407: * We are off the end.
408: */
409: if (flag) {
410: list->types = xlalloc(run);
411: for (i = 0; i < run; ++i)
412: list->types[i] = flag;
413: }
414: list->next = 0;
415: lr->next = list;
416: return;
417: }
418:
419: if (list->max < r->min - 1) {
420: /*
421: * We come before this range and we do not intersect it.
422: * We are not before the root node, it was checked before the loop
423: */
424: if (flag) {
425: list->types = xlalloc(run);
426: for (i = 0; i < run; ++i)
427: list->types[i] = flag;
428: }
429: list->next = lr->next;
430: lr->next = list;
431: return;
432: }
433:
434: /*
435: * At this point we have found that we at least intersect with
436: * the range pointed to by `r', we might intersect with one or
437: * more ranges beyond `r' as well.
438: */
439:
440: if (!flag && list->map - list->min != r->map - r->min) {
441: /*
442: * There are only two cases when we are doing case maps and
443: * our maps needn't have the same offset. When we are adjoining
444: * but not intersecting.
445: */
446: if (list->max + 1 == r->min) {
447: lr->next = list;
448: list->next = r;
449: return;
450: }
451: if (list->min - 1 == r->max) {
452: list->next = r->next;
453: r->next = list;
454: return;
455: }
456: fprintf(stderr, "Error: conflicting map entries\n");
457: exit(1);
458: }
459:
460: if (list->min >= r->min && list->max <= r->max) {
461: /*
462: * Subset case.
463: */
464:
465: if (flag) {
466: for (i = list->min; i <= list->max; ++i)
467: r->types[i - r->min] |= flag;
468: }
469: free(list);
470: return;
471: }
472: if (list->min <= r->min && list->max >= r->max) {
473: /*
474: * Superset case. Make him big enough to hold us.
475: * We might need to merge with the guy after him.
476: */
477: if (flag) {
478: list->types = xlalloc(list->max - list->min + 1);
479:
480: for (i = list->min; i <= list->max; ++i)
481: list->types[i - list->min] = flag;
482:
483: for (i = r->min; i <= r->max; ++i)
484: list->types[i - list->min] |= r->types[i - r->min];
485:
486: free(r->types);
487: r->types = list->types;
488: } else {
489: r->map = list->map;
490: }
491: r->min = list->min;
492: r->max = list->max;
493: free(list);
494: } else if (list->min < r->min) {
495: /*
496: * Our tail intersects his head.
497: */
498: if (flag) {
499: list->types = xlalloc(r->max - list->min + 1);
500:
501: for (i = r->min; i <= r->max; ++i)
502: list->types[i - list->min] = r->types[i - r->min];
503:
504: for (i = list->min; i < r->min; ++i)
505: list->types[i - list->min] = flag;
506:
507: for (i = r->min; i <= list->max; ++i)
508: list->types[i - list->min] |= flag;
509:
510: free(r->types);
511: r->types = list->types;
512: } else {
513: r->map = list->map;
514: }
515: r->min = list->min;
516: free(list);
517: return;
518: } else {
519: /*
520: * Our head intersects his tail.
521: * We might need to merge with the guy after him.
522: */
523: if (flag) {
524: r->types = xrelalloc(r->types, list->max - r->min + 1);
525:
526: for (i = list->min; i <= r->max; ++i)
527: r->types[i - r->min] |= flag;
528:
529: for (i = r->max+1; i <= list->max; ++i)
530: r->types[i - r->min] = flag;
531: }
532: r->max = list->max;
533: free(list);
534: }
535:
536: /*
537: * Okay, check to see if we grew into the next guy(s)
538: */
539: while ((lr = r->next) && r->max >= lr->min) {
540: if (flag) {
541: if (r->max >= lr->max) {
542: /*
543: * Good, we consumed all of him.
544: */
545: for (i = lr->min; i <= lr->max; ++i)
546: r->types[i - r->min] |= lr->types[i - lr->min];
547: } else {
548: /*
549: * "append" him on to the end of us.
550: */
551: r->types = xrelalloc(r->types, lr->max - r->min + 1);
552:
553: for (i = lr->min; i <= r->max; ++i)
554: r->types[i - r->min] |= lr->types[i - lr->min];
555:
556: for (i = r->max+1; i <= lr->max; ++i)
557: r->types[i - r->min] = lr->types[i - lr->min];
558:
559: r->max = lr->max;
560: }
561: } else {
562: if (lr->max > r->max)
563: r->max = lr->max;
564: }
565:
566: r->next = lr->next;
567:
568: if (flag)
569: free(lr->types);
570: free(lr);
571: }
572: }
573:
574: void
575: dump_tables()
576: {
577: int x, n;
578: rune_list *list;
579: _FileRuneLocale file_new_locale;
580: FILE *fp = (ofile ? ofile : stdout);
581:
582: memset(&file_new_locale, 0, sizeof(file_new_locale));
583:
584: /*
585: * See if we can compress some of the istype arrays
586: */
587: for(list = types.root; list; list = list->next) {
588: list->map = list->types[0];
589: for (x = 1; x < list->max - list->min + 1; ++x) {
590: if (list->types[x] != list->map) {
591: list->map = 0;
592: break;
593: }
594: }
595: }
596:
597: memcpy(&file_new_locale.frl_magic, new_locale.rl_magic,
598: sizeof(file_new_locale.frl_magic));
599: memcpy(&file_new_locale.frl_encoding, new_locale.rl_encoding,
600: sizeof(file_new_locale.frl_encoding));
601:
602: file_new_locale.frl_invalid_rune = htonl(new_locale.rl_invalid_rune);
603:
604: /*
605: * Fill in our tables. Do this in network order so that
606: * diverse machines have a chance of sharing data.
607: * (Machines like Crays cannot share with little machines due to
608: * word size. Sigh. We tried.)
609: */
610: for (x = 0; x < _CACHED_RUNES; ++x) {
611: file_new_locale.frl_runetype[x] = htonl(types.map[x]);
612: file_new_locale.frl_maplower[x] = htonl(maplower.map[x]);
613: file_new_locale.frl_mapupper[x] = htonl(mapupper.map[x]);
614: }
615:
616: /*
617: * Count up how many ranges we will need for each of the extents.
618: */
619: list = types.root;
620:
621: while (list) {
622: new_locale.rl_runetype_ext.rr_nranges++;
623: list = list->next;
624: }
625: file_new_locale.frl_runetype_ext.frr_nranges =
626: htonl(new_locale.rl_runetype_ext.rr_nranges);
627:
628: list = maplower.root;
629:
630: while (list) {
631: new_locale.rl_maplower_ext.rr_nranges++;
632: list = list->next;
633: }
634: file_new_locale.frl_maplower_ext.frr_nranges =
635: htonl(new_locale.rl_maplower_ext.rr_nranges);
636:
637: list = mapupper.root;
638:
639: while (list) {
640: new_locale.rl_mapupper_ext.rr_nranges++;
641: list = list->next;
642: }
643: file_new_locale.frl_mapupper_ext.frr_nranges =
644: htonl(new_locale.rl_mapupper_ext.rr_nranges);
645:
646: file_new_locale.frl_variable_len = htonl(new_locale.rl_variable_len);
647:
648: /*
649: * Okay, we are now ready to write the new locale file.
650: */
651:
652: /*
653: * PART 1: The _RuneLocale structure
654: */
655: if (fwrite((char *)&file_new_locale, sizeof(file_new_locale), 1, fp) != 1)
656: err(1, "writing _RuneLocale to %s", locale_file);
657: /*
658: * PART 2: The runetype_ext structures (not the actual tables)
659: */
660: for (list = types.root, n = 0; list != NULL; list = list->next, n++) {
661: _FileRuneEntry re;
662:
663: memset(&re, 0, sizeof(re));
664: re.fre_min = htonl(list->min);
665: re.fre_max = htonl(list->max);
666: re.fre_map = htonl(list->map);
667:
668: if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
669: err(1, "writing runetype_ext #%d to %s", n, locale_file);
670: }
671: /*
672: * PART 3: The maplower_ext structures
673: */
674: for (list = maplower.root, n = 0; list != NULL; list = list->next, n++) {
675: _FileRuneEntry re;
676:
677: memset(&re, 0, sizeof(re));
678: re.fre_min = htonl(list->min);
679: re.fre_max = htonl(list->max);
680: re.fre_map = htonl(list->map);
681:
682: if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
683: err(1, "writing maplower_ext #%d to %s", n, locale_file);
684: }
685: /*
686: * PART 4: The mapupper_ext structures
687: */
688: for (list = mapupper.root, n = 0; list != NULL; list = list->next, n++) {
689: _FileRuneEntry re;
690:
691: memset(&re, 0, sizeof(re));
692: re.fre_min = htonl(list->min);
693: re.fre_max = htonl(list->max);
694: re.fre_map = htonl(list->map);
695:
696: if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
697: err(1, "writing mapupper_ext #%d to %s", n, locale_file);
698: }
699: /*
700: * PART 5: The runetype_ext tables
701: */
702: for (list = types.root, n = 0; list != NULL; list = list->next, n++) {
703: for (x = 0; x < list->max - list->min + 1; ++x)
704: list->types[x] = htonl(list->types[x]);
705:
706: if (!list->map) {
707: if (fwrite((char *)list->types,
708: (list->max - list->min + 1) * sizeof(u_int32_t),
709: 1, fp) != 1)
710: err(1, "writing runetype_ext table #%d to %s", n, locale_file);
711: }
712: }
713: /*
714: * PART 5: And finally the variable data
715: */
716: if (new_locale.rl_variable_len != 0 &&
717: fwrite((char *)new_locale.rl_variable,
718: new_locale.rl_variable_len, 1, fp) != 1)
719: err(1, "writing variable data to %s", locale_file);
720: fclose(fp);
721:
722: if (!debug)
723: return;
724:
725: if (new_locale.rl_encoding[0])
726: fprintf(stderr, "ENCODING %s\n", new_locale.rl_encoding);
727: if (new_locale.rl_variable)
728: fprintf(stderr, "VARIABLE %s\n",
729: (char *)new_locale.rl_variable);
730:
731: fprintf(stderr, "\nMAPLOWER:\n\n");
732:
733: for (x = 0; x < _CACHED_RUNES; ++x) {
734: if (isprint(maplower.map[x]))
735: fprintf(stderr, " '%c'", (int)maplower.map[x]);
736: else if (maplower.map[x])
737: fprintf(stderr, "%04x", maplower.map[x]);
738: else
739: fprintf(stderr, "%4x", 0);
740: if ((x & 0xf) == 0xf)
741: fprintf(stderr, "\n");
742: else
743: fprintf(stderr, " ");
744: }
745: fprintf(stderr, "\n");
746:
747: for (list = maplower.root; list; list = list->next)
748: fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map);
749:
750: fprintf(stderr, "\nMAPUPPER:\n\n");
751:
752: for (x = 0; x < _CACHED_RUNES; ++x) {
753: if (isprint(mapupper.map[x]))
754: fprintf(stderr, " '%c'", (int)mapupper.map[x]);
755: else if (mapupper.map[x])
756: fprintf(stderr, "%04x", mapupper.map[x]);
757: else
758: fprintf(stderr, "%4x", 0);
759: if ((x & 0xf) == 0xf)
760: fprintf(stderr, "\n");
761: else
762: fprintf(stderr, " ");
763: }
764: fprintf(stderr, "\n");
765:
766: for (list = mapupper.root; list; list = list->next)
767: fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map);
768:
769:
770: fprintf(stderr, "\nTYPES:\n\n");
771:
772: for (x = 0; x < _CACHED_RUNES; ++x) {
773: u_int32_t r = types.map[x];
774:
775: if (r) {
776: if (isprint(x))
777: fprintf(stderr, " '%c':%2d", x, (int)(r & 0xff));
778: else
779: fprintf(stderr, "%04x:%2d", x, (int)(r & 0xff));
780:
781: fprintf(stderr, " %4s", (r & _RUNETYPE_A) ? "alph" : "");
782: fprintf(stderr, " %4s", (r & _RUNETYPE_C) ? "ctrl" : "");
783: fprintf(stderr, " %4s", (r & _RUNETYPE_D) ? "dig" : "");
784: fprintf(stderr, " %4s", (r & _RUNETYPE_G) ? "graf" : "");
785: fprintf(stderr, " %4s", (r & _RUNETYPE_L) ? "low" : "");
786: fprintf(stderr, " %4s", (r & _RUNETYPE_P) ? "punc" : "");
787: fprintf(stderr, " %4s", (r & _RUNETYPE_S) ? "spac" : "");
788: fprintf(stderr, " %4s", (r & _RUNETYPE_U) ? "upp" : "");
789: fprintf(stderr, " %4s", (r & _RUNETYPE_X) ? "xdig" : "");
790: fprintf(stderr, " %4s", (r & _RUNETYPE_B) ? "blnk" : "");
791: fprintf(stderr, " %4s", (r & _RUNETYPE_R) ? "prnt" : "");
792: fprintf(stderr, " %4s", (r & _RUNETYPE_I) ? "ideo" : "");
793: fprintf(stderr, " %4s", (r & _RUNETYPE_T) ? "spec" : "");
794: fprintf(stderr, " %4s", (r & _RUNETYPE_Q) ? "phon" : "");
795: fprintf(stderr, "\n");
796: }
797: }
798:
799: for (list = types.root; list; list = list->next) {
800: if (list->map && list->min + 3 < list->max) {
801: u_int32_t r = list->map;
802:
803: fprintf(stderr, "%04x:%2d", list->min, r & 0xff);
804:
805: fprintf(stderr, " %4s", (r & _RUNETYPE_A) ? "alph" : "");
806: fprintf(stderr, " %4s", (r & _RUNETYPE_C) ? "ctrl" : "");
807: fprintf(stderr, " %4s", (r & _RUNETYPE_D) ? "dig" : "");
808: fprintf(stderr, " %4s", (r & _RUNETYPE_G) ? "graf" : "");
809: fprintf(stderr, " %4s", (r & _RUNETYPE_L) ? "low" : "");
810: fprintf(stderr, " %4s", (r & _RUNETYPE_P) ? "punc" : "");
811: fprintf(stderr, " %4s", (r & _RUNETYPE_S) ? "spac" : "");
812: fprintf(stderr, " %4s", (r & _RUNETYPE_U) ? "upp" : "");
813: fprintf(stderr, " %4s", (r & _RUNETYPE_X) ? "xdig" : "");
814: fprintf(stderr, " %4s", (r & _RUNETYPE_B) ? "blnk" : "");
815: fprintf(stderr, " %4s", (r & _RUNETYPE_R) ? "prnt" : "");
816: fprintf(stderr, " %4s", (r & _RUNETYPE_I) ? "ideo" : "");
817: fprintf(stderr, " %4s", (r & _RUNETYPE_T) ? "spec" : "");
818: fprintf(stderr, " %4s", (r & _RUNETYPE_Q) ? "phon" : "");
819: fprintf(stderr, "\n...\n");
820:
821: fprintf(stderr, "%04x:%2d", list->max, r & 0xff);
822:
823: fprintf(stderr, " %4s", (r & _RUNETYPE_A) ? "alph" : "");
824: fprintf(stderr, " %4s", (r & _RUNETYPE_C) ? "ctrl" : "");
825: fprintf(stderr, " %4s", (r & _RUNETYPE_D) ? "dig" : "");
826: fprintf(stderr, " %4s", (r & _RUNETYPE_G) ? "graf" : "");
827: fprintf(stderr, " %4s", (r & _RUNETYPE_L) ? "low" : "");
828: fprintf(stderr, " %4s", (r & _RUNETYPE_P) ? "punc" : "");
829: fprintf(stderr, " %4s", (r & _RUNETYPE_S) ? "spac" : "");
830: fprintf(stderr, " %4s", (r & _RUNETYPE_U) ? "upp" : "");
831: fprintf(stderr, " %4s", (r & _RUNETYPE_X) ? "xdig" : "");
832: fprintf(stderr, " %4s", (r & _RUNETYPE_B) ? "blnk" : "");
833: fprintf(stderr, " %4s", (r & _RUNETYPE_R) ? "prnt" : "");
834: fprintf(stderr, " %4s", (r & _RUNETYPE_I) ? "ideo" : "");
835: fprintf(stderr, " %4s", (r & _RUNETYPE_T) ? "spec" : "");
836: fprintf(stderr, " %4s", (r & _RUNETYPE_Q) ? "phon" : "");
837: fprintf(stderr, " %1u", (unsigned)((r & _RUNETYPE_SWM)>>_RUNETYPE_SWS));
838: fprintf(stderr, "\n");
839: } else
840: for (x = list->min; x <= list->max; ++x) {
841: u_int32_t r = ntohl(list->types[x - list->min]);
842:
843: if (r) {
844: fprintf(stderr, "%04x:%2d", x, (int)(r & 0xff));
845:
846: fprintf(stderr, " %4s", (r & _RUNETYPE_A) ? "alph" : "");
847: fprintf(stderr, " %4s", (r & _RUNETYPE_C) ? "ctrl" : "");
848: fprintf(stderr, " %4s", (r & _RUNETYPE_D) ? "dig" : "");
849: fprintf(stderr, " %4s", (r & _RUNETYPE_G) ? "graf" : "");
850: fprintf(stderr, " %4s", (r & _RUNETYPE_L) ? "low" : "");
851: fprintf(stderr, " %4s", (r & _RUNETYPE_P) ? "punc" : "");
852: fprintf(stderr, " %4s", (r & _RUNETYPE_S) ? "spac" : "");
853: fprintf(stderr, " %4s", (r & _RUNETYPE_U) ? "upp" : "");
854: fprintf(stderr, " %4s", (r & _RUNETYPE_X) ? "xdig" : "");
855: fprintf(stderr, " %4s", (r & _RUNETYPE_B) ? "blnk" : "");
856: fprintf(stderr, " %4s", (r & _RUNETYPE_R) ? "prnt" : "");
857: fprintf(stderr, " %4s", (r & _RUNETYPE_I) ? "ideo" : "");
858: fprintf(stderr, " %4s", (r & _RUNETYPE_T) ? "spec" : "");
859: fprintf(stderr, " %4s", (r & _RUNETYPE_Q) ? "phon" : "");
860: fprintf(stderr, " %1u", (unsigned)((r & _RUNETYPE_SWM)>>_RUNETYPE_SWS));
861: fprintf(stderr, "\n");
862: }
863: }
864: }
865: }